#pragma once

#include <vector>
#include "Mix/Tool/Win32/Core/Dynamics/Design/Basic.h"

namespace Mix{ namespace Tool{ namespace Win32{ namespace Dynamics{
	class World;
	class Joint;
}}}}

namespace Mix{ namespace Tool{ namespace Win32{ namespace Dynamics{ namespace Design{

	class Actor;

	class Part : public Mix::Tool::Win32::Dynamics::Design::Basic
	{
	private:
		typedef std::vector<Part*> ChildList;

	private:
		Part* m_pParent;
		Part::ChildList m_ChildList;

		D3DXMATRIX m_InitalLocalMat;

		Mix::Tool::Win32::Dynamics::Joint* m_pJoint;
		D3DXVECTOR3 m_JointLocalPivotAPos;
		D3DXMATRIX m_JointLocalPivotBMat;

	private:
		Part(	Actor* pSubject,
				Part* pParent,
				Basic::COORDINATE_SYSTEM coordinateSystem,
				const D3DXVECTOR3& localPos,
				const D3DXMATRIX& worldMat,
				const D3DXQUATERNION& centerRot,
				const D3DXVECTOR3& centerPos );

		virtual ~Part( void );

	protected:
		virtual void OnWorldChanged( const Basic::WORLD_CHANGED_EVENT_ARGS& args );
		virtual void OnModeChanged( const Basic::MODE_CHANGED_EVENT_ARGS& args );
		virtual void OnColliderChanged( void );
		virtual void OnRefresh( void );
		virtual bool OnRefreshWorldTransform( D3DXMATRIX& worldMat );

	public:
		Part* GetParentPtr( void );

		Part* AddChild( const D3DXVECTOR3& localPos,
						const D3DXMATRIX& worldMat,
						const D3DXQUATERNION& centerRot,
						const D3DXVECTOR3& centerPos );

		Part* AddChild( const D3DXVECTOR3& localPos,
						const D3DXQUATERNION& worldRot,
						const D3DXVECTOR3& worldPos,
						const D3DXQUATERNION& centerRot,
						const D3DXVECTOR3& centerPos );

		int GetChildCount( void ) const;
		Part* GetChildPtr( int index );

		Mix::Tool::Win32::Dynamics::Joint* Joint_Get( void ) const;
		bool Joint_Set( Mix::Tool::Win32::Dynamics::Joint* pJoint );

		const D3DXVECTOR3& Joint_GetLocalPivotA( void ) const;
		void Joint_SetLocalPivotA( const D3DXVECTOR3& pivot );

		const D3DXMATRIX& Joint_GetLocalPivotB( void ) const;

		void Draw(	Mix::Tool::Win32::Graphics::LineHelper* pLineHelper,
					bool bSensor,
					bool bBody,
					bool bJoint,
					const D3DXVECTOR4& selectedColor,
					const D3DXVECTOR4& sensorColor,
					const D3DXVECTOR4& bodyColor,
					const D3DXVECTOR4& jointAxisColor,
					const D3DXVECTOR4& jointBallColor,
					const D3DXVECTOR4& jointLimitColor,
					float jointScale = 1.0f,
					float axisScale = 1.0f,
					bool bProcChild = true );

	private:
		void Joint_UpdateFrame( void );

		D3DXMATRIX Joint_ComputeLocalPivotMatrix( Mix::Tool::Win32::Dynamics::Design::Basic* pBase );
		D3DXVECTOR3 Joint_ComputePivot( Mix::Tool::Win32::Dynamics::Design::Basic* pBase );

	public:
		MIX_OBJECT_TYPE( Mix::Tool::Win32::Object::DYNAMICS__PART_DESIGNER, Mix::Tool::Win32::Dynamics::Design::Basic )

		friend class Actor;
	};

}}}}}
