/***************************************************************************
 * songview.h: implementation of SongView class
 *
 * This file is part of KtabEdit, a KDE tabulature editor
 *
 * copyright (C) 2003-2006 the KTabEdit development team <mrgwen@gmail.com>
 * copyright (C) 2002-2003 the KGuitar 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 SONGVIEW_H
#define SONGVIEW_H

#include <QWidget>
#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>

#include "tablature/tabduration.h"
#include "tablatureModel/tabsongobserver.h"

class QSplitter;
class QUndoStack;
class QVBoxLayout;
class QPrinter;

class MelodyEditor;
class PlaybackTracker;
class SongPrint;
class TabSongPlayer;
class TrackEditView;
class TabTrack;
class TrackList;
class TrackPane;
class TrackPos;
class TrackProperties;
class TabSong;
class TabSongModel;

/**
\brief Main widget that includes all other ones: TrackEditView etc...
**/
class SongView : public QWidget, public TabSongObserver {
	Q_OBJECT
public:
	class AddTrackCommand;
	class DeleteTrackCommand;
	class SetSongPropCommand;
	class SetTrackPropCommand;
	class InsertTabsCommand;
	
	SongView(TSE3::MidiScheduler* midiScheduler, QUndoStack* commandHistory);
	virtual ~SongView();
	
	virtual void setReadOnly(bool b);
	virtual bool isReadOnly() const;
	
	virtual void setTabSong(TabSong* tabSong);
	virtual TabSong* tabSong() const;
	
	void setMidiScheduler(TSE3::MidiScheduler* midiScheduler);
	
	uint trackSelected() const;
	
	void refreshView();
	
	void print(QPrinter* printer);
	
	void drawBackground();
	
	virtual void propertyChanged();
	
	virtual void initSong();
	virtual void initLayouts();
	virtual void initWidgets();
	virtual void buildLayouts();
	virtual void initUI();
	
	virtual void connectTrackEditView() const;
	virtual void connectTabSong() const;
	virtual void connectObjects();
signals:
	void statusBar(const QString& msg);
	
	void isAccentuated(bool b);
	void isGhostNote(bool b);
	void isTieNote(bool b);
	void isHammerOnPullOff(bool b);
	void isSlide(bool b);
	void isLetRing(bool b);
	void isDynamic(bool b);
	void isFingeringLeft(bool b);
	void isFingeringRight(bool b);
	void isLeftHandVibrato(bool b);
	void isPalmMute(bool b);
	void isStaccato(bool b);
	void isTremoloPicking(bool b);
	void isHarmonic(bool b);
	void isBend(bool b);
	void isGraceNote(bool b);
	void isTrill(bool b);
	void isRasgueado(bool b);
	void isPickStroke(bool b);
	void isTremolo(bool b);
	void isTapping(bool b);
	void isPopping(bool b);
	void isSlapping(bool b);
	void isStroke(bool b);
	void isVibrato(bool b);
	void isFadeIn(bool b);
	
public slots:
	void zoomIn();
	void zoomOut();
	
	void cut();
	void copy();
	void paste();
	void selectAll();
	
	void showMelodyEditor(bool b);
	void showScore(bool b);
	
	void songProperties();
	
	/**
	\brief Create a new track
	**/
	void trackNew();
	
	/**
	\brief Deletes a track
	\param track Track to be deleted
	**/
	void trackDelete(TabTrack* track);

	/**
	\brief Deletes current track (mtrack)
	**/
	void trackDelete();

	void trackProperties();
	void trackBassLine();
	
	void addBar();
	void deleteBar();
	void keySignature();
	void timeSignature();
	
	void addTime();
	void deleteTime();
	void addChord();
	
	void setDefaultDuration(Duration d);
	
	void setLengthWhole();
	void setLengthHalf();
	void setLengthQuarter();
	void setLengthEighth();
	void setLengthSixteenth();
	void setLengthThirtySecond();
	void setLengthSixtyFourth();
	
	void setDotted();
	void setRest();
	void setLinkPrev();
	void setLegato();
	void setSlide();
	void setLetRing();
	void setHarmonic();
	void setPalmMuting();
	void setBend();
	void setVibrato();
	void setTrill();
	void setTapping();
	void setTremolo();
	
	void playSong();
	void stopPlay();
	
	
	/**
	\brief Move the cursor to the position and refresh the view.
	*/
	void playbackCursor(int track, const TrackPos& position);
	void fullBend();
	void halfBendRelease();
	void fullBendRelease();
	void halfPreBend();
	void fullPreBend();
	void halfPreBendRelease();
	void fullPreBendRelease();
	void unisonBend();
	void wideVibrato();
	void muffledStrings();
	void tremoloPicking();
	void keySig();
	void timeSig();
	void addArtHarm();
	void addSlide();
	void rhythmer();
	void transposeUp();
	void transposeDown();
	void selectLeft();
	
	/**
		move the cursor to an high string.
	*/
	void selectRight();
	
	/**
		move the cursor to an high string.
	*/
	void deadNote();
	
	/**
		Insert a palm mute effect.
	*/
	void palmMute();
	
	/**
		Insert a dot note effect.
	*/
	void dotNote();
	
	/**
		Select a n-tuplet number.
	*/
	void ntupletSelected(int n);
	
	/**
		Insert a n-tuplet effect.
	*/
	void ntuplet();
	
	/**
		Set the length of a note.
	*/
	void arrangeTracks();
	
	/**
		Actions of the melody editor
	*/
	void melodyEditorPress(int, int, Qt::ButtonState);
	/**
		I DON'T KNOW
	*/
	void melodyEditorRelease(Qt::ButtonState);
	
	/**
	\brief Change the track and refresh the view.
	\param tabTrack the pointer of the track in the song list.
	*/
	void selectTrack(TabTrack* tabTrack);

	
	/**
		I DON'T KNOW
	*/
	void setPlaybackCursor(bool);
	
	/**
		I DON'T KNOW
	*/
	void viewScore(bool);
	
	/**
		Number of bar.
		\return return the number of bar.
	*/
	uint getBarNumber();
	
	/**
		Bar the number where the cursor is.
		\return return the position of the cursor.
	*/
	uint getBarPosition();
	
	/*
		Set the string position of the cursor this function
		is used by songviewcommand when the user change the number
		of strings
	*/
	void setString(uint i);
	
	/*
		Return the string position of the cursor this function
		is used by songviewcommand when the user change the number
		of strings
	*/
	uint string();
signals:
	void songChanged(bool);
	void trackPropertiesChanged(const TrackProperties*);
	
private slots:

	
private:
	void initActions();
	
	void insertTabs(TabTrack& tempTrack);
	
	bool setTrackProperties(TrackProperties* trackProperties);

	QSplitter* mSplitter;
	QSplitter* mSplitterHorizontal;
	QVBoxLayout* mLayout;
	
	TabTrack *highlightedTabs();
	
	TSE3::MidiScheduler* mMidiScheduler; /**< The Midi Scheduler. TODO: replace it, because TSE3 is old */
	QUndoStack* mCommandHistory; /**< A Undo Stack */
	
	TabTrack* mCurrentTrack;
	TabSongModel* mSong;
	
	PlaybackTracker* mPlaybackTracker; /**< Refresh the cursor during the playback */
	SongPrint* mSongPrint; /**< Print the song */
	MelodyEditor* mMelodyEditor; /**< Display the melody editor which can draw main scales, triads, apergios, and can help the user to edit the track */
	TrackEditView* mTrackEditView; /**< Track editor */
	TrackList* mTrackList; /**< The track list */
	TrackPane* mTrackPane; /**< The bar list in the tracks */
	TabSongPlayer* mTabSongPlayer; /**< The song player */
	
	bool mReadOnly;

private slots:
	/**
	\brief Called when there is a mouse press event for the mCanvasView widget
	\param event the mouse event
	*/
	void mousePressEvent(QMouseEvent* event);
	
	/**
	\brief Called when there is an undo/redo action.
	*/
	void refreshCommand();
};

#endif
