//
// EnginePlugin
//
// This example plugin demostrates loading proprietary file format,
// how to use the file duration methods, and how to set the value
// of a parameter when another parameter changes.
//

#ifndef __ENGINEPLUGIN_H__
#define __ENGINEPLUGIN_H__


#include "DemopajaVersion.h"
#include "PajaTypes.h"
#include "EffectI.h"
#include "EditableI.h"
#include "UndoC.h"
#include "ParamI.h"
#include "ImportableImageI.h"
#include "BBox2C.h"
#include "Matrix2C.h"
#include "DeviceContextC.h"
#include "DeviceInterfaceI.h"
#include "OpenGLDeviceC.h"
#include "OpenGLViewportC.h"
#include "ImportInterfaceC.h"
#include "TimeContextC.h"
#include "AutoGizmoC.h"

#include "ScenegraphItemI.h"
#include "MeshC.h"
#include "LightC.h"
#include "CameraC.h"


//////////////////////////////////////////////////////////////////////////
//
//  Class IDs
//  Remember to make new ones if you this file as template!
//

const PluginClass::ClassIdC	CLASS_ASE_IMPORT( 0x7031F6CF, 0x748B4C4C );
const PluginClass::ClassIdC	CLASS_ASEPLAYER_EFFECT( 0x0B492425, 0x52474FC9 );


//////////////////////////////////////////////////////////////////////////
//
//  ASE importer class descriptor.
//

class ASEImportDescC : public PluginClass::ClassDescC
{
public:
	ASEImportDescC();
	virtual ~ASEImportDescC();
	virtual void*						create();
	virtual PajaTypes::int32			get_classtype() const;
	virtual PluginClass::SuperClassIdC	get_super_class_id() const;
	virtual PluginClass::ClassIdC		get_class_id() const;
	virtual const char*					get_name() const;
	virtual const char*					get_desc() const;
	virtual const char*					get_author_name() const;
	virtual const char*					get_copyright_message() const;
	virtual const char*					get_url() const;
	virtual const char*					get_help_filename() const;
	virtual PajaTypes::uint32			get_required_device_driver_count() const;
	virtual const PluginClass::ClassIdC&	get_required_device_driver( PajaTypes::uint32 ui32Idx );
	virtual PajaTypes::uint32			get_ext_count() const;
	virtual const char*					get_ext( PajaTypes::uint32 ui32Index ) const;
};


//////////////////////////////////////////////////////////////////////////
//
//  ASE player effect class descriptor.
//

class EngineDescC : public PluginClass::ClassDescC
{
public:
	EngineDescC();
	virtual ~EngineDescC();
	virtual void*						create();
	virtual PajaTypes::int32			get_classtype() const;
	virtual PluginClass::SuperClassIdC	get_super_class_id() const;
	virtual PluginClass::ClassIdC		get_class_id() const;
	virtual const char*					get_name() const;
	virtual const char*					get_desc() const;
	virtual const char*					get_author_name() const;
	virtual const char*					get_copyright_message() const;
	virtual const char*					get_url() const;
	virtual const char*					get_help_filename() const;
	virtual PajaTypes::uint32			get_required_device_driver_count() const;
	virtual const PluginClass::ClassIdC&	get_required_device_driver( PajaTypes::uint32 ui32Idx );
	virtual PajaTypes::uint32			get_ext_count() const;
	virtual const char*					get_ext( PajaTypes::uint32 ui32Index ) const;
};


namespace EnginePlugin {


//////////////////////////////////////////////////////////////////////////
//
// ASE Importer class.
//

class ASEImportC : public Import::ImportableI
{
public:
	static ASEImportC*				create_new();
	virtual Edit::DataBlockI*		create();
	virtual Edit::DataBlockI*		create( Edit::EditableI* pOriginal );
	virtual void					copy( Edit::EditableI* pEditable );
	virtual void					restore( Edit::EditableI* pEditable );

	virtual const char*				get_filename();
	virtual bool					load_file( const char* szName, Import::ImportInterfaceC* pInterface );
	virtual void					initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DeviceContextC* pContext, PajaSystem::TimeContextC* pTimeContext );

	virtual PluginClass::ClassIdC	get_class_id();
	virtual	PluginClass::SuperClassIdC	get_super_class_id();
	virtual const char*				get_class_name();

	virtual const char*				get_info();
	virtual PluginClass::ClassIdC	get_default_effect();

	virtual PajaTypes::int32		get_duration( PajaSystem::TimeContextC* pTimeContext );
	virtual PajaTypes::float32		get_start_label( PajaSystem::TimeContextC* pTimeContext );
	virtual PajaTypes::float32		get_end_label( PajaSystem::TimeContextC* pTimeContext );

	virtual PajaTypes::uint32		get_reference_file_count();
	virtual Import::FileHandleC*	get_reference_file( PajaTypes::uint32 ui32Index );


	virtual PajaTypes::uint32		get_scenegraphitem_count();
	virtual MeshC*					get_scenegraphitem( PajaTypes::uint32 ui32Index );

	virtual PajaTypes::uint32		get_camera_count();
	virtual CameraC*				get_camera( PajaTypes::uint32 ui32Index );

	virtual PajaTypes::uint32		get_light_count();
	virtual LightC*					get_light( PajaTypes::uint32 ui32Index );

	virtual void					get_time_parameters( PajaTypes::int32& i32FPS, PajaTypes::int32& i32TicksPerFrame, PajaTypes::int32& i32FirstFrame, PajaTypes::int32& i32LastFrame );


	virtual PajaTypes::uint32		save( FileIO::SaveC* pSave );
	virtual PajaTypes::uint32		load( FileIO::LoadC* pLoad );

protected:
	ASEImportC();
	ASEImportC( Edit::EditableI* pOriginal );
	virtual ~ASEImportC();

private:

	void							count_file_references( MeshC* pMesh );
	PajaTypes::uint32				save_scenegraphitem( FileIO::SaveC* pSave, MeshC* pItem,
															PajaTypes::uint32 ui32ParentId, PajaTypes::uint32& ui32Id );
	MeshC*							find_parent( MeshC* pItem, PajaTypes::uint32 ui32ParentId );


	std::string							m_sFileName;
	bool								m_bFileRefsValid;
	std::vector<Import::FileHandleC*>	m_rFileRefs;

	std::vector<MeshC*>					m_rScenegraph;
	std::vector<CameraC*>				m_rCameras;
	std::vector<LightC*>				m_rLights;
	PajaTypes::int32					m_i32FPS;
	PajaTypes::int32					m_i32TicksPerFrame;
	PajaTypes::int32					m_i32FirstFrame;
	PajaTypes::int32					m_i32LastFrame;
};


//////////////////////////////////////////////////////////////////////////
//
// The transform gizmo class.
//

enum TransformGizmoParamsE {
	ID_TRANSFORM_POS = 0,
	ID_TRANSFORM_SCALE,
	TRANSFORM_COUNT,
};

class TransformGizmoC : public Composition::GizmoI
{
public:

	static TransformGizmoC*			create_new( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
	virtual Edit::DataBlockI*		create();
	virtual Edit::DataBlockI*		create( Edit::EditableI* pOriginal );
	virtual void					copy( Edit::EditableI* pEditable );
	virtual void					restore( Edit::EditableI* pEditable );

	virtual PajaTypes::int32		get_parameter_count();
	virtual Composition::ParamI*	get_parameter( PajaTypes::int32 i32Index );

	virtual PajaTypes::uint32		save( FileIO::SaveC* pSave );
	virtual PajaTypes::uint32		load( FileIO::LoadC* pLoad );

	PajaTypes::Vector2C				get_pos( PajaTypes::int32 i32Time );
	PajaTypes::Vector2C				get_scale( PajaTypes::int32 i32Time );

protected:
	TransformGizmoC();
	TransformGizmoC( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
	TransformGizmoC( Edit::EditableI* pOriginal );
	virtual ~TransformGizmoC();

private:
	void							init();

	Composition::ParamVector2C*	m_pParamPos;
	Composition::ParamVector2C*	m_pParamScale;
};


//////////////////////////////////////////////////////////////////////////
//
// The attributes gizmo class.
//

enum AttributeGizmoParamsE {
	ID_ATTRIBUTE_SIZE = 0,
	ID_ATTRIBUTE_FPS,
	ID_ATTRIBUTE_CAMERA,
	ID_ATTRIBUTE_CLEAR,
	ID_ATTRIBUTE_CLEARCOLOR,
	ID_ATTRIBUTE_FILE,
	ATTRIBUTE_COUNT,
};

class AttributeGizmoC : public Composition::GizmoI
{
public:

	static AttributeGizmoC*			create_new( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
	virtual Edit::DataBlockI*		create();
	virtual Edit::DataBlockI*		create( Edit::EditableI* pOriginal );
	virtual void					copy( Edit::EditableI* pEditable );
	virtual void					restore( Edit::EditableI* pEditable );

	virtual PajaTypes::int32		get_parameter_count();
	virtual Composition::ParamI*	get_parameter( PajaTypes::int32 i32Index );

	virtual PajaTypes::uint32		save( FileIO::SaveC* pSave );
	virtual PajaTypes::uint32		load( FileIO::LoadC* pLoad );

	virtual void					update_notify( PajaTypes::uint32 ui32ID, PajaTypes::int32 i32Time );

	void							init();

	PajaTypes::Vector2C				get_size( PajaTypes::int32 i32Time );
	PajaTypes::int32				get_fps( PajaTypes::int32 i32Time );
	CameraC*						get_camera( PajaTypes::int32 i32Time );
	bool							get_clear( PajaTypes::int32 i32Time );
	PajaTypes::ColorC				get_clear_color( PajaTypes::int32 i32Time );
	ASEImportC*						get_file();

protected:
	AttributeGizmoC();
	AttributeGizmoC( Composition::EffectI* pParent, PajaTypes::uint32 ui32Id );
	AttributeGizmoC( Edit::EditableI* pOriginal );
	virtual ~AttributeGizmoC();

private:
	Composition::ParamVector2C*	m_pParamSize;
	Composition::ParamIntC*		m_pParamFps;
	Composition::ParamIntC*		m_pParamCamera;
	Composition::ParamIntC*		m_pParamClear;
	Composition::ParamColorC*	m_pParamClearColor;
	Composition::ParamFileC*	m_pParamFile;
};


//////////////////////////////////////////////////////////////////////////
//
// The Image effect class.
//

enum ImageEffectGizmosE {
	ID_GIZMO_TRANS = 0,
	ID_GIZMO_ATTRIB,
	GIZMO_COUNT,
};

class EngineEffectC : public Composition::EffectI
{
public:
	static EngineEffectC*			create_new();
	virtual Edit::DataBlockI*		create();
	virtual Edit::DataBlockI*		create( Edit::EditableI* pOriginal );
	virtual void					copy( Edit::EditableI* pEditable );
	virtual void					restore( Edit::EditableI* pEditable );

	virtual PajaTypes::int32		get_gizmo_count();
	virtual Composition::GizmoI*	get_gizmo( PajaTypes::int32 i32Index );

	virtual PluginClass::ClassIdC	get_class_id();
	virtual const char*				get_class_name();

	virtual void					set_default_file( Import::FileHandleC* pHandle );
	virtual Composition::ParamI*	get_default_param( PajaTypes::int32 i32Param );

	virtual void					initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DeviceContextC* pContext, PajaSystem::TimeContextC* pTimeContext );

	virtual void					do_frame( PajaSystem::DeviceContextC* pContext );
	virtual void					eval_state( PajaTypes::int32 i32Time, PajaSystem::TimeContextC* pTimeContext );
	virtual PajaTypes::BBox2C		get_bbox();

	virtual const PajaTypes::Matrix2C&	get_transform_matrix() const;

	virtual bool					hit_test( const PajaTypes::Vector2C& rPoint );

	virtual PajaTypes::uint32		save( FileIO::SaveC* pSave );
	virtual PajaTypes::uint32		load( FileIO::LoadC* pLoad );


protected:
	EngineEffectC();
	EngineEffectC( Edit::EditableI* pOriginal );
	virtual ~EngineEffectC();

private:

	void							render_item( PajaSystem::OpenGLDeviceC* pDevice, MeshC* pMesh, PajaTypes::int32 i32Frame );

	TransformGizmoC*			m_pTransGizmo;
	AttributeGizmoC*			m_pAttribGizmo;

	PajaTypes::int32			m_i32Frame;
	PajaTypes::float32			m_f32Aspect;
	PajaTypes::ColorC			m_rClearColor;
	bool						m_bDoClear;
	CameraC*					m_pCam;

	PajaTypes::Matrix2C			m_rTM;
	PajaTypes::BBox2C			m_rBBox;
};

};	// namespace

// The global descriptors.
extern EngineDescC		g_rEngineDesc;
extern ASEImportDescC	g_rASEImportDesc;


#endif	// __ENGINEPLUGIN_H__
