#pragma once

#include "Mix/Dynamics/IStaticMesh.h"
#include "Mix/Private/Dynamics/Object.h"

namespace Mix{ namespace Dynamics{

	class ObjectContext;
	class StaticMeshContext;

	class StaticMesh : public Mix::Dynamics::IStaticMesh, public Mix::Dynamics::Object
	{
	public:
		static StaticMesh* CreateInstance( void );

	private:
		btBulletWorldImporter* m_pImporter;
		btTriangleIndexVertexArray* m_pShapeData;
		btBvhTriangleMeshShape* m_pShape;
		btDefaultMotionState* m_pMotionState;
		btRigidBody* m_pRigidBody;

		Mix::Dynamics::StaticMeshContext* m_pContext;

		Int32 m_UserIndex;
		void* m_pUserPtr;

	private:
		StaticMesh( void );
		virtual ~StaticMesh( void );

		Boolean FinishInitialize( UInt32 materialNum, const wchar_t* pDebugName );

	public:
		Boolean Initialize( const Mix::Dynamics::MESH* pMeshes, UInt32 meshNum, UInt32 materialNum, const wchar_t* pDebugName );
		Boolean Initialize( void* pSrc, Int32 size, UInt32 materialNum, const wchar_t* pDebugName );

	public:
		virtual Mix::Dynamics::ObjectContext* GetContextPtr( void ) const;

		virtual btCollisionObject* Bullet_GetCollisionObjectPtr( void ) const;
		virtual btRigidBody* Bullet_GetRigidBodyPtr( void ) const;

	public:
		virtual UInt32 GetPartCount( void ) const;

		virtual UInt32 GetPolygonCount( UInt32 partIndex ) const;
		virtual UInt32 GetTotalPolygonCount( void ) const;

		virtual UInt32 GetMaterialCount( void ) const;

		virtual UInt32 GetMaterialIndex( UInt32 partIndex, UInt32 polygonIndex ) const;
		virtual Boolean SetMaterialIndex( UInt32 partIndex, UInt32 polygonIndex, UInt32 materialIndex );
		virtual UInt32 LockMaterialIndices( UInt32 partIndex, UInt32 polygonStartIndex, UInt32 polygonCount, UInt32** ppMaterialIndices ) const;

		virtual const Mix::Dynamics::MATERIAL& GetMaterial( UInt32 index ) const;
		virtual Boolean GetMaterial( UInt32 index, Mix::Dynamics::MATERIAL& material ) const;
		virtual const Mix::Dynamics::MATERIAL& GetMaterial( UInt32 partIndex, UInt32 polygonIndex ) const;
		virtual Boolean GetMaterial( UInt32 partIndex, UInt32 polygonIndex, Mix::Dynamics::MATERIAL& material ) const;
		virtual Boolean SetMaterial( UInt32 index, const Mix::Dynamics::MATERIAL& material );
		virtual UInt32 LockMaterials( UInt32 startIndex, UInt32 count, Mix::Dynamics::MATERIAL** ppMaterials ) const;

	public:
		virtual Mix::Dynamics::IObject::TYPE GetType( void ) const;

		virtual Boolean GetShape( Mix::Dynamics::IShape** ppShape );

		virtual Float32 GetShapeMargin( void ) const;
		virtual void SetShapeMargin( Float32 margin );

		virtual UInt16 GetFilterGroup( void ) const;
		virtual void SetFilterGroup( UInt16 filterGroup );

		virtual UInt16 GetFilterMask( void ) const;
		virtual void SetFilterMask( UInt16 filterMask );

		virtual const Mix::Dynamics::MATERIAL& GetMaterial( void ) const;
		virtual void SetMaterial( const Mix::Dynamics::MATERIAL& material );

		virtual Mix::Quaternion GetWorldRotation( void ) const;
		virtual Mix::Vector3 GetWorldPosition( void ) const;
		virtual Mix::Matrix4x4 GetWorldMatrix( void ) const;

		virtual void SetWorldRotation( const Mix::Quaternion& rotation );
		virtual void SetWorldPosition( const Mix::Vector3& pos );
		virtual void SetWorldTransform( const Mix::Quaternion& rot, const Mix::Vector3& pos );

		virtual Boolean IsInWorld( void ) const;

		virtual Mix::Geometry::AABB GetBounds( void ) const;

		virtual Boolean AddListener( Mix::Dynamics::IObjectListener* pListener );
		virtual void RemoveListener( Mix::Dynamics::IObjectListener* pListener );

		virtual Int32 GetUserIndex( void ) const;
		virtual void SetUserIndex( Int32 index );

		virtual void* GetUserPtr( void ) const;
		virtual void SetUserPtr( void* pData );

		virtual UInt32 Debug_GetDrawFlags( void ) const;
		virtual void Debug_SetDrawFlags( UInt32 flags );

		virtual Float32 Debug_GetDrawAxisScaling( void ) const;
		virtual void Debug_SetDrawAxisScaling( Float32 scaling );

		virtual void Debug_Draw( Mix::Graphics::Utility::IPerspectiveRenderer* pPerspectiveRenderer, Float32 opacity );

	public:
		static const wchar_t* FAILED_CREATE;
	};

}}
