////////////////////////////////////////////////////////
// filename: ChaResourceObject.h
// author: Chafumi Touji
// version: 1.0.0
// date: 2020/03/08
////////////////////////////////////////////////////////

#ifndef __CHARESOURCEOBJECT_H__
#define __CHARESOURCEOBJECT_H__

struct ConstantBufferMaterial{

	XMFLOAT4		Diffuse;
	XMFLOAT4		Ambient;
	XMFLOAT4		Specular;
	XMFLOAT4		AlphaParam;
};

struct ConstantBufferJoint{

	XMFLOAT4		ToneLightPos;
	XMFLOAT4X4		BindShapeMatrix;
	XMFLOAT4X4		MatTransform;
	XMFLOAT4X4		MatNormalTransform;
	XMFLOAT4X4		BoneMatrix[BONE_JOINT_NUM_MAX];
};

class CMaterialResource{
public:
	float4 diffuse;
	float4 ambient;
	float4 emmition;
	float4 specular;
	ID3D12Resource *Texture;
	UINT ShaderResourceNum;

public:
	CMaterialResource();
	~CMaterialResource();
};

class CGeometryResource{
public:

	ID3D12Resource				*VertexBuffer;
	D3D12_VERTEX_BUFFER_VIEW	*VertexBufferView;
	CVector						*IndexBuffer;
	CVector						*IndexBufferView;
	CVector						*Material;
	CVector						*IndexCount;
	XMMATRIX					BindShapeMatrix;
	int							WeightCount;

	XMFLOAT4	ObjectRect[8];
	XMFLOAT4	CenterPos;
	float				Length;

public:
	CGeometryResource();
	~CGeometryResource();
	bool Inside(float x, float y, float z);
};

class CBoneResource{
public:

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

	XMMATRIX	JointParam;
	XMMATRIX	InvBindMatrix;
	XMMATRIX	JointParamTransformed;
	XMMATRIX	PrevJointParamTransformed;
	XMMATRIX	BoneMatrix;

	CVector			*ChildBone;
	CBoneResource	*ParentBone;
	int				Type;
	bool			ChangeNewAnimation;
	int				ChangeFrameCount;
	int				NowChangeFrameCount;

public:

	CBoneResource();
	~CBoneResource();
};

class CAnimationResource{
public:

	wchar_t AnimationID[SIZE_CHAR_MAX];
	CVector *BoneAnimation;

public:

	CAnimationResource();
	~CAnimationResource();
};

class CBoneAnimationResource{
public:

	wchar_t Target[SIZE_CHAR_MAX];
	CBoneResource *TargetBone;

	CVector *KeyTime;
	CVector *PoseMatrix;

public:

	CBoneAnimationResource();
	~CBoneAnimationResource();
};

class CChaResourceObject{
public:

	wchar_t	ModelID[SIZE_CHAR_MAX];
	int		DataType;

	int		CurrentAnimationNum;

	CResManager	*ResManager;

	bool		IsAnimated;
	bool		Refrain;
	bool		AnimationFinished;
	float		AnimationSpeed;
	float		Alpha;
	float		RefrainSec;

	XMMATRIX	TransformMatrix;
	XMMATRIX	NormalTransformMatrix;

	XMFLOAT4	Scale;
	XMFLOAT4	Rotation;
	XMFLOAT4	Position;
	XMFLOAT4	ToneLightPosition;

	int64_t		FrameCount;
	CVector		*GeometryResource;
	CVector		*TextureOrigin;
	CVector		*ShaderResourceOriginNum;
	CVector		*ControlBone;
	CVector		*BoneArray;
	CVector		*AnimationList;

	ID3D12Resource				*m_pConstantBufferMaterial;
	ConstantBufferMaterial		*constant_buffer_material_begin;
	UINT						constant_buffer_material_num;

	ID3D12Resource				*m_pConstantBufferJoint;
	ConstantBufferJoint			*constant_buffer_joint_begin;
	UINT						constant_buffer_joint_num;

public:
	CChaResourceObject();
	~CChaResourceObject();
	bool CreateResource(ID3D12Device *device, CChaDataObject *object, CResManager *ResManager, bool is_animated);
	int LoadTexture(ID3D12Device *device, ID3D12Resource **pTexture, CResManager *ResManager,int64_t *ResNum, wchar_t* filename);
	bool Draw( ID3D12GraphicsCommandList *CmdList, int cbf_slot_1, int cbf_slot_2, int root_signature_slot );
	bool SetScale(float scale_x, float scale_y, float scale_z, float scale_r );
	bool SetRotation(float angle_x, float angle_y, float angle_z);
	bool SetPosition(float pos_x, float pos_y, float pos_z);
	bool SetToneLightPos(float pos_x, float pos_y, float pos_z);
	bool SetAlpha(float alpha);
	bool UpdateTransform();
	bool SetRefrainSec(float sec);
	bool CopyAnimation(CChaDataObject *object);
	bool CopyAnimation(CChaDataObject *object, int anim_num);
	bool SetCurrentAnimation(int num, int change_frame_count, float anim_speed, bool refrain, bool model_swapped );

private:
	bool BoneInit(CBoneResource *bone);
	bool CopyControlBone(CChaDataObject *object);
	bool CopyChildBone(CBone *parent, CBoneResource *parent_res);
	bool BoneTransform(CBoneResource *bone);
	XMMATRIX GetAnimationMatrix(CBoneAnimationResource *bone_anim, float sec, int *finishied);
	XMMATRIX CalcInterPauseLinear(XMMATRIX matrix1, XMMATRIX matrix2, float t);
	CBoneResource *FindBoneByID(wchar_t *search_name);
};

#endif