#pragma once

//! @file Mix/Dynamics/IObject.h
//! @brief オブジェクトインターフェースインクルードファイル

#include "Mix/Reference.h"
#include "Mix/Geometry/AABB.h"

namespace Mix{ namespace Dynamics{

	//! @class IObject
	//! @brief オブジェクトインターフェース
	class IObject : public Mix::Reference
	{
	public:
		//! @enum TYPE
		//! @brief タイプ列挙定数
		enum TYPE
		{
			STATIC_PLANE		= 0,	//!< スタティックプレーン
			STATIC_MESH			= 1,	//!< スタティックメッシュ
			RIGIDBODY			= 2,	//!< リジッドボディ
			SENSOR				= 3,	//!< センサー
			KINEMATIC_CHARACTER	= 4,	//!< キネマティックキャラクター
			VEHICLE				= 5,	//!< ビハイクル
		};

	protected:
		//! @brief デストラクタ
		virtual ~IObject( void ) {}

	public:
		//! @brief 種類を取得します
		//! @return 種類を表す Mix::Dynamics::IObject::TYPE 列挙定数を返します
		virtual Mix::Dynamics::IObject::TYPE GetType( void ) const = 0;

		//! @brief シェイプを取得します
		//! @param[out] ppShape 取得したシェイプを渡す Mix::Dynamics::IShape インターフェースのポインタのアドレス
		//! @return 成功した場合は True を返します
		//! @note
		//! 以下のオブジェクトはシェイプを取得することができないため、<br>
		//! このメソッドは常に False を返します。<br>
		//! <br>
		//! Mix::Dynamics::IStaticPlane<br>
		//! Mix::Dynamics::IStaticMesh 
		virtual Boolean GetShape( Mix::Dynamics::IShape** ppShape ) = 0;

		//! @brief シェイプの衝突マージンを取得します
		//! @return 衝突マージンを返します
		//! @note Mix::Dynamics::IShape::GetMargine を呼び出しています
		virtual Float32 GetShapeMargin( void ) const = 0;
		//! @brief シェイプの衝突マージンを設定します
		//! @param[in] margin 衝突マージン
		//! @note Mix::Dynamics::IShape::SetMargine を呼び出しています
		virtual void SetShapeMargin( Float32 margin ) = 0;

		//! @brief フィルターグループを取得します
		//! @return フィルターグループを返します
		virtual UInt16 GetFilterGroup( void ) const = 0;
		//! @brief フィルターグループを設定します
		//! @param[in] filterGroup フィルターグループ
		virtual void SetFilterGroup( UInt16 filterGroup ) = 0;

		//! @brief フィルターマスクを取得します
		//! @return フィルターマスクを返します
		virtual UInt16 GetFilterMask( void ) const = 0;
		//! @brief フィルターマスクを設定します
		//! @param[in] filterMask フィルターマスク
		virtual void SetFilterMask( UInt16 filterMask ) = 0;

		//! @brief マテリアルを取得します
		//! @return マテリアルを表す Mix::Dynamics::MATERIAL 構造体を返します
		virtual const Mix::Dynamics::MATERIAL& GetMaterial( void ) const = 0;
		//! @brief マテリアルを設定します
		//! @param[in] material マテリアルを表す Mix::Dynamics::MATERIAL 構造体
		virtual void SetMaterial( const Mix::Dynamics::MATERIAL& material ) = 0;

		//! @brief ワールドの回転を取得します
		//! @return ワールドの回転を表す Mix::Quaternion クラスを返します
		virtual Mix::Quaternion GetWorldRotation( void ) const = 0;
		//! @brief ワールドの位置を取得します
		//! @return 位置を表す Mix::Vector3 クラスを返します
		virtual Mix::Vector3 GetWorldPosition( void ) const = 0;
		//! @brief ワールド行列を取得します
		//! @return ワールド行列を表す Mix::Matrix4x4 クラスを返します
		virtual Mix::Matrix4x4 GetWorldMatrix( void ) const = 0;

		//! @brief ワールドの回転を設定します
		//! @param[in] rot 回転を表す Mix::Quaternion クラス
		virtual void SetWorldRotation( const Mix::Quaternion& rot ) = 0;
		//! @brief ワールドの位置を設定します
		//! @param[in] pos 位置を表す Mix::Vector3 クラス
		virtual void SetWorldPosition( const Mix::Vector3& pos ) = 0;
		//! @brief ワールドトランスフォームを設定します
		//! @param[in] rot 回転を表す Mix::Quaternion クラス
		//! @param[in] pos 位置を表す Mix::Vector3 クラス
		virtual void SetWorldTransform( const Mix::Quaternion& rot, const Mix::Vector3& pos ) = 0;

		//! @brief ワールドに配置されているかどうかを確認します
		//! @return 配置されている場合は True を返します
		virtual Boolean IsInWorld( void ) const = 0;

		//! @brief 境界を取得します
		//! @return 境界を表す Mix::Geometry::AABB クラスを返します
		virtual Mix::Geometry::AABB GetBounds( void ) const = 0;

		//! @brief リスナーを追加します
		//! @param[in] pListener 追加するリスナーを表す Mix::Dynamics::IObjectListener インターフェースのポインタ
		//! @return 追加に成功した場合は True を返します
		virtual Boolean AddListener( Mix::Dynamics::IObjectListener* pListener ) = 0;
		//! @brief リスナーを削除します
		//! @param[in] pListener 削除するリスナーを表す Mix::Dynamics::IObjectListener インターフェースのポインタ
		virtual void RemoveListener( Mix::Dynamics::IObjectListener* pListener ) = 0;

		//! @brief ユーザーインデックスを取得します
		//! @return インデックスを返します
		virtual Int32 GetUserIndex( void )  const = 0;
		//! @brief ユーザーインデックスを設定します
		//! @param index インデックス
		//! @note この値はユーザーが自由に使用できます
		virtual void SetUserIndex( Int32 index ) = 0;

		//! @brief ユーザーポインタを取得します
		//! @return ポインタを返します
		virtual void* GetUserPtr( void ) const = 0;
		//! @brief ユーザーポインタを設定します
		//! @param pData ポインタ
		//! @note この値はユーザーが自由に使用できます
		virtual void SetUserPtr( void* pData ) = 0;

		//! @brief デバッグ : 描画フラグを取得します
		//! @return 描画フラグを表す Mix::Dynamics::DEBUG_DRAW_FLAG 列挙定数の組み合わせを返します
		virtual UInt32 Debug_GetDrawFlags( void ) const = 0;
		//! @brief デバッグ : 描画フラグを設定します
		//! @param[in] flags 描画フラグを表す Mix::Dynamics::DEBUG_DRAW_FLAG 列挙定数の組み合わせ
		virtual void Debug_SetDrawFlags( UInt32 flags ) = 0;

		//! @brief デバッグ : 軸を描画する際のを取得します
		//! @return 軸を描画する際のスケールを返します
		virtual Float32 Debug_GetDrawAxisScaling( void ) const = 0;
		//! @brief デバッグ : 軸を描画する際のスケールを設定します
		//! @param[in] scaling 軸を描画する際のスケール( 0.0f以上 )
		virtual void Debug_SetDrawAxisScaling( Float32 scaling ) = 0;

		//! @brief デバッグ描画をします
		//! @param[in] pPerspectiveRenderer デバッグ描画用のインターフェースを表す Mix::Graphics::Utility::IPerspectiveRenderer インターフェースのポインタ
		//! @param[in] opacity 不透明度( 0.0f〜1.0f )
		virtual void Debug_Draw( Mix::Graphics::Utility::IPerspectiveRenderer* pPerspectiveRenderer, Float32 opacity = 1.0f ) = 0;
	};

}}
