/** 
 * \file MeshHierarchy.h
 * \brief Creates mesh heirarchy.
 * 
 * \author Keith Ditchburn
 * \date 17 July 2005
 */

#pragma once

#include "d3dx9.h"

#ifndef SAFE_DELETE
#define SAFE_DELETE(p)       { if(p) { delete (p);     (p)=NULL; } }
#endif    
#ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p);   (p)=NULL; } }
#endif    
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p)      { if(p) { (p)->Release(); (p)=NULL; } }
#endif
#ifndef V
#define V(x)           { hr = x; }
#endif
#ifndef V_RETURN
#define V_RETURN(x)    { hr = x; if( FAILED(hr) ) { return hr; } }
#endif

/**
 * \struct D3DXMESHCONTAINER_EXTENDED
 * \brief Structure derived from D3DXMESHCONTAINER and extended with some app-specific 
 * info that will be stored with each mesh. To help detect which data is extended and which is
 * from the base each variable begins with ex
 * \author Keith Ditchburn \date 17 July 2005
*/
struct D3DXMESHCONTAINER_EXTENDED: public D3DXMESHCONTAINER
{
	// The base D3DXMESHCONTAINER has a pMaterials member which is a D3DXMATERIAL structure 
	// that contains a texture filename and material data. It is easier to ignore this and 
	// instead store the data in arrays of textures and materials in this extended structure:
    IDirect3DTexture9**  exTextures;		// Array of texture pointers  
	D3DMATERIAL9*		 exMaterials;		// Array of materials
                                
	// Skinned mesh variables
	ID3DXMesh*           exSkinMesh;			// The skin mesh
	D3DXMATRIX*			 exBoneOffsets;			// The bone matrix Offsets, one per bone
	D3DXMATRIX**		 exFrameCombinedMatrixPointer;	// Array of frame matrix pointers
};

/**
 * \struct D3DXFRAME_EXTENDED
 * \brief Structure derived from D3DXFRAME and extended so we can add some app-specific
 * info that will be stored with each frame. To help detect which data is extended and which is
 * from the base each variable begins with ex
 * \author Keith Ditchburn \date 17 July 2005
*/
struct D3DXFRAME_EXTENDED: public D3DXFRAME
{
    D3DXMATRIX exCombinedTransformationMatrix;
};


/**
 * \class CMeshHierarchy
 * \brief This class defines a number of callbacks required by the D3DXLoadMeshHierarchyFromX function.
 *
 * The required functions are defined by the abstract interface class: ID3DXAllocateHierarchy
 * \author Keith Ditchburn \date 17 July 2005
*/
class CMeshHierarchy : public ID3DXAllocateHierarchy
{
public:	
    // callback to create a D3DXFRAME extended object and initialize it
    STDMETHOD( CreateFrame )( THIS_ LPCSTR Name, LPD3DXFRAME *ppNewFrame );

    // callback to create a D3DXMESHCONTAINER extended object and initialize it
    STDMETHOD( CreateMeshContainer )( THIS_ LPCSTR Name, CONST D3DXMESHDATA * pMeshData, 
                            CONST D3DXMATERIAL * pMaterials, CONST D3DXEFFECTINSTANCE * pEffectInstances,
                            DWORD NumMaterials, CONST DWORD * pAdjacency, LPD3DXSKININFO pSkinInfo, 
                            LPD3DXMESHCONTAINER * ppNewMeshContainer );

    // callback to release a D3DXFRAME extended object
    STDMETHOD( DestroyFrame )( THIS_ LPD3DXFRAME pFrameToFree );

    // callback to release a D3DXMESHCONTAINER extended object
    STDMETHOD( DestroyMeshContainer )( THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree );
};


/**
 * \class CUtilities
 * \brief a set of static utility helper functions
 * this class is never instantiated
 * \author Keith Ditchburn \date 17 July 2005
*/
class CUtilities
{
private:
	CUtilities(void){};
	virtual ~CUtilities(void)=0;
public:
	static char* DuplicateCharString(const char* c_str);
	static WCHAR* CreateWideStringFromCharString(const char *c_str);
	static bool FillWideStringFromCharString(const char *c_str,WCHAR *wideString,size_t wideStringLen);
};
