
// Purpose: This is a wrapper for the DirectX functions
//	that work with models. This class when completed
//	will allow for loading, drawing, texturing, and
//	model animation.
//
// Note: This was written for DirectX version 9
//	Each instance of this class = one model
//
//		In the future could add functionality to 
//		load files in other formats for DirectX
//		and if I feel up too it OpenGL

#ifndef __CD3DMODEL_H__
#define __CD3DMODEL_H__

#include <d3dx9.h>
#include <d3dx9anim.h>
#include <vector>
#include "CAllocateHierarchy.h"
#include "DemoInterfaceC.h"
#include "FileHandleC.h"
#include "DX9DeviceC.h"

class CD3DModel;

struct RenderContextS
{
	LPD3DXEFFECT	pEffect;
	LPD3DXMATRIX	pMatView;
	int						iTime;
	PajaSystem::DX9DeviceC*		pDevice;
};


class CD3DModelInstance
{
public:
	CD3DModelInstance( CD3DModel* pModel );

	virtual HRESULT	Setup( LPD3DXANIMATIONCONTROLLER pAC );
	virtual void		Cleanup();
	virtual void		Draw( RenderContextS* pRC );
	virtual void		Update( double dTime, LPD3DXMATRIX pMatModel );
	virtual void		Release();
	virtual float		GetAnimMaxTime();

protected:
	virtual ~CD3DModelInstance();

	CD3DModel*								m_pModel;
	LPD3DXANIMATIONCONTROLLER	m_pAC;
};


class CD3DModel
{
public:
	//////////////////////////////////////////////////////////////////////////
	// Construction/Destruction
	//////////////////////////////////////////////////////////////////////////
	CD3DModel( LPDIRECT3DDEVICE9 pD3DDevice );
	CD3DModel( const CD3DModel& );
	virtual	~CD3DModel();

	CD3DModel&						operator=( const CD3DModel& );

	virtual const D3DXVECTOR3&GetBoundingSphereCenter() const;
	virtual float					GetBoundingSphereRadius() const;
	virtual DWORD					GetCurrentAnimation() const;
	virtual void					SetCurrentAnimation( DWORD dwAnimationFlag );
	virtual double				GetCurrentAnimationPerioid();
	virtual void					Draw( RenderContextS* pRC );
	virtual HRESULT				LoadXFile( const char* strFileName );
	virtual HRESULT				LoadXFile( BYTE* pData, UINT uiDataSize );
	virtual void					Update( double dTime, LPD3DXMATRIX pMatModel );
	virtual void					UpdateMatrices( LPD3DXMATRIX pMatModel );
	virtual HRESULT				CreateInstance( CD3DModelInstance** ppAnimInstance );
	virtual void					RemoveInstance( CD3DModelInstance* pAnimInstance );
	virtual void					LoadTextures( PajaSystem::DemoInterfaceC* pInterface );
	virtual void					FixTextures();
	virtual int						GetTextureCount();
	virtual Import::FileHandleC*	GetTextureHandle( int i );
	virtual const std::string&		GetTextureName( int i );
	virtual Import::FileHandleC*	GetBumpTextureHandle( int i );
	virtual const std::string&		GetBumpTextureName( int i );
	virtual void					SetTextureCount( int iCount );
	virtual void					SetTextureHandle( int i, Import::FileHandleC* pHandle );
	virtual void					SetTextureName( int i, const std::string& strName );
	virtual void					SetBumpTextureHandle( int i, Import::FileHandleC* pHandle );
	virtual void					SetBumpTextureName( int i, const std::string& strName );
	virtual float					GetAnimMaxTime();

private:
	void	LoadFrameTextures( LPD3DXFRAME pFrame, PajaSystem::DemoInterfaceC* pInterface );
	void	FixFrameTextures( LPD3DXFRAME pFrame );
	void	DrawFrame( LPD3DXFRAME pFrame, RenderContextS* pRC );
	void	DrawMeshContainer( LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase, RenderContextS* pRC );
	void	UpdateFrameMatrices( LPD3DXFRAME pFrame, LPD3DXMATRIX pParentMatrix );
	HRESULT	SetupBoneMatrixPointersOnMesh( LPD3DXMESHCONTAINER pMeshContainer );
	HRESULT	SetupBoneMatrixPointers( LPD3DXFRAME pFrame );

	LPDIRECT3DDEVICE9		m_pd3dDevice;			//The d3d device to use
	LPD3DXFRAME					m_pFrameRoot;			// Frame hierarchy of the model
	LPD3DXMATRIX				m_pBoneMatrices;		// Used when calculating the bone position
	D3DXVECTOR3					m_vCenter;			// Center of bounding sphere of object
	float								m_fRadius;				// Radius of bounding sphere of object
	UINT								m_NumBoneMatricesMax;			// The Max number of bones for the model
	DWORD								m_dwCurrentAnimation;	// The current animation
	DWORD								m_dwAnimationSetCount;	// Number of animation sets
	LPD3DXANIMATIONCONTROLLER	m_pAnimController;// Controller for the animations
	std::vector<CD3DModelInstance*>	m_vecInstances;

	struct TextureHandleS
	{
		std::string						strTexName;
		std::string						strBumpTexName;
		Import::FileHandleC*	pTexHandle;
		Import::FileHandleC*	pBumpTexHandle;
	};
	std::vector<TextureHandleS*>			m_vecTextureHandles;
};

#endif