//---------------------------------------------------------------------------

#ifndef ContentPanelUnitH
#define ContentPanelUnitH

#include "SkinScrollBarUnit.h"
#include "ToolpalPanel.h"
#include "StyleItem.h"
#include "MenuUnit.h"
#include "BaseTrack.h"

#define BAR_CURSOR	0x00
#define BAR_TITLE 	0x100
#define BAR_DATA 	0x200
#define BAR_TRACK	0x400
#define BAR_LEFT	0x1000
#define MIN_HDR_WIDTH	120
#define MAX_HDR_WIDTH	240

typedef struct tagShowTrack
{
	BYTE type;
	BYTE index;
	BYTE iHover;
	TBaseTrack* pTrack;

	tagShowTrack( BYTE ty, BYTE ind, TBaseTrack* p  )
	{
		type = ty;
		index = ind;
		iHover = 0;
		pTrack = p;
	};
}TShowTrack, *PTShowTrack;

typedef vector<TShowTrack*> TShowTrackList;
//---------------------------------------------------------------------------
class TContentPanel : public Extctrls::TPanel
{
private:
	//显示相关
	HRGN m_rgnClip;
	bool m_bVertical; //竖版/横版

	int m_iMode, //0=音频模式 1=和弦模式 2=风格模式
		m_nRowShow,
		m_nTrackShow,
		m_nColumnNum,
		m_nRowNum,
		m_nBarNum,
		m_iBeginShowRow,
		m_iBeginShowBar,
		m_iBeginShowTrack,

		m_nBarWidth,
		m_nBarHeight,
		m_nDataWidth,
		m_nBarDrawHeight,
		m_nRowGapHeight,    //播放区
		m_nTitleHeight,  	//小节区
		m_nChordHeight,     //和弦区
		m_nTrackHeight,		//轨道区
		m_nTrkHdrWidth,		//轨道头宽度

		m_nLeftBound,
		m_nLeftOriBound,
		m_nRightBound,
		m_nTopBound,
		m_nBottomBound;

	TShowTrackList m_aTracks;	//显示的轨道

	TSkinScrollBar *m_sbVert,
					*m_sbHoriz;
	TToolpalPanel 	*m_pStylePanel, //风格面板
					*m_pChordPanel, //和弦面板
					*m_pTrackPanel; //轨道面板

	//选择相关
	int m_iSelBarStart,
		m_iSelBarEnd,
		m_iSelPointStart,
		m_iSelPointEnd,
		m_iSelTrackBar,
		m_iSelTrackPoint,
		m_iSelTrack;

	//录音/播放相关
	bool m_bPlaying;
	int m_iPlayBar,
		m_iPlayPoint;
	TBitmap *m_imgPlayCursor,
			*m_imgMidiIcon,
			*m_imgWaveIcon;

	TPngImage * m_imgBeatHint[4],
			*m_pngChordUp,
			*m_pngChordDown,
			*m_pngChord2,
			*m_pngChord4,
			*m_pngChord6,
			*m_pngChord7,
			*m_pngChordI,
			*m_pngChordV,
			*m_pngChordMaj,
			*m_pngChordMin,
			*m_pngChordSus;
	int m_iBeatHint,
		m_lBeatHint,
		m_tBeatHint,
		m_wBeatHint,
		m_hBeatHint;

	//和弦相关
	int m_nChordTxtWidth,
		m_nChordTxtHeight,
		m_iMinSelBar,
		m_iMaxSelBar,
		m_iSelCellStart,
		m_iSelCellEnd;

	//复制剪切相关
	int m_iCopyBarStart,
		m_iCopyBarEnd,
		m_iCopyCellStart,
		m_iCopyCellEnd,
		m_iCopyPointStart,
		m_iCopyPointEnd,
		m_iCopyAudio;
	bool m_bCut;

	//拖动相关
	int m_iDropBar,
		m_iMouseDownBar,
		m_iMouseDownPoint,
		m_iDragingStage,
		m_iDragAudio; //拖动的音频轨
	bool m_bDragReady,  //鼠标拖动进行选择操作
		m_bDraging,
		m_bBrush;
	TPoint ptDown;
	TCommonItem *m_pItem;

	TTimer *m_pTimer;	//自动滚屏定时器

	TMenuPanel *m_PopupMenu;          //右键菜单   //add
	TApplicationEvents *m_ApplicationEvents;

	void ChordPaste( int key[], int type[], int len, bool bAddUndo=true );
//	void ChangeMelodyKey( int Index );
	void ChangeBarsKey( int iBarStart, int iBarEnd, int iKey, int keys[] );
	void AudioMove( int iSrcTrack, int iBarStart, int iPointStart,
							int iBarEnd, int iPointEnd, bool bCut );
	void GetBarKeys( int iBarStart, int iBarEnd, int keys[] );
	void ChangeMidiTrack( int iMT=-1, int iSBar=-1, int iEBar=-1 );

	void ClearShowTracks();
    void ShowTrackChangeState( int iTrack, int iType );
	void ShowPlayPoint();

	void CalcViewArea();
	bool SetScrollView( int iFirstShowBar );

	void DrawBars();
	void DrawBarTitle( int l, int r, int t, bool bSel );
	void DrawBarData( int iBar, int iStage, int iFirstBar, int left, int top );
	void DrawTrack( int iBar, int nBarNum, int left, int top, int iTrack );
	void DrawRowWave( int iBar, int nBarNum, int left, int top, int iWave );
	void DrawRowMidi( int iBar, int nBarNum, int left, int top, int iMidi );
	void DrawChord( TRect& rcDraw, int iBarKey, int iKey, int iType );

	//HitTest返回iHitType值 -1=无效区域 0=行间空白 1=小节栏 2=和弦区 >=3 波形区
	DWORD HitTest( int X, int Y, int& iHitType, bool bHead=false );

	void SelectRange( int iBarStart, int iPointStart, int iBarEnd, int iPointEnd, bool bInvalid=false );
	void SelectCopyBars( int iBarStart, int iBarEnd, bool bCut=false );
	void SelectCopyCells( int iBarStart, int iCellStart, int iBarEnd, int iCellEnd );
	void SelectCopyPos( int iBarStart, int iPointStart, int iBarEnd, int iPointEnd );
	void SetDropBar( int iBar );
	void SelectRangeByWave( int iHitBar, int iHitPoint );

	int GetCell( int iPoint );
	void GetSelectChord( int& iBarKey, int& iChordKey, int& iChordType );

	void DrawDragImg( int mode );
	void SetScrollTimer(TPoint ptMouse, bool bVertical=true);
	void HandleDropEvent( int iState=0 );
	bool HandleHoverEvent(TPoint ptMouse);
	void HandleBrush();

	void OnAudioEffectProcess( int iFxType );
	void OnAudioEffectAdd( int iFxType );
	void OnWMScroll(TWMScroll &Message, bool bVertical);

	void __fastcall DoHandleMessage(MSG &Msg, bool &Handled);  //鼠标消息处理
	void __fastcall TimerProc(TObject* Sender);
	void __fastcall DoubleClick(TObject* sender);
	void __fastcall DoSetSelPosStart(System::TObject* Sender);
	void __fastcall DoSetSelPosEnd(System::TObject* Sender);
	void __fastcall DoDelSelPosStart(System::TObject* Sender);
	void __fastcall DoDelSelPosEnd(System::TObject* Sender);
	void __fastcall DoAudioFxProcess(System::TObject* Sender);
	void __fastcall DoAudioVstProcess(System::TObject* Sender);
	void __fastcall DoAudioAddFx(System::TObject* Sender);
	void __fastcall DoAudioAddVst(System::TObject* Sender);

	MESSAGE void __fastcall OnMidiSwitch(TMessage &msg);
	MESSAGE void __fastcall UMMouseMove(TWMMouse &Message);
	MESSAGE void __fastcall UMMouseUp(TWMMouse &Message);
	MESSAGE void __fastcall WMEraseBkgnd(TWMEraseBkgnd &Message);
	MESSAGE void __fastcall WMSize(TWMSize &Message);
	MESSAGE void __fastcall WMVScroll(TWMScroll &Message);
	MESSAGE void __fastcall WMHScroll(TWMScroll &Message);
	MESSAGE void __fastcall WMMouseWheel(TWMMouseWheel &Message);
	MESSAGE void __fastcall WMMouseDown(TWMMouse &Message);

	BEGIN_MESSAGE_MAP
		MESSAGE_HANDLER(WM_ERASEBKGND, TWMEraseBkgnd, WMEraseBkgnd)
		MESSAGE_HANDLER(WM_SIZE, TWMSize, WMSize)
		MESSAGE_HANDLER(WM_VSCROLL, TWMVScroll, WMVScroll)
		MESSAGE_HANDLER(WM_HSCROLL, TWMHScroll, WMHScroll)
		MESSAGE_HANDLER(WM_MOUSEWHEEL, TWMMouseWheel, WMMouseWheel)
		MESSAGE_HANDLER(WM_LBUTTONDOWN, TWMMouse, WMMouseDown)
		MESSAGE_HANDLER(WM_RBUTTONDOWN, TWMMouse, WMMouseDown)
		MESSAGE_HANDLER(UM_MOUSEMOVE, TWMMouseMove, UMMouseMove)
		MESSAGE_HANDLER(UM_MOUSEUP, TWMMouse, UMMouseUp)
		MESSAGE_HANDLER(UM_MIDISWITCH, TMessage, OnMidiSwitch)
	END_MESSAGE_MAP(Vcl::Extctrls::TPanel)

protected:
	virtual void __fastcall CreateWnd();
	virtual void __fastcall Paint(void);

public:
	inline void SetStylePanel( TToolpalPanel* pPanel ){ m_pStylePanel=pPanel; };
	inline void SetChordPanel( TToolpalPanel* pPanel ){ m_pChordPanel=pPanel; };
	inline void SetTrackPanel( TToolpalPanel* pPanel ){ m_pTrackPanel=pPanel; };
	inline void SetPopMenu( TMenuPanel* pMenu ){ m_PopupMenu = pMenu; };

	void InitialVars( bool bClear = false );
	inline int GetBarNum(){ return m_nBarNum; };
	void AddNewBar( int iBar );
	void ShowBeatHint( int iBeat );

	void SetMode( int iMode );
	void SetScrollMode( bool bVertical=true );
	inline bool IsVertical() { return m_bVertical; };
	inline void Play( bool bPlay ) { m_bPlaying=bPlay; };
	inline bool IsPlaying() { return m_bPlaying; };
	void SetPlayPoint( int iBar, int iPoint );

	int GetShowTrackId( int type, int index );
	void SelectTrack( int iTrack, int iBar, int iPoint, bool bClear=true );
	void ShowTrack( int type, int index, bool bShow );
	void DeleteTrack( int type, int index );

	void SetSelectRange( int iStartBar, int iStartPoint, int iEndBar, int iEndPoint, bool bInvalid=false );
	void GetSelectRange( int& iStartBar, int& iStartPoint, int& iEndBar, int& iEndPoint );
	inline bool IsModifyMode() { return !(m_iSelBarStart<0 && m_iSelBarEnd<0); };

	bool SetSelectChord( int iKey, int iChordType );
	void GetChordDispalyKey( int iKey, int iBarKey, int& iMainKey, int& iAjustKey );

	void SelectCells( int iBarStart, int iCellStart, int iBarEnd, int iCellEnd );
	void SelectStage( int iStage );
	void SelectBars( int iStartBar, int iEndBar );
	void GetSelectBars( int& iStartBar, int& iEndBar );

	void InvalidateBar( int iBar, int iBeginPoint, int iEndPoint, int iArea=BAR_DATA );
	void InvalidateBars( int iBarStart, int iBarEnd, int iArea=BAR_DATA );
	void InvalidateShowBars( int iArea=BAR_TITLE|BAR_DATA|BAR_TRACK );
	void InvalidateStage( int iStage, int iArea=BAR_DATA );
	void ScrollView( int nPos, bool bVertical=true, bool bRedraw=true );

	bool ShowDragImg( bool bShow=true, int iState=0 );
	TCommonItem* GetDropItem(){ return m_pItem; };
	void SetDropItem( TCommonItem* pItem ){ m_pItem = pItem; };
	void BeginBrush( TCommonItem* pBrushItem );
	void CancelBrush();
	bool IsStyleBrush() { return m_bBrush; };

	void Undo( bool bUndo );

	void __fastcall OnTrackStateChanged( int iType, int iIndex, BYTE iState, bool bUnset );
	void __fastcall OnStageChanged( int iStage, int iMode );
	void __fastcall OnChangeMelodyKey( int Index );
	void __fastcall OnDirectionKey( WORD key );

	void __fastcall DoCancelAll(System::TObject* Sender);
	void __fastcall DoSelectAll(System::TObject* Sender);
	void __fastcall DoInsertBlankBar(System::TObject* Sender);
	void __fastcall DoBarsCopy(System::TObject* Sender);
	void __fastcall DoBarsCut(System::TObject* Sender);
	void __fastcall DoBarsDelete(System::TObject* Sender);
	void __fastcall DoBarsInsert(System::TObject* Sender);
	void __fastcall DoBarsChangeKey(System::TObject* Sender);
	void __fastcall DoChordCopy(System::TObject* Sender);
	void __fastcall DoChordPaste(System::TObject* Sender);
	void __fastcall DoChordDelete(System::TObject* Sender);
	void __fastcall DoAudioDelete(System::TObject* Sender);
	void __fastcall DoAudioCopy(System::TObject* Sender);
	void __fastcall DoAudioCut(System::TObject* Sender);
	void __fastcall DoAudioPaste(System::TObject* Sender);
	void __fastcall DoAudioLoad(System::TObject* Sender);
	void __fastcall DoTrackAdd(System::TObject* Sender);
	void __fastcall DoTrackDel(System::TObject* Sender);
	void __fastcall DoTrackShow(System::TObject* Sender);
	void __fastcall DoTrackHide(System::TObject* Sender);
	void __fastcall DoTrackSave(System::TObject* Sender);
	void __fastcall DoTrackMute(System::TObject* Sender);
	void __fastcall DoTrackSolo(System::TObject* Sender);
	void __fastcall DoInsertTexture(TObject* Sender);
	void __fastcall DoDeleteTexture(TObject* Sender);
	void __fastcall DoSwitchTexture(TObject* Sender);
	void __fastcall DoSwitchFontProg(TObject* Sender);
	void __fastcall DoTrackSwitchTexture(TObject* Sender);
	void __fastcall DoTrackSwitchFontProg(TObject* Sender);

	void __fastcall CreateEditMenu(TMenuPanel *Menu, bool bEnabled);
	void __fastcall CreateTrackMenu(TMenuPanel *Menu, bool bEnabled);

	__fastcall virtual TContentPanel(System::Classes::TComponent* AOwner);
	__fastcall ~TContentPanel();
};

#endif
