#pragma once

#include "Mix/Dynamics/IManager.h"

namespace Mix{ namespace Dynamics{

	class Manager : public Mix::Dynamics::IManager
	{
	private:
		static const wchar_t* FAILED_CREATESPHERESHAPE;
		static const wchar_t* FAILED_CREATEBOXSHAPE;
		static const wchar_t* FAILED_CREATECONESHAPE;
		static const wchar_t* FAILED_CREATECAPSULESHAPE;
		static const wchar_t* FAILED_CREATECYLINDERSHAPE;
		static const wchar_t* FAILED_CREATECONVEXHULLSHAPE;
		static const wchar_t* FAILED_CREATECOMPOUNDSHAPE;
		static const wchar_t* FAILED_CREATEWORLD;
		static const wchar_t* FAILED_CREATE_OBJECT_PICKER;

		static const wchar_t* AXISNAME_TABLE[3];

	public:
		static Manager* CreateInstance( Boolean bParallel );

	private:
		Boolean m_bParallel;

	private:
		Manager( Boolean bParallel );
		virtual ~Manager( void );

	public:
		virtual Boolean CreateSphereShape( Float32 radius, Mix::Dynamics::ISphereShape** ppSphereShape, const wchar_t* pDebugName );
		virtual Boolean CreateBoxShape( Float32 x, Float32 y, Float32 z, Mix::Dynamics::IBoxShape** ppBoxShape, const wchar_t* pDebugName );
		virtual Boolean CreateBoxShape( const Mix::Vector3& size, Mix::Dynamics::IBoxShape** ppBoxShape, const wchar_t* pDebugName );
		virtual Boolean CreateConeShape( Mix::Dynamics::AXIS_TYPE axis, Float32 axisLength, Float32 radius, Mix::Dynamics::IConeShape** ppConeShape, const wchar_t* pDebugName );
		virtual Boolean CreateCapsuleShape( Mix::Dynamics::AXIS_TYPE axis, Float32 height, Float32 radius, Mix::Dynamics::ICapsuleShape** ppCapsuleShape, const wchar_t* pDebugName );
		virtual Boolean CreateCylinderShape( Mix::Dynamics::AXIS_TYPE axis, Float32 height, Float32 radius, Mix::Dynamics::ICylinderShape** ppCylinderShape, const wchar_t* pDebugName );
		virtual Boolean CreateConvexHullShape( const Mix::Dynamics::MESH& mesh, Mix::Dynamics::IConvexHullShape** ppConvexHullShape, const wchar_t* pDebugName );
		virtual Boolean CreateCompoundShape( Mix::Dynamics::ICompoundShape** ppCompoundShape, const wchar_t* pDebugName );

		virtual Boolean CreatePointJoint(	Mix::Dynamics::IRigidBody* pRigidBodyA,
											const Mix::Vector3& pivotA,
											Mix::Dynamics::IPointJoint** ppPointJoint,
											const wchar_t* pDebugName );

		virtual Boolean CreatePointJoint(	Mix::Dynamics::IRigidBody* pRigidBodyA,
											Mix::Dynamics::IRigidBody* pRigidBodyB,
											const Mix::Vector3& pivotA,
											const Mix::Vector3& pivotB,
											Mix::Dynamics::IPointJoint** ppPointJoint,
											const wchar_t* pDebugName );

		virtual Boolean CreateHingeJoint(	Mix::Dynamics::IRigidBody* pRigidBodyA,
											const Mix::Vector3& pivotA,
											const Mix::Vector3& axis,
											Mix::Dynamics::IHingeJoint** ppHingeJoint,
											const wchar_t* pDebugName );

		virtual Boolean CreateHingeJoint(	Mix::Dynamics::IRigidBody* pRigidBodyA,
											Mix::Dynamics::IRigidBody* pRigidBodyB,
											const Mix::Vector3& pivotA,
											const Mix::Vector3& pivotB,
											const Mix::Vector3& axis,
											Mix::Dynamics::IHingeJoint** ppHingeJoint,
											const wchar_t* pDebugName );

		virtual Boolean CreateSliderJoint(	Mix::Dynamics::IRigidBody* pRigidBodyA,
											const Mix::Quaternion& rotA,
											const Mix::Vector3& pivotA,
											Mix::Dynamics::ISliderJoint** ppSliderJoint,
											const wchar_t* pDebugName );

		virtual Boolean CreateSliderJoint(	Mix::Dynamics::IRigidBody* pRigidBodyA,
											Mix::Dynamics::IRigidBody* pRigidBodyB,
											const Mix::Quaternion& rotA,
											const Mix::Quaternion& rotB,
											const Mix::Vector3& pivotA,
											const Mix::Vector3& pivotB,
											Mix::Dynamics::ISliderJoint** ppSliderJoint,
											const wchar_t* pDebugName );

		virtual Boolean CreateDofJoint(	Mix::Dynamics::IRigidBody* pRigidBodyA,
										const Mix::Quaternion& rotA,
										const Mix::Vector3& pivotA,
										Mix::Dynamics::IDofJoint** ppDofJoint,
										const wchar_t* pDebugName );

		virtual Boolean CreateDofJoint(	Mix::Dynamics::IRigidBody* pRigidBodyA,
										Mix::Dynamics::IRigidBody* pRigidBodyB,
										const Mix::Quaternion& rotA,
										const Mix::Quaternion& rotB,
										const Mix::Vector3& pivotA,
										const Mix::Vector3& pivotB,
										Mix::Dynamics::IDofJoint** ppDofJoint,
										const wchar_t* pDebugName );

		virtual Boolean CreateBallJoint(	Mix::Dynamics::IRigidBody* pRigidBodyA,
											const Mix::Vector3& pivotA,
											const Mix::Vector3& twistAxis,
											const Mix::Vector3& swingAxis,
											Mix::Dynamics::IBallJoint** ppBallJoint,
											const wchar_t* pDebugName );

		virtual Boolean CreateBallJoint(	Mix::Dynamics::IRigidBody* pRigidBodyA,
											Mix::Dynamics::IRigidBody* pRigidBodyB,
											const Mix::Vector3& pivotA,
											const Mix::Vector3& pivotB,
											const Mix::Vector3& twistAxis,
											const Mix::Vector3& swingAxis,
											Mix::Dynamics::IBallJoint** ppBallJoint,
											const wchar_t* pDebugName );

		virtual Boolean CreateWorld( const Mix::Dynamics::WORLD_CONFIG& config, Mix::Dynamics::IWorld** ppWorld, const wchar_t* pDebugName );

		virtual Boolean CreateStaticPlane( const Mix::Vector3& normal, Float32 constant, Mix::Dynamics::IStaticPlane** ppStaticPlane, const wchar_t* pDebugName );

		virtual Boolean CreateStaticMesh( const Mix::Dynamics::MESH* meshes, UInt32 meshNum, UInt32 materialNum, Mix::Dynamics::IStaticMesh** ppStaticMesh, const wchar_t* pDebugName );
		virtual Boolean CreateStaticMesh( Mix::Memory::IBuffer* pBuffer, UInt32 materialNum, Mix::Dynamics::IStaticMesh** ppStaticMesh, const wchar_t* pDebugName );

		virtual Boolean CreateRigidBody( Float32 mass, Mix::Dynamics::IShape* pShape, Mix::Dynamics::IRigidBody** ppRigidBody, const wchar_t* pDebugName );
		virtual Boolean CreateSensor( Mix::Dynamics::IShape* pShape, Mix::Dynamics::ISensor** ppSensor, const wchar_t* pDebugName );

		virtual Boolean CreateKinematicCharacter( Float32 height, Float32 radius, Float32 stepHeight, Mix::Dynamics::IKinematicCharacter** ppKinematicCharacter, const wchar_t* pDebugName );
		virtual Boolean CreateVehicle( Float32 mass, Mix::Dynamics::IShape* pShape, const Mix::Dynamics::VEHICLE_WHEEL_DESC* wheels, UInt32 wheelNum, Mix::Dynamics::IVehicle** ppVehicle, const wchar_t* pDebugName );

		virtual Boolean CreateObjectDragger( Mix::Dynamics::IWorld* pWorld, Mix::Dynamics::IObjectDragger** ppObjectDragger, const wchar_t* pDebugName );

	public:
		virtual const Mix::Vector4& Debug_GetDrawColor( Mix::Dynamics::DEBUG_DRAW_COLOR_TYPE type ) const;
		virtual void Debug_SetDrawColor( Mix::Dynamics::DEBUG_DRAW_COLOR_TYPE type, const Mix::Vector4& color );
	};

}}
