/***************************************************************************
 * tabsongplayer.h: implementation of TabSongPlayer class
 *
 * This file is part of KTabEdit, a KDE tabulature editor
 *
 * copyright (C) 2003-2006 the KTabEdit development team <mrgwen@gmail.com>
 ***************************************************************************/

/***************************************************************************
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * See the file COPYING for more information.
 ***************************************************************************/

#ifndef TABSONGPLAYER_H
#define TABSONGPLAYER_H

#include <QThread>

#include <tse3/Error.h>
#include <tse3/listen/Transport.h>
#include <tse3/Metronome.h>
#include <tse3/MidiScheduler.h>
#include <tse3/Part.h>
#include <tse3/PhraseEdit.h>
#include <tse3/Song.h>
#include <tse3/TempoTrack.h>
#include <tse3/Track.h>
#include <tse3/Transport.h>
#include <tse3/util/MidiScheduler.h>

class TabSongModel;
class TabTime;
class TabTrack;
class PlaybackTracker;
class Settings;

class TabSongPlayer : public QThread
{
public:
	TabSongPlayer(const TabSongModel* tempSong, PlaybackTracker* tracker);
	virtual ~TabSongPlayer();
	
	void setScheduler(TSE3::MidiScheduler* midiScheduler);
	void stopPlaying();
	
	virtual void run();
	
	virtual void insertMidiCommand(TSE3::PhraseEdit* phraseEdit, int status, int channel, int data1);
	virtual void insertMidiCommand(TSE3::PhraseEdit* phraseEdit, int status, int channel, int data1, int data2);
	virtual void insertMidiCommand(TSE3::PhraseEdit* phraseEdit, int status, int channel, int data1, int data2, int time);
	virtual void insertMidiCommand(TSE3::PhraseEdit* phraseEdit, int status, int channel, int data1, int data2, int time, int velocity, int nextTime);
	
	virtual void createMidiHeaders(TSE3::PhraseEdit* phraseEdit);
	virtual long createTheSong(TSE3::PhraseEdit* phraseEdit);
	virtual void fillWithEmptyNotesForEnd(TSE3::PhraseEdit* phraseEdit, uint lastTime);
	virtual void assembleTheSong(TSE3::PhraseEdit* phraseEdit, TSE3::Transport* transport, TSE3::Song* song);
	virtual void playTheSong(TSE3::Transport* transport, TSE3::Song* song);
private:
	inline long calcDuration(const TabTime& time) const;
	inline long calcLink(uint barNb, uint timeNb, uint chord, const TabTrack* tempTrack) const;
	inline bool checkLinkAndRest(uint barNb, uint timeNb, uint chord, const TabTrack* tempTrack) const;
	
	const TabSongModel* mTabSong;
	TSE3::MidiScheduler* scheduler;
	PlaybackTracker* mPlaybackTracker;
	Settings* mSettings;
	bool stop;
};

#endif
