#pragma once

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

namespace Mix{ namespace Scene{ namespace Common{

	class ActorSensor : public Mix::Scene::IActorSensor, public Mix::Scene::Common::DynamicsObject
	{
	public:
		static ActorSensor* CreateInstance( const wchar_t* pName, const Mix::Matrix4x4& centerMat, Mix::Dynamics::ISensor* pObject );
		static ActorSensor* CreateInstance( Mix::Scene::IRendererObject* pOwner, const wchar_t* pName, const Mix::Matrix4x4& centerMat, Mix::Dynamics::ISensor* pObject );

	private:
		Mix::Scene::IRendererObject* m_pOwner;
		Mix::StringW m_Name;
		Mix::Matrix4x4 m_CenterMat;
		Mix::Dynamics::ISensor* m_pObject;

	private:
		MIX_DECLARE_ALLOCATOR();

		ActorSensor( const wchar_t* pName, const Mix::Matrix4x4& centerMat, Mix::Dynamics::ISensor* pSensor );
		ActorSensor( Mix::Scene::IRendererObject* pOwner, const wchar_t* pName, const Mix::Matrix4x4& centerMat, Mix::Dynamics::ISensor* pSensor );
		virtual ~ActorSensor( void );

	public:
		void SetOwner( Mix::Scene::IRendererObject* pOwner );

		void Reset( const Mix::Matrix4x4& baseMat );

		Mix::Dynamics::ISensor* GetInternalSensorPtr( void ) const;

		ActorSensor* Clone( void );

		void Dispose( void );

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

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

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::IActorSensor
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual const wchar_t* GetName( void ) const;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::ISensor
		////////////////////////////////////////////////////////////////////////////////////////////////////

		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 );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// 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;
	};

}}}
