//-------------------------------------------------------------------------
//
// File:		DemopajaPlayerC.cpp
// Purpose:		Moppi Demopaja Player class header
// Author:		memon <memon@inside.org>
// Version:		0.6
//
//-------------------------------------------------------------------------
//	Copyright (c) 2000 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://moppi.inside.org/demopaja/
//-------------------------------------------------------------------------


#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
#include <windows.h>

#include "PajaTypes.h"
#include "SceneC.h"
#include "FileListC.h"
#include "DemopajaVersion.h"
#include "DeviceContextC.h"
#include "TimeContextC.h"
#include "DeviceFeedbackC.h"
#include <string>
#include <vector>
#include "fmod.h"



typedef void	(*LoadCallbackF)( PajaTypes::float32 f32Percent );


//! Demopaja Player class.
/*! DemopajaPlayerC class provides easy to use stand alone player for Moppi Demopaja files.
*/
class DemopajaPlayerC
{
public:
	//! Default constructor.
	DemopajaPlayerC();
	//! Default destructor.
	virtual ~DemopajaPlayerC();

	//! Registers and internal plugin class.
	/*!	\param pDesc Plugin class to register.
		This method provides a way to include the effect code inside the player without
		loading the effect from a DLL.
		
		Example:
		\b ImageEffectC.h
		\code
		// Global class descriptor.
		ImageDescC		g_rImageDesc;
		\endcode

		\b DemoPlayer.h
		\code
		#include "ImageEffectC.h"

		...

		rPlayer.register_plugin( &g_rImageDesc );
		\endcode
	*/
	void				register_plugin( PluginClass::ClassDescC* pDesc );

	//! Loads plugins from DLLs.
	/*! Loads plugins from specified path.
	*/
	void				load_plugins( const char* szPath );

	//! Initialises the player.
	/*!	Intialises necessary data for load_demo() and run(). Must be called before load_demo() and run().
	*/
	bool				init( HINSTANCE hInst, bool bFullScreen );

	void				set_fullscreen_resolution( PajaTypes::uint32 ui32Width, PajaTypes::uint32 ui32Height );

	//! Loads the demo file.
	/*!	Must be called after init().
	*/
	PajaTypes::uint32	load_demo( const char* szFileName );

	//! Loads the demo memory.
	/*!	Must be called after init().
	*/
	PajaTypes::uint32	load_demo( PajaTypes::uint8* pData, PajaTypes::uint32 ui32Size );

	//! Sets pointer where the music is laoded.
	/*!	Must be called before load_demo().
		Only the pointer is stored, so the data must exists when the load_demo() is called.
	*/
	void				set_music_data( PajaTypes::uint8* pData, PajaTypes::uint32 ui32Size );

	void				set_load_callback( LoadCallbackF pFunc );

	//! Runs the demo.
	/*! \returns 0 (zero) on success, else -1.
	*/
	PajaTypes::int32	run();

private:

	PajaTypes::uint32			load_scene( FileIO::LoadC* pLoad );
	bool						init_music_system();
	void						initialise_data( PajaTypes::uint32 ui32Reason );

	void						play_music( PajaTypes::int32 i32Time );
	void						stop_music();
	PajaTypes::int32			get_music_pos();


	PajaSystem::DemoInterfaceC*	m_pDemoInterface;
	PajaSystem::DeviceContextC*	m_pDeviceContext;
	PajaSystem::TimeContextC*	m_pTimeContext;
	Import::FileListC*			m_pFileList;
	Composition::SceneC*		m_pScene;
	PluginClass::FactoryC		m_rFactory;

	bool						m_bFullscreen;
	std::string					m_sMusicFile;

	PluginClass::ClassIdC		m_rGraphicsDeviceId;
	std::string					m_sGraphicsDeviceName;
	PajaSystem::DeviceFeedbackC	m_rDeviceFeedback;

	static FSOUND_STREAM*		m_pMusicStream;
	static bool					m_bMusicSystemPresent;
	static PajaTypes::int32		m_i32MusicChannel;

	PajaTypes::int32			m_i32MusicStartTime;
	PajaTypes::float64			m_f64MusicTimeScale;

	static HINSTANCE			m_hInst;

	PajaTypes::uint8*			m_pMusicData;
	PajaTypes::uint32			m_ui32MusicDataSize;

	PajaTypes::uint32			m_ui32FullscreenWidth;
	PajaTypes::uint32			m_ui32FullscreenHeight;

	LoadCallbackF				m_pLoadCallback;
};