// demopajaDoc.h : interface of the CDemopajaDoc class
//
/////////////////////////////////////////////////////////////////////////////

#if !defined(AFX_DEMOPAJADOC_H__B4C5B4EE_2A90_11D4_A80C_0000E8D926FD__INCLUDED_)
#define AFX_DEMOPAJADOC_H__B4C5B4EE_2A90_11D4_A80C_0000E8D926FD__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "stdafx.h"
#include "EditableI.h"
#include "DataBlockI.h"
#include "PajaTypes.h"
#include "LayerC.h"
#include "EffectI.h"
#include "GizmoI.h"
#include "SceneC.h"
#include "UndoManagerC.h"
#include "ImportableI.h"
#include <vector>
#include "FileListC.h"
#include "FileIO.h"
#include "KeySelectorC.h"
#include "DeviceFeedbackC.h"
#include "DemoInterfaceC.h"
#include "fmod.h"
#include "ColorSwatchSetC.h"
#include "BBox2C.h"

#define			MUSIC_BAND_COUNT		8

const PajaTypes::uint32	REDRAW_VIEWS = 0x10;
const PajaTypes::uint32	RECALC_VIEWS = 0x20;

enum RedrawFlagsE {
	NOTIFY_REDRAW_GRAPHICS		= 0,
	NOTIFY_REDRAW_ALL			= 1,
	NOTIFY_RESET_VIEWS			= 2,
	NOTIFY_FILELIST_CHANGED		= 3,
	NOTIFY_LAYERLIST_CHANGED	= 4,
};

enum EditFocusE {
	FOCUS_NONE = 0,
	FOCUS_VIEW,
	FOCUS_INSPECTOR,
	FOCUS_TIMELINE,
	FOCUS_LAYERLIST,
	FOCUS_PARAMETERS,
};

enum ToolE {
	TOOL_ARROW = 0,
	TOOL_ROTATE,
	TOOL_SCALE,
	TOOL_KEYARROW,
	TOOL_PAN,
	TOOL_ZOOM,
};

enum MusicDataViewE {
	MUSIC_VIEW_MONO = 0,
	MUSIC_VIEW_STEREO,
	MUSIC_VIEW_LEFT,
	MUSIC_VIEW_RIGHT,
	MUSIC_VIEW_BAND_0,
	MUSIC_VIEW_BAND_1,
	MUSIC_VIEW_BAND_2,
	MUSIC_VIEW_BAND_3,
	MUSIC_VIEW_BAND_4,
	MUSIC_VIEW_BAND_5,
	MUSIC_VIEW_BAND_6,
	MUSIC_VIEW_BAND_7,
};

enum GetTimeFromStringFormatE {
	TIME_FORMAT_HOUR_MIN_SEC,
	TIME_FORMAT_HOUR_MIN_SEC_FRAME,
};




class CDemopajaDoc : public CDocument
{
protected:
	// create from serialization only
	CDemopajaDoc();
	DECLARE_DYNCREATE(CDemopajaDoc)

public:

	static CLIPFORMAT			GetPrivateClipboardFormat();

	void						SetTool( ToolE eTool );
	PajaTypes::uint32			GetTool();

	void						UndoNotify();

	void						AskDemoProperties();

	void						SetEditFocus( PajaTypes::int32 i32Focus );
	PajaTypes::int32			GetEditFocus();

	void						OnCut();
	void						OnCopy();
	void						OnPaste();

	void						SetDrawRulers( bool bState );
	bool						GetDrawRulers();
	void						SetDrawGrid( bool bState );
	bool						GetDrawGrid();
	void						SetSnapToGrid( bool bState );
	bool						GetSnapToGrid();
	PajaTypes::int32			GetGridSize();
	void						SetGridSize( PajaTypes::int32 i32GridSize );
	void						SetShowMarkers( bool bState );
	bool						GetShowMarkers();

	PajaTypes::int32			GetFrameSizeInTicks();
	PajaTypes::int32			GetEditAccuracy();
	PajaTypes::int32			GetBeatsPerMin();
	PajaTypes::int32			GetQNotesPerBeat();
	PajaTypes::int32			GetBeatsPerMeasure();

	PajaTypes::int32			GetLastFrameTime();
	PajaTypes::int32			TimeToFrame( PajaTypes::int32 i32Time );
	PajaTypes::int32			FrameToTime( PajaTypes::int32 i32Frame );
	void						SetTimecursor( PajaTypes::int32 i32Time );
	PajaTypes::int32			GetTimecursor();
	PajaTypes::int32			GetTimeFromString( const char* szStr, PajaTypes::uint32 ui32Format );


	// show/hide
	void						AddFlagsAll( PajaTypes::int32 i32ModMask, PajaTypes::int32 i32Flags );
	void						DelFlagsAll( PajaTypes::int32 i32ModMask, PajaTypes::int32 i32Flags );
	void						ToggleFlagsAll( PajaTypes::int32 i32ModMask, PajaTypes::int32 i32Flags );

	bool						CanCopy();
	bool						CanPaste();

	void						ApplyChanges();
	void						CancelChanges();

	void						KeysDeleteSelected();
	void						KeysDeselectAll();
	void						KeysSaveStateSelected( const char* szAction );
	void						KeysSaveStateItem( SceneItemC* pItem, const char* szAction );
	void						KeysMoveTime( PajaTypes::int32 i32DeltaTime );
	void						KeysMoveValue( SceneItemC* pItem, PajaTypes::int32 i32Channel, PajaTypes::float32 f32Delta );
	void						KeysDeselectKey( SceneItemC* pItem, PajaTypes::int32 i32Time );
	void						KeysSelectKey( SceneItemC* pItem, PajaTypes::int32 i32Time );
	bool						KeysSelectInRange( SceneItemC* pItem, PajaTypes::int32 i32StartTime, PajaTypes::int32 i32EndTime );
	void						KeysSelectAll( SceneItemC* pItem );
	void						KeysSetInterpolation( PajaTypes::uint32 ui32Type );
	void						KeysSetInterpolationProperty( PajaTypes::uint32 ui32Type, PajaTypes::float32 f32Val );
	void						KeysGatherCommonValues( CommonKeyValuesS* pCommon );

	void						ControllerAddKeyAtTime( Composition::ControllerC* pCont, PajaTypes::int32 i32Time );
	void						ControllerSetStartOutOfRange( Composition::ControllerC* pCont, PajaTypes::uint32 ui32ORT );
	void						ControllerSetEndOutOfRange( Composition::ControllerC* pCont, PajaTypes::uint32 ui32ORT );

	void						ParameterToggleAnim( Composition::ParamI* pParam, PajaTypes::int32 i32Time );
	PajaTypes::float32			ParameterGetValue( Composition::ParamI* pParam, PajaTypes::int32 i32Time, PajaTypes::uint32 ui32Channel );
	PajaTypes::int32			ParameterSetValue( Composition::ParamI* pParam, PajaTypes::int32 i32Time, PajaTypes::uint32 ui32Channel, PajaTypes::float32 );
	PajaTypes::int32			ParameterCreateValue( Composition::ParamI* pParam, PajaTypes::int32 i32Time );
	void						ParameterShow( Composition::ParamI* pParam, bool bShow );
	PajaTypes::int32			ParameterTypeIn( Composition::ParamI* pParam, PajaTypes::int32 i32Time );
	PajaTypes::int32			ParameterTypeInShowDlg( Composition::ParamI* pParam, PajaTypes::int32 i32Time );
	void						ParameterSaveState( Composition::ParamI* pParam, PajaTypes::int32 i32Time );
	PajaTypes::int32			ParameterGetTimeOffset( Composition::ParamI* pParam );
	void						ParameterSetFile( Composition::ParamI* pParam, PajaTypes::int32 i32Time, Import::FileHandleC* pHandle );

	void						GizmoShow( Composition::GizmoI* pGizmo, bool bShow );

	void						TimeSegmentTypeIn( Composition::EffectI* pEffect, PajaTypes::int32 i32Time );
	void						TimeSegmentTypeIn( Composition::LayerC* pLayer, PajaTypes::int32 i32Time );
	void						TimeSegmentTypeIn( Composition::TimeSegmentC* pSeg, PajaTypes::int32 i32Time, PajaTypes::int32 i32TimeOffset, PajaTypes::int32 i32Type );
	void						TimeSegmentAddKeyAtTime( Composition::EffectI* pEffect, PajaTypes::int32 i32Time );
	void						TimeSegmentAddKeyAtTime( Composition::LayerC* pLayer, PajaTypes::int32 i32Time );
	void						TimeSegmentAddKeyAtTime( Composition::TimeSegmentC* pSeg, PajaTypes::int32 i32Time );
	void						TimeSegmentSaveState( Composition::TimeSegmentC* pSeg, const char* szAction );

	void						EffectEditName( Composition::EffectI* pEffect, const char* szName );
	Composition::EffectI*		EffectCreate( const PluginClass::ClassIdC& rClassId, const char* szName, Composition::LayerC* pLayer, PajaTypes::int32 i32Time, Import::FileHandleC* pHandle = 0 );
	void						EffectDeleteSelected( bool bCut = false );
	void						EffectMoveAfter( PajaTypes::int32 i32Item, PajaTypes::int32 i32ItemLayer, PajaTypes::int32 i32ItemAfter, PajaTypes::int32 i32ItemAfterLayer );
	void						EffectMoveBefore( PajaTypes::int32 i32Item, PajaTypes::int32 i32ItemLayer, PajaTypes::int32 i32ItemBefore, PajaTypes::int32 i32ItemBeforeLayer );
	Composition::EffectI*		EffectGetSelected();

	void						LayerEditName( Composition::LayerC* pLayer, const char* szName );
	void						LayerAdd( PajaTypes::int32 i32Time );
	void						LayerDeleteSelected( bool bCut = false );
	void						LayerMoveAfter( PajaTypes::int32 i32Item, PajaTypes::int32 i32ItemAfter );
	void						LayerMoveBefore( PajaTypes::int32 i32Item, PajaTypes::int32 i32ItemBefore );
	Composition::LayerC*		LayerGetSelected();
	void						LayerAndEffectDeleteSelected( bool bCut = false );

	void						MarkerTypeIn( PajaTypes::int32 i32MarkerIdx );
	void						MarkerDelete( PajaTypes::int32 i32MarkerIdx );
	void						MarkerAdd( PajaTypes::int32 i32Time );
	void						MarkerSaveState( const char* szAction );

	// file list
	Import::FileListC*			GetFileList();
	PajaSystem::DemoInterfaceC*	GetDemoInterface();

	// undo stuff
	Edit::UndoManagerC*			GetUndoManager();

	// import a file
	void						ImportFile( Import::FileHandleC* pFolder );
	Import::FileHandleC*		CreateFile( const PluginClass::ClassIdC& rClassId, Import::FileHandleC* pFolder );
	Import::FileHandleC*		CreateFolder( const char* szName, Import::FileHandleC* pFolder, PajaTypes::uint32 ui32ColorFlags );
	void						RenameFolder( PajaTypes::uint32 ui32Index, const char* szName, PajaTypes::uint32 ui32ColorFlags );
	void						MoveFileOrder( PajaTypes::uint32 ui32Index, Import::FileHandleC* pNewParent );
	void						DeleteFile( PajaTypes::uint32 ui32Index );
	void						ReloadFile( PajaTypes::uint32 ui32Index );
	void						ReplaceFile( PajaTypes::uint32 ui32Index );
	void						PromptFileProperties( PajaTypes::uint32 ui32Index );
	void						UpdateFileHandles( Import::FileHandleC* pNewHandle, Composition::SceneC* pScene, Edit::UndoC* pUndo );
	void						FileUpdateNotify( Import::FileHandleC* pHandle );

	void						CreateScene( Import::FileHandleC* pFolder );
	PajaTypes::uint32			GetSceneCount();
	Composition::SceneC*		GetScene( PajaTypes::uint32 ui32Index );
	Composition::SceneC*		GetMainScene();
	Composition::SceneC*		GetCurrentScene();
	void						SetCurrentScene( PajaTypes::uint32 ui32Index );
	PajaTypes::int32			GetSceneLayerListPos();
	void						SetSceneLayerListPos( PajaTypes::int32 i32Pos );
	PajaTypes::BBox2C			GetSceneViewport() const;
	void						SetSceneViewport( const PajaTypes::BBox2C& rBox );
	void						AdjustSceneViewports( const PajaTypes::Vector2C& rDelta );

	// export script
	bool						ExportScript( const char* szName );
	bool						ExportAVI( const char* szName );

	// update file references
	void						UpdateFileReferences();

	// layout size
	PajaTypes::int32			GetLayoutWidth();
	PajaTypes::int32			GetLayoutHeight();

	// file io
	PajaTypes::uint32			Load( FileIO::LoadC* pLoad, bool bMerge );
	PajaTypes::uint32			LoadProperties( FileIO::LoadC* pLoad );
	PajaTypes::uint32			Save( FileIO::SaveC* pSave );

	// merge
	bool						OnMergeDocument( const char* szPathName, Import::FileHandleC* pFolder, bool bMergeFiles, bool bCreateScene );

	// music file
	const char*					GetMusicName();
	void						PlayMusic( PajaTypes::int32 i32Time );
	void						StopMusic();
	void						SetPosMusic( PajaTypes::int32 i32Time );
	bool						LoadMusic( const char* szFilename );
	void						ReleaseMusic();
	PajaTypes::int32			GetMusicPos();

	PajaTypes::uint8*			GetMusicData();
	PajaTypes::int32			GetMusicDataLength();
	PajaTypes::int32			GetMusicDataSamplesPerSecond();

	PajaTypes::uint8*			GetBandData( PajaTypes::uint32 ui32Band );
	PajaTypes::int32			GetBandDataLength();
	PajaTypes::int32			GetBandDataSamplesPerSecond();

	bool						GetMusicDataStereo();
	PajaTypes::int32			GetMusicDataView();
	void						SetMusicDataView( PajaTypes::int32 i32View );

	bool						GetMusicShowWaveform() const;
	void						SetMusicShowWaveform( bool bState );

	bool						GetPlayLoop();

	bool						CheckFileRecursion();
	void						InitialiseData( PajaTypes::uint32 ui32Reason );
	PajaSystem::DeviceFeedbackC*	GetDeviceFeedback();
	PajaSystem::DeviceContextC*		GetDeviceContext();

	void						HandleParamNotify( PajaTypes::uint32 ui32Notify );
	// All param notifies that should change the UI between begin/end defer
	// are ignored, and executed when EndDeferHandleParamNotify() is called
	void						BeginDeferHandleParamNotify();
	void						EndDeferHandleParamNotify();
	void						NotifyViews( PajaTypes::uint32 ui32Notify );

	PajaTypes::uint32			GetFrameID();
	void						IncFrameID();

	ColorSwatchSetC*			GetColorSwatchSet();

	void						SetProjectPath( const char* szPath, bool bTemp );
	const char*					GetProjectPath();
	bool						IsProjectPathTemporary();


	// Implementation
	virtual ~CDemopajaDoc();

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CDemopajaDoc)
	public:
	virtual BOOL OnNewDocument();
	virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
	virtual BOOL OnSaveDocument(LPCTSTR lpszPathName);
	virtual void DeleteContents();
	virtual void OnCloseDocument();
	//}}AFX_VIRTUAL

protected:

	void	ClearClipboard();
	void	UpdateSceneTimeSettigs( PajaTypes::int32 i32BPM, PajaTypes::int32 i32QNotesPerBeat, PajaTypes::int32 i32BeatsPerMeasure, PajaTypes::int32 i32EditAccuracy );
	void	SetupDemoInterface( PajaSystem::DemoInterfaceC* pImpIface );
	void	UpdateSceneViewList();

	enum ClipboardE {
		CLIPBOARD_NONE = 0,
		CLIPBOARD_EFFECT,
		CLIPBOARD_LAYER,
		CLIPBOARD_KEYS,
		CLIPBOARD_TIMESEG_KEYS,
	};

	struct ClipboardS {
		Composition::LayerC*				m_pLayer;
		std::vector<Composition::EffectI*>	m_rEffects;
		std::vector<Composition::KeyC*>		m_rKeys;
		PluginClass::ClassIdC				m_rFilterClassId;
		PluginClass::SuperClassIdC			m_rFilterSuperClassId;
		ClipboardE							m_eType;
		PajaTypes::int32					m_i32ParamType;
		Composition::SceneC*				m_pFromScene;
	};

	struct SceneViewS {
		Composition::SceneC*	m_pScene;
		PajaTypes::int32		m_i32LayerListPos;
		PajaTypes::BBox2C		m_rViewport;
	};

	struct KeyStateS {
		Composition::FloatKeyC*	m_pKey;
		PajaTypes::float32		m_f32Values[Composition::KEY_MAXCHANNELS];
	};
	std::vector<KeyStateS>	m_rKeyStates;

	std::vector<SceneViewS>	m_rSceneViews;
	PajaTypes::int32		m_i32CurrentSceneIdx;
	Composition::SceneC*	m_pMainScene;
	Composition::SceneC*	m_pCurrentScene;


	Edit::UndoManagerC		m_rUndoManager;
	
	static CLIPFORMAT		m_rClipboardFormat;
	
	Import::FileListC*		m_pFileList;
	std::string				m_sComment;
	std::string				m_sMusicFile;
	bool					m_bFirstNewDoc;
	bool					m_bDrawRulers;
	bool					m_bDrawGrid;
	bool					m_bSnapToGrid;
	bool					m_bShowMarkers;
	PajaTypes::int32		m_i32GridSize;
	PajaTypes::int32		m_i32EditFocus;
	KeySelectorC*			m_pKeySelector;
	ClipboardS				m_rClipboard;
	ToolE					m_eTool;

	// Music system
	FSOUND_STREAM*			m_pStream;
	PajaTypes::int32		m_i32Channel;
	bool								m_bStreamTimeFirstUpdate;

//	PajaTypes::uint8*		m_pBandData[MUSIC_BAND_COUNT];
//	PajaTypes::int32		m_i32BandDataLength;

	PajaTypes::uint8*		m_pMusicData;
	PajaTypes::int32		m_i32MusicDataLength;
	PajaTypes::int32		m_i32MusicDataView;
	bool					m_bMusicDataStereo;
	PajaSystem::DeviceContextC*	m_pDeviceContext;
	PajaSystem::DeviceFeedbackC	m_rDeviceFeedback;
	PajaSystem::TimeContextC*	m_pTimeContext;
	PajaSystem::DemoInterfaceC*	m_pDemoInterface;
	PajaTypes::int32		m_i32MusicTime;
	PajaTypes::int32		m_i32MusicStartTime;
	PajaTypes::float64		m_f64MusicTimeScale;
	bool					m_bShowWaveform;

	bool					m_bPlayLoop;
	bool					m_bPlayMusic;

	CFont					m_rDefaultFont;
	LOGFONT					m_rDefaultLogfont;

	ColorSwatchSetC			m_rColorSwatches;

	std::string				m_sProjectPath;
	bool					m_bSaveProjectPath;

	// Merge options
	Import::FileHandleC*	m_pMergeFolder;
	bool					m_bMergeFiles;
	bool					m_bMergeCreateScene;
	std::string				m_sMergeName;

	bool					m_bDeferParamUpdateNotify;
	PajaTypes::uint32		m_ui32DeferParamUpdateNotifyMsg;

	Edit::UndoC*			m_pCurrentUndo;

	// Generated message map functions
	//{{AFX_MSG(CDemopajaDoc)
	afx_msg void OnPlayLoop();
	afx_msg void OnUpdatePlayLoop(CCmdUI* pCmdUI);
	afx_msg void OnPlayPlaymusic();
	afx_msg void OnUpdatePlayPlaymusic(CCmdUI* pCmdUI);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};



// Get the document everywhere in the program...
CDemopajaDoc*	GetDoc();



/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DEMOPAJADOC_H__B4C5B4EE_2A90_11D4_A80C_0000E8D926FD__INCLUDED_)
