#pragma once

#include "Mix/Scene/ITerrainCollider.h"
#include "Mix/Private/Scene/Common/DynamicsObject.h"

namespace Mix{ namespace Scene{ namespace Common{

	class TerrainCollider : public Mix::Scene::ITerrainCollider, public Mix::Scene::Common::DynamicsObject
	{
	public:
		static TerrainCollider* CreateInstance( Mix::Scene::IRendererObject* pOwner, Mix::Dynamics::IStaticMesh* pObject );

	private:
		Mix::Scene::IRendererObject* m_pOwner;
		Mix::Dynamics::IStaticMesh* m_pObject;

	private:
		TerrainCollider( Mix::Scene::IRendererObject* pOwner, Mix::Dynamics::IStaticMesh* pObject );
		virtual ~TerrainCollider( void );

	public:
		Mix::Dynamics::IStaticMesh* GetObjectPtr( void ) const;
		void Dispose( void );

	public:
		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::Common::DynamicsObject
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual Mix::Dynamics::IObject* GetInternalObjectPtr( void ) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::ITerrainCollider
		////////////////////////////////////////////////////////////////////////////////////////////////////

		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;

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

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

		virtual Float32 GetMargin( void ) const;
		virtual void SetMargin( Float32 margin );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::ICollider
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual Boolean IsDefault( void ) const;
		virtual Boolean IsStatic( void ) const;
		virtual Boolean IsKinematic( void ) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::IDynamicsObject
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual Mix::Scene::IDynamicsObject::TYPE GetType( void ) const;

		virtual Boolean GetOwner( Mix::Scene::IRendererObject** ppOwner );
		virtual Mix::Scene::IRendererObject* GetOwnerPtr( void ) const;

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

		virtual Boolean HasContactListener( void ) const;
		virtual Boolean ContainsContactListener( Mix::Scene::IContactListener* pListener ) const;
		virtual Boolean AddContactListener( Mix::Scene::IContactListener* pListener );
		virtual Boolean RemoveContactListener( Mix::Scene::IContactListener* pListener );
		virtual void ClearContactListener( void );

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

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

	private:
		static const UInt16 FILTER_GROUP;
		static const UInt16 FILTER_MASK;
	};

}}}
