//
// Asura_Animation_IK_Template_Chain.h
//
// Created by Richard Rice - 12/05/2008
// 
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef __ASURA_ANIMATION_IK_TEMPLATE_CHAIN_H__
#define __ASURA_ANIMATION_IK_TEMPLATE_CHAIN_H__
#ifdef ASURA_USE_ANIMATION_IK_SOLVER


class Asura_Animation_IK_Chain;
class Asura_Animation;
class Asura_Chunk_Stream;

enum Asura_IKChain_Type
{
	ASURA_IKCHAIN_LOS = 0,
	ASURA_IKCHAIN_MARKERPOINT = 1,

	ASURA_IKCHAIN_NUMTYPES
};

#ifdef ASURA_TOOLS
//Flag defines for use by the tickbox controls
#define ASURA_IKTEMPLATEFLAG_ROOTBONEMOVER 0x00000001
#define ASURA_IKTEMPLATEFLAG_USEPOSSMOOTHING 0x00000002
#define ASURA_IKTEMPLATEFLAG_USEORISMOOTHING 0x00000004
#endif //ASURA_TOOLS

class Asura_Animation_IK_Template_Chain
{
	friend class Tools_Animation_IK_Template_System;
public :
	Asura_Animation_IK_Template_Chain();
	virtual ~Asura_Animation_IK_Template_Chain();

	//Creates an instance of the IK chain from this template
	virtual Asura_Animation_IK_Chain* CreateChainFromTemplate(const Asura_Animation* pxAnim) const = 0;

	const int* GetBoneArray() const {return m_piBoneArray;}
	const int* GetTwistBoneArray() const {return m_piTwistBoneArray;}

	virtual Asura_IKChain_Type GetType() const = 0;

	u_int GetNumBones() const {return m_uBoneArraySize - 1;}
	#ifdef ASURA_TOOLS
	const char* GetName() const {return m_xName.GetString();}

	const char* GetFirstBoneName() const {return m_pxBoneNames[0].GetString();}
	const char* GetLastBoneName() const {return m_pxBoneNames[GetNumBones()-1].GetString();}

	void SetTwistBone(u_int uIndex, int iBone, const char* szBoneName);
	#endif

	virtual bool ReadFromChunkStream(Asura_Chunk_Stream& xStream);
	#ifdef ASURA_TOOLS
	virtual void WriteToChunkStream(Asura_Chunk_Stream& xStream) const;
	#endif

protected :
	//Fills in anything that wasn't dealt with by the constructor
	virtual void SetupChain(Asura_Animation_IK_Chain* pxChain) const;

private :
	///array of bone ids in the chain (with -1 terminator)
	u_int m_uBoneArraySize;
	int* m_piBoneArray;
	//and optional array of twist bones
	int* m_piTwistBoneArray;

	union
	{
		u_int m_uFlags;
		struct
		{
			u_int m_bRootBoneMover:1;
			u_int m_bUsePosSmoothing:1;
			u_int m_bUseOriSmoothing:1;
			u_int m_bHasTwistBones:1;
		};
	};

	float m_fPosSmoothingSpeed;
	float m_fOriSmoothingSpeed;


	#ifdef ASURA_TOOLS
	//name for the chain
	Asura_String m_xName;

	//names of all the bones in the chain
	Asura_String* m_pxBoneNames;

	//names of twist bones (blank/null for empty slots)
	Asura_String* m_pxTwistBoneNames;
	#endif
};




#endif //ASURA_USE_ANIMATION_IK_SOLVER
#endif //__ASURA_ANIMATION_IK_TEMPLATE_CHAIN_H__
