#ifndef _RUCONTROLLER_BONE_H_
#define _RUCONTROLLER_BONE_H_

#include "../../Scene/Base/RuEntityController.h"

#pragma unmanaged

// ************************************************************************************************************************************************************

class CRuController_Bone : public IRuEntity_Controller
{
	ruRTTI_DECLARE
	ruHEAP_DECLARE
	ruCLASSGUID_DECLARE

protected:
	struct TransformDesc
	{
		INT32								m_subNodeID;									//!< ID of the sub node to control
		INT32								m_subNodeIndex;									//!< Index of the sub node to control

		REAL								m_scaleWeight;
		REAL								m_rotationWeight;

		REAL								m_scale_BlendWeight;
		CRuVector3							m_scale_Current;								//!< Current scale
		CRuVector3							m_scale_0;										//!< Origin scale
		CRuVector3							m_scale_1;										//!< Target scale

		REAL								m_rotation_BlendWeight;
		CRuQuaternion						m_rotation_Current;								//!< Current rotation
		CRuQuaternion						m_rotation_0;									//!< Origin rotation
		CRuQuaternion						m_rotation_1;									//!< Target rotation
	};

	// Controller settings
	CRuMatrix4x4							m_basisTransform;								//!< Basis transform to be applied onto all transformations
	REAL									m_blendGradient;								//!< 

	// Target entity
	CRuFrameHierarchy*						m_targetEntity;									//!< Entity that the controller affects

	// Rotation data
	CRuArrayList<TransformDesc>				m_transformDescriptors;

public:
											CRuController_Bone();
	virtual									~CRuController_Bone();

	virtual BOOL							Update(REAL elapsedTime);

	virtual IRuObject*						GetTarget();
	virtual BOOL							SetTarget(IRuObject *targetEntity);

	virtual BOOL							SetBasis(CRuVector3 xBasis, CRuVector3 yBasis, CRuVector3 zBasis);
	virtual BOOL							SetTransformTarget(INT32 subNodeID, const CRuVector3 &scale, const CRuVector3 &originVector, const CRuVector3 &targetVector, REAL weight);

	// IRuEntityEventListener implementation
	virtual BOOL							HandleEvent(CRuEntity *entity, INT32 eventID, INT32 eventParameter0, INT32 eventParameter1, const char *eventString, REAL eventDuration, void *userData);

protected:
	void									BlendDeltaKey(INT32 boneID, const CRuVector3 &scale, const CRuVector3 &rotAxis, REAL rotAngle, const CRuVector3 &position);
};

// ************************************************************************************************************************************************************

#pragma managed

#endif
