////////////////////////////////////////////////////////
// filename: ChaDataObject.h
// author: Chafumi Touji
// version: 1.0.0
// date: 2020/03/05
////////////////////////////////////////////////////////

#ifndef __CHADATAOBJECT_H__
#define __CHADATAOBJECT_H__

struct CMaterial{

	float4 diffuse;
	float4 ambient;
	float4 emmition;
	float4 specular;
	wchar_t MaterialName[SIZE_CHAR_MAX];
	wchar_t TextureName[SIZE_CHAR_MAX];
};

struct CVertex{

	float3 Pos;
	float3 Normal;
	float4 Color;
	float2 UV;
	float2 Weight[WEIGHT_BONE_APPLY_NUM];
};

struct CTextureName{

	wchar_t TextureID[SIZE_CHAR_MAX];
	wchar_t TextureName[SIZE_CHAR_MAX];
};

class CFloatArray{
public:

	wchar_t ID[SIZE_CHAR_MAX];
	CVector	*FloatData;

public:

	CFloatArray();
	~CFloatArray();
};

class CPolygonData{
public:

	wchar_t MaterialID[SIZE_CHAR_MAX];
	wchar_t VertexID[SIZE_CHAR_MAX];
	wchar_t NormalID[SIZE_CHAR_MAX];
	wchar_t ColorID[SIZE_CHAR_MAX];
	CVector	*VertexIndex;
	CVector *NormalIndex;
	CVector *TexIndex;
	CVector *ColorIndex;
	CVector *TexID;

public:

	CPolygonData();
	~CPolygonData();
};

class CBone{
public:

	wchar_t ID[SIZE_CHAR_MAX];
	wchar_t Name[SIZE_CHAR_MAX];

	matrix JointParam;
	matrix InvBindMatrix;

	CVector *ChildBone;
	CBone *ParentBone;
	int Type;

public:

	CBone();
	~CBone();
};

class CAnimation{
public:

	wchar_t AnimatonID[SIZE_CHAR_MAX];
	CVector *BoneAnimation;

public:

	CAnimation();
	~CAnimation();
};

class CBoneAnimation{
public:

	wchar_t Target[SIZE_CHAR_MAX];
	CBone *TargetBone;

	CVector *KeyTime;
	CVector *PoseMatrix;

public:

	CBoneAnimation();
	~CBoneAnimation();
};

class CGeometry{
public:

	wchar_t	GeometryID[SIZE_CHAR_MAX];
	matrix	BindShapeMatrix;
	int		VertexCount;
	CVector	*VecFloatArray;
	CVector	*PolygonData;
	int64_t		***Weights;
	int		WeightCount;

public:

	CGeometry();
	~CGeometry();
	CFloatArray *GetFloatArray(wchar_t *id);
};

class CChaDataObject{
public:

	wchar_t	ModelID[SIZE_CHAR_MAX];
	wchar_t ColliderFilePath[SIZE_CHAR_MAX];

	CVector *Geometry;
	CVector	*Material;
	CVector	*TextureName;
	CVector *ControlBone;
	CVector *BoneArray;
	CVector *AnimationList;

public:

	CChaDataObject();
	~CChaDataObject();
	CMaterial *GetMaterial(wchar_t *id);
	int GetMaterialNum(wchar_t *id);
	CTextureName *GetTextureName(wchar_t *id);
	int GetTextureNum(int material_num);
	bool LoadDAE(const wchar_t *filename, const wchar_t *ext_dae);
	bool WriteModel(const wchar_t *modelname, const wchar_t *filename);
	bool LoadModel(wchar_t *filename);
	bool WriteAnimation(wchar_t *target_modelname, wchar_t *animation_id, wchar_t *filename);
	bool LoadAnimation(wchar_t *filename);
	bool WriteCollider(const wchar_t* modelname, const wchar_t* filename);

private:
	bool LoadMaterial(MSXML2::IXMLDOMDocumentPtr pDoc);
	bool LoadTextureName(MSXML2::IXMLDOMDocumentPtr pDoc);
	bool LoadMesh(MSXML2::IXMLDOMDocumentPtr pDoc);
	bool LoadTransform(MSXML2::IXMLDOMDocumentPtr pDoc);
	bool LoadTransform(MSXML2::IXMLDOMElementPtr node, CBone *bone_back);
	CBone *FindBone(wchar_t *search_name);
	bool LoadAnimation(MSXML2::IXMLDOMNodePtr pDoc);
	CBone *FindBoneByID(wchar_t *search_name);
	int FindName(CVector *name_list, wchar_t *search_name);
	bool LoadController(MSXML2::IXMLDOMNodePtr pDoc);
	CGeometry *FindGeometry(wchar_t *search_name);
	bool BoneTransform(CBone *bone);
	bool InsertWeight(CGeometry *geometry, int index, int joint_num, float weight);
	bool WriteChildBone(FILE *fp, CBone *child_bone, int tab);
	CBone *LoadBone(FILE *fp, CBone *parent_bone);
};

#endif