/** 
 * \file XFileEntity.h
 * \brief Loads a .x file and maintains the heirarchy
 * 
 * \author Keith Ditchburn
 * \date 17 July 2005
 */
#pragma once

#include "d3dx9.h"
#include "MeshHierarchy.h"

struct D3DXFRAME_EXTENDED;
struct D3DXMESHCONTAINER_EXTENDED;

/**
 * \class CXFileEntity
 * \brief Loads a .x file and maintains the heirarchy
 * \author Keith Ditchburn \date 17 July 2005
*/
class CXFileEntity
{
public:
	LPD3DXFRAME                 m_frameRoot;
    LPD3DXANIMATIONCONTROLLER   m_animController;
	
	// Them bones
	D3DXMATRIX *m_boneMatrices;
	UINT m_maxBones;

	D3DXMESHCONTAINER_EXTENDED* m_firstMesh;

	// Bounding sphere
	D3DXVECTOR3 m_sphereCentre;
	float m_sphereRadius;

	// Animation variables
	UINT m_currentAnimationSet;	
	UINT m_numAnimationSets;
	DWORD m_currentTrack;
	float m_currentTime;
	float m_speedAdjust;

	void UpdateFrameMatrices(const D3DXFRAME *frameBase, const D3DXMATRIX *parentMatrix);
	void DrawFrame(LPDIRECT3DDEVICE9 device,LPD3DXFRAME frame) const;
	void DrawMeshContainer(LPDIRECT3DDEVICE9 device,LPD3DXMESHCONTAINER meshContainerBase, LPD3DXFRAME frameBase) const;

	CXFileEntity(void);
	~CXFileEntity(void);

	HRESULT LoadXFile(LPDIRECT3DDEVICE9 device,const WCHAR* filename);
	void SetupBoneMatrices(LPDIRECT3DDEVICE9 device,D3DXFRAME_EXTENDED *pFrame, LPD3DXMATRIX pParentMatrix);
	void OnFrameMove(LPDIRECT3DDEVICE9 device, float elapsedTime,const D3DXMATRIX *matWorld);
	void Render(LPDIRECT3DDEVICE9 device) const;
	void SetAnimationSet(UINT index);
	void GetBoundingSphere(D3DXVECTOR3* centre,float *radius) const {*centre=m_sphereCentre;*radius=m_sphereRadius;}

	void NextAnimation();

	inline UINT GetIndexOfCurrentAnimationSet() const {return m_currentAnimationSet;}
	inline UINT GetNumAnimationSets() const {return m_numAnimationSets;}
	inline UINT GetMaxBones() const {return m_maxBones;}

	void AnimateFaster();
	void AnimateSlower();

	const char *GetAnimationSetName(UINT index);

	bool m_copy; //this sheep is copy of another, do not free its resources easily
};
