//
// DX9Mesh.h
//
// DX9Mesh Plugin
//
// Copyright (c) 2004 memon/moppi productions
//

#ifndef __DX9MeshPLUGIN_H__
#define __DX9MeshPLUGIN_H__


#include "DemopajaVersion.h"
#include "PajaTypes.h"
#include "EffectI.h"
#include "EditableI.h"
#include "UndoC.h"
#include "ParamI.h"
#include "BBox2C.h"
#include "Matrix2C.h"
#include "DeviceContextC.h"
#include "DeviceInterfaceI.h"
#include "DemoInterfaceC.h"
#include "DX9ViewportC.h"
#include "DX9DeviceC.h"
#include "TimeContextC.h"
#include "AutoGizmoC.h"
#include "ImportableImageI.h"
#include "CD3DModel.h"
#include "ASELoaderC.h"
#include "HelperC.h"
#include "LightC.h"
#include "CameraC.h"

//////////////////////////////////////////////////////////////////////////
//
//  Class IDs
//

#define	CLASS_DX9MESH_EFFECT_NAME	"Mesh (DX9)"
#define	CLASS_DX9MESH_EFFECT_DESC	"Mesh (DX9)"
const PluginClass::ClassIdC	CLASS_DX9MESH_EFFECT( 0x55578FF8, 0x565B468A );

#define	CLASS_DX9X_IMPORT_NAME	"X Import (DX9)"
#define	CLASS_DX9X_IMPORT_DESC	"X File importer (DX9)"
const	PluginClass::ClassIdC	CLASS_DX9X_IMPORT( 0xE3986A1A, 0x8FAC4B86 );

#define	CLASS_DX9ASE_IMPORT_NAME	"ASE Import (DX9)"
#define	CLASS_DX9ASE_IMPORT_DESC	"ASE File importer (DX9)"
const	PluginClass::ClassIdC	CLASS_DX9ASE_IMPORT( 0xF3D47876, 0xDAB049A5 );


//////////////////////////////////////////////////////////////////////////
//
//  DX9Mesh effect class descriptor.
//

class DX9MeshDescC : public PluginClass::ClassDescC
{
public:
	DX9MeshDescC();
	virtual ~DX9MeshDescC();
	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;
};

//////////////////////////////////////////////////////////////////////////
//
//  DX9 .X importer class descriptor.
//

class DX9XImportDescC : public PluginClass::ClassDescC
{
public:
	DX9XImportDescC();
	virtual ~DX9XImportDescC();
	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;
};

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

class DX9ASEImportDescC : public PluginClass::ClassDescC
{
public:
	DX9ASEImportDescC();
	virtual ~DX9ASEImportDescC();
	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 DX9MeshPlugin {

//////////////////////////////////////////////////////////////////////////
//
// DX9Mesh effect class.
//

	enum AttributeGizmoParamsE {
		ID_ATTRIBUTE_FILE_MESH = 0,
		ID_ATTRIBUTE_FILE_ENVMAP,
		ATTRIBUTE_COUNT,
	};

	enum AVIPlayerEffectGizmosE {
		ID_GIZMO_ATTRIB,
		GIZMO_COUNT,
	};

	class DX9MeshEffectC : public Composition::EffectI
	{
	public:
		static DX9MeshEffectC*				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( PajaTypes::int32 i32Time, Import::FileHandleC* pHandle );
		virtual Composition::ParamI*	get_default_param( PajaTypes::int32 i32Param );

		virtual PajaTypes::uint32			update_notify( EditableI* pCaller );

		virtual void									initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DemoInterfaceC* pInterface );

		virtual void									eval_state( PajaTypes::int32 i32Time );

		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:
		DX9MeshEffectC();
		DX9MeshEffectC( Edit::EditableI* pOriginal );
		virtual ~DX9MeshEffectC();

		void		init_effect();

	private:
		Composition::AutoGizmoC*	m_pAttGizmo;

		float		m_fSpeed;

		CD3DModelInstance*				m_pInstance;
		LPD3DXEFFECT							m_pEffect;

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

};	// namespace


//////////////////////////////////////////////////////////////////////////
//
// X Importer class.
//

	class DX9XImportC : public Import::ImportableI
	{
	public:
		static DX9XImportC*				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 void					set_filename( const char* szName );
		virtual bool					load_file( const char* szName, PajaSystem::DemoInterfaceC* pInterface );
		virtual void					initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DemoInterfaceC* pInterface );

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

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

		virtual PajaTypes::int32		get_duration();
		virtual PajaTypes::float32		get_start_label();
		virtual PajaTypes::float32		get_end_label();

		virtual void					eval_state( PajaTypes::int32 i32Time );

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

		virtual CD3DModel*			get_model();

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

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

	private:
		CD3DModel*					m_pModel;
		std::string					m_sFileName;
		bool								m_bFileRefsValid;
		std::vector<Import::FileHandleC*>	m_rFileRefs;
		PajaTypes::uint8*		m_pData;
		PajaTypes::uint32		m_ui32DataSize;
		struct SavedTexHandleS
		{
			std::string						strName;
			std::string						strBumpName;
			Import::FileHandleC*	pHandle;
			Import::FileHandleC*	pBumpHandle;
		};
		bool		m_bHasTextures;
		std::vector<SavedTexHandleS>	m_vecTexHandles;
	};

//////////////////////////////////////////////////////////////////////////
//
// X Importer class.
//

	class DX9ASEImportC : public Import::ImportableI
	{
	public:
		static DX9ASEImportC*				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 void					set_filename( const char* szName );
		virtual bool					load_file( const char* szName, PajaSystem::DemoInterfaceC* pInterface );
		virtual void					initialize( PajaTypes::uint32 ui32Reason, PajaSystem::DemoInterfaceC* pInterface );

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

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

		virtual PajaTypes::int32		get_duration();
		virtual PajaTypes::float32		get_start_label();
		virtual PajaTypes::float32		get_end_label();

		virtual void					eval_state( PajaTypes::int32 i32Time );


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

		virtual PajaTypes::uint32			get_helper_count();
		virtual HelperC*							get_helper( 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::int32			get_current_frame() const;

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

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


	private:
		void							count_file_references( HelperC* pHelper );
		PajaTypes::uint32	save_helper( FileIO::SaveC* pSave, HelperC* pItem, PajaTypes::uint32 ui32ParentId, PajaTypes::uint32& ui32Id );
		HelperC*					find_parent( HelperC* pItem, PajaTypes::uint32 ui32ParentId );


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

		std::vector<HelperC*>				m_rHelpers;
		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;
		PajaTypes::int32						m_i32CurrentFrame;
	};


extern DX9MeshDescC				g_rDX9MeshDesc;
extern DX9XImportDescC		g_rDX9XImport;
extern DX9ASEImportDescC	g_rDX9ASEImport;


#endif	// __DX9Mesh_H__
