//-------------------------------------------------------------------------
//
// File:		SceneC.h
// Desc:		Composition scene class.
// Author:		memon <memon@inside.org>
//
//-------------------------------------------------------------------------
//	Copyright (c) 2000-2004 Moppi Productions. All Rights Reserved.
//  This file is part of Moppi Demopaja SDK. For conditions of 
//  distribution and use, see the accompanying license.txt file.
//  http://www.demopaja.org
//-------------------------------------------------------------------------

#ifndef __DEMOPAJA_SCENEC_H__
#define __DEMOPAJA_SCENEC_H__


namespace Composition {
	class SceneC;
};

#include "DataBlockI.h"
#include "EditableI.h"
#include "UndoC.h"
#include "LayerC.h"
#include "PajaTypes.h"
#include "ColorC.h"
#include "DeviceContextC.h"
#include "TimeContextC.h"
#include <vector>
#include <string>


namespace Composition {

	//! Base classID.
	const PluginClass::SuperClassIdC		BASECLASS_SCENE = PluginClass::SuperClassIdC( 1, 10 );

	//! Composition scene class.
	/*!	The base of the demo in Demopaja is scene. The layers are store inside
		the scene. Scene also contains information about the size of the canvas
		where the demo is shown and the speed of the demo.

		The changes made to the scene is saved to a undo object if present.

		This class is implemented by the system.
	*/
	class SceneC : public Edit::EditableI
	{
	public:
		//! Creates new, empty scene.
		static SceneC*				create_new();
		//! Creates new, empty scene.
		virtual Edit::DataBlockI*	create();
		//! Creates new scene (used internally), see Edit::EditableI::create().
		virtual Edit::DataBlockI*	create( Edit::EditableI* pOriginal );
		//! Deep copy from a data block, see Edit::DataBlockI::copy().
		virtual void				copy( Edit::EditableI* pEditable );
		//! Shallow copy from a editable, see Edit::EditableI::restore().
		virtual void				restore( Edit::EditableI* pEditable );
		//! Returns the base class ID.
		virtual PluginClass::SuperClassIdC		get_base_class_id() const;
		//! Update notify from a connected editable.
		virtual PajaTypes::uint32							update_notify( EditableI* pCaller );

		//! Sets the name of the scene.
		void						set_name( const char* szName );
		//! Returns the name of the scene.
		const char*					get_name() const;

		//! Returns number of layers in the scene.
		PajaTypes::uint32			get_layer_count();
		//! Returns a layer at specified index.
		LayerC*						get_layer( PajaTypes::uint32 ui32Index );
		//! Adds new layer to the scene.
		LayerC*						add_layer();
		//! Deletes a layer at specified index.
		void						del_layer( PajaTypes::uint32 ui32Index );
		//! Moves the order of a layer.
		/*! \param ui32Index the index of the layer to move.
			\param ui32IndexBefore the index of the layer before the layer is moved.
			Moves the layer before another layer.
		*/
		void						move_layer_before( PajaTypes::uint32 ui32Index, PajaTypes::uint32 ui32IndexBefore );

		//! Returns number of beats per minute (BPM) of the demo.
		PajaTypes::int32			get_beats_per_min();
		//! Sets number of beats per minute (BPM) of the demo.
		void						set_beats_per_min( PajaTypes::int32 i32BeatsPerMin );

		//! Returns the edit accuracy of the demo.
		PajaTypes::int32			get_edit_accuracy();
		//! Sets the edit accuracy of the demo.
		void						set_edit_accuracy( PajaTypes::int32 i32Accuracy );

		//! Returns number of beats per measure of the demo.
		PajaTypes::int32			get_beats_per_measure();
		//! Sets number of beats per measure of the demo.
		void						set_beats_per_measure( PajaTypes::int32 i32Beats );

		//! Returns number of quater-notes per beat.
		PajaTypes::int32			get_qnotes_per_beat();
		//! Sets number of quater-notes per beat.
		void						set_qnotes_per_beat( PajaTypes::int32 i32QNotes );

		//! Returns the start time of the music.
		PajaTypes::int32			get_music_start_time() const;
		//! Sets the start time of the music.
		void						set_music_start_time( PajaTypes::int32 i32Time );

		//! Returns the current time.
		PajaTypes::int32			get_time() const;
		//! Sets the current time.
		void						set_time( PajaTypes::int32 i32Time );
		//! Returns the duration of the demo.
		/*!	The return value is number of quater-notes multiplied by 256.
		*/
		PajaTypes::int32			get_duration();
		//! Sets the duration of the demo.
		void						set_duration( PajaTypes::int32 i32Duration );

		//! Returns the width of the layout in pixels.
		PajaTypes::int32			get_layout_width();
		//! Sets the width of the layout in pixels.
		void						set_layout_width( PajaTypes::int32 i32Width );

		//! Returns the height of the layout in pixels.
		PajaTypes::int32			get_layout_height();
		//! Sets the height of the layout in pixels.
		void						set_layout_height( PajaTypes::int32 i32Height );

		//! Returns the layout color
		const PajaTypes::ColorC&	get_layout_color() const;

		//! Sets the layout color
		void						set_layout_color( const PajaTypes::ColorC& rCol );


		//! Returns the number of markers.
		PajaTypes::uint32			get_marker_count() const;
		//! Returns the time of the specified marker.
		PajaTypes::int32			get_marker_time( PajaTypes::uint32 ui32Index ) const;
		//! Returns the name of the specified marker.
		const char*					get_marker_name( PajaTypes::uint32 ui32Index ) const;
		//! Returns the color of the specified marker.
		PajaTypes::int32			get_marker_color( PajaTypes::uint32 ui32Index ) const;

		//! Sets the time of the specified marker
		void						set_marker_time( PajaTypes::uint32 ui32Index, PajaTypes::int32 i32Time );
		//! Sets the name of the specified marker.
		void						set_marker_name( PajaTypes::uint32 ui32Index, const char* szName );
		//! Sets the color of the specified marker.
		void						set_marker_color( PajaTypes::uint32 ui32Index, PajaTypes::int32 i32Color );

		//! Adds new marker at specified time.
		void						add_marker( PajaTypes::int32 i32Time, const char* szName, PajaTypes::int32 i32Color );
		//! Removes the specified marker.
		void						del_marker( PajaTypes::uint32 ui32Index );
		//! Sorts markers (time).
		void						sort_markers();

		//! Reset reference count (used internally).
		virtual void				reset_references();
		//! Updates each reference.
		virtual void					update_references();

		//! Relays the initialise for all effects in a scene.
		void						initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DemoInterfaceC* pInterface );

		//! Returns the parent of the parameter.
		virtual void				set_parent( EditableI* pParent );
		//! Sets the parent of the parameter.
		virtual EditableI*				get_parent();

		//! Serialize the key to a Demopaja output stream.
		PajaTypes::uint32			save( FileIO::SaveC* pSave );
		//! Serialize the key from a Demopaja input stream.
		PajaTypes::uint32			load( FileIO::LoadC* pLoad );
		//! Serialize the key from a Demopaja input stream with merge to old scnene.
		PajaTypes::uint32			load( FileIO::LoadC* pLoad, bool bMerge );

	protected:
		//! Default constructor.
		SceneC();
		//! Constructor with reference to the original.
		SceneC( Edit::EditableI* pOriginal );
		//! Default destructor.
		virtual ~SceneC();

	private:

		static int	compare_func( const void* vpParam1, const void* vpParam2 );

		struct MarkerS {
			PajaTypes::int32	m_i32Time;
			PajaTypes::int32	m_i32Color;
			std::string			m_sName;
		};

		std::vector<MarkerS>		m_rMarkers;
		std::string					m_sName;
		std::vector<LayerC*>		m_rLayers;
		PajaTypes::int32			m_i32BeatsPerMin;
		PajaTypes::int32			m_i32EditAccuracy;
		PajaTypes::int32			m_i32BeatsPerMeasure;
		PajaTypes::int32			m_i32QNotesPerBeat;
		PajaTypes::int32			m_i32Duration;
		PajaTypes::int32			m_i32LayoutWidth;
		PajaTypes::int32			m_i32LayoutHeight;
		PajaTypes::int32			m_i32Time;
		PajaTypes::int32			m_i32MusicStartTime;
		PajaTypes::ColorC			m_rLayoutColor;
		EditableI*						m_pParent;
	};

};

#endif // __DEMOPAJA_SCENEC_H__
