#pragma once

//! @file Mix/Scene/IActorDynamicsDirector.h
//! @brief アクターダイナミクスディレクターインターフェースインクルードファイル

#include "Mix/Reference.h"

namespace Mix{ namespace Scene{

	//! @class IActorDynamicsDirector
	//! @brief アクターダイナミクスディレクターインターフェース
	class IActorDynamicsDirector : public Mix::Reference
	{
	public:
		//! @class ICollection
		//! @brief コレクションインターフェース
		//! @tparam T オブジェクトの型
		template<typename T>
		class ICollection : public Mix::Reference
		{
		protected:
			//! @brief デストラクタ
			virtual ~ICollection( void ) {}

		public:
			//! @brief オブジェクトの数を取得します
			//! @return オブジェクトの数を返します
			virtual UInt32 GetCount( void ) const = 0;

			//! @brief オブジェクトを取得します
			//! @param[in] index インデックス
			//! @param[out] ppObject 取得したオブジェクトのポインタのアドレスを返します
			//! @return 成功した場合は True を返します
			//! @note 取得したオブジェクトは参照カウンタを +1 します
			virtual Boolean Get( UInt32 index, T** ppObject ) = 0;

			//! @brief オブジェクトを取得します
			//! @param[in] index インデックス
			//! @return 成功した場合はオブジェクトのポインタを返します。<br>
			//! また失敗した場合は NULL を返します。
			//! @note オブジェクトのポインタを返すだけで、参照カウンタはインクリメントされませんので注意してください。
			virtual T* operator[] ( UInt32 index ) const = 0;
		};

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

	public:
		//! @brief キャラクターが有効かどうかを確認します
		//! @return 有効な場合は True を返します
		virtual Boolean IsCharacterEnabled( void ) const = 0;
		//! @brief キャラクターを有効にするかどうかを設定します
		//! @param[in] state 有効にする場合は True
		virtual void SetCharacterEnabled( Boolean state ) = 0;
		//! @brief キャラクターのモードを取得します
		//! @return モードを表す Mix::Scene::DYNAMICS_KCHAR_MODE 列挙定数を返します
		virtual Mix::Scene::DYNAMICS_KCHAR_MODE GetCharacterMode( void ) const = 0;
		//! @brief キャラクターのモードを設定します
		//! @param[in] mode モードを表す Mix::Scene::DYNAMICS_KCHAR_MODE 列挙定数
		//! @param[in] bInstantly 即座に実行したい場合は True
		//! @note 通常この操作は Mix::Scene::IActorModel::Update で行われます。
		virtual void SetCharacterMode( Mix::Scene::DYNAMICS_KCHAR_MODE mode, Boolean bInstantly = False ) = 0;

		//! @brief コライダーが有効かどうかを確認します
		//! @return 有効な場合は True を返します
		virtual Boolean IsColliderEnabled( void ) const = 0;
		//! @brief コライダーを有効にするかどうかを設定します
		//! @param[in] state 有効にする場合は True
		virtual void SetColliderEnabled( Boolean state ) = 0;
		//! @brief コライダーのモードを取得します
		//! @return モードを表す Mix::Scene::DYNAMICS_COLLIDER_MODE 列挙定数を返します
		virtual Mix::Scene::DYNAMICS_COLLIDER_MODE GetColliderMode( void ) const = 0;
		//! @brief コライダーのモードを設定します
		//! @param[in] mode モードを表す Mix::Scene::DYNAMICS_COLLIDER_MODE 列挙定数
		//! @param[in] bInstantly 即座に実行したい場合は True
		//! @note
		//! 通常この操作は Mix::Scene::IActorModel::Update で行われます。<br>
		//! <br>
		//! <b>(即知のバグ)</b><br>
		//! モードをラグドール( Mix::Scene::DC_RAGDOLL )に設定した場合、<br>
		//! モデルが異様な変形をしてしまう場合は、 Mix::Scene::IActorModel::Reset などを使用して、ノードのローカル行列を初期値にしてください。<br>
		//! これはノードにコライダーが存在せず、モーションなどによりローカル行列が変更されている際に発生します。<br>
		//! <br>
		virtual void SetColliderMode( Mix::Scene::DYNAMICS_COLLIDER_MODE mode, Boolean bInstantly = False ) = 0;

		//! @brief センサーが有効かどうかを取得します
		//! @return 有効な場合は True を返します
		virtual Boolean IsSensorEnabled( void ) const = 0;
		//! @brief センサーを有効にするかどうかを設定します
		//! @param[in] state 有効にする場合は True
		virtual void SetSensorEnabled( Boolean state ) = 0;

		//! @brief 全てのコライダーを含むコレクションを取得します
		//! @param[out] ppCollection コレクションを表す Mix::Scene::IActorDynamicsController::ICollection<Mix::Scene::IActorCollider> インターフェースのポインタのアドレス
		//! @return 成功した場合は True を返します
		virtual Boolean GetColliders( Mix::Scene::IActorDynamicsDirector::ICollection<Mix::Scene::IActorCollider>** ppCollection ) = 0;
		//! @brief 指定した名前のコライダー含むコレクションを取得します
		//! @param[in] pName 名前
		//! @param[out] ppCollection コレクションを表す Mix::Scene::IActorDynamicsController::ICollection<Mix::Scene::IActorCollider> インターフェースのポインタのアドレス
		//! @return 成功した場合は True を返します
		virtual Boolean GetColliders( const wchar_t* pName, Mix::Scene::IActorDynamicsDirector::ICollection<Mix::Scene::IActorCollider>** ppCollection ) = 0;

		//! @brief 全てのセンサーを含むコレクションを取得します
		//! @param[out] ppCollection コレクションを表す Mix::Scene::IActorDynamicsController::ICollection<Mix::Scene::ISensor> インターフェースのポインタのアドレス
		//! @return 成功した場合は True を返します
		virtual Boolean GetSensors( Mix::Scene::IActorDynamicsDirector::ICollection<Mix::Scene::IActorSensor>** ppCollection ) = 0;
		//! @brief 指定した名前のセンサー含むコレクションを取得します
		//! @param[in] pName 名前
		//! @param[out] ppCollection コレクションを表す Mix::Scene::IActorDynamicsController::ICollection<Mix::Scene::ISensor> インターフェースのポインタのアドレス
		//! @return 成功した場合は True を返します
		virtual Boolean GetSensors( const wchar_t* pName, Mix::Scene::IActorDynamicsDirector::ICollection<Mix::Scene::IActorSensor>** ppCollection ) = 0;

		//! @brief 活動状態かどうかを確認します
		//! @return 活動状態の場合は True を返します
		//! @note 返される値は Mix::Scene::IActorModel::Refresh で更新されます。
		virtual Boolean IsActive( void ) const = 0;
		//! @brief 活動状態にします
		//! @param[in] bInstantly 即座に実行したい場合は True
		//! @note 通常この操作は Mix::Scene::IActorModel::Update で行われます。
		virtual void Activate( Boolean bInstantly = False ) = 0;
		//! @brief 非活動状態にします
		//! @param[in] bForce 強制的に非活動状態にする場合は True
		//! @param[in] bInstantly 即座に実行したい場合は True
		//! @note 通常この操作は Mix::Scene::IActorModel::Update で行われます。
		virtual void Deactivate( Boolean bForce = False, Boolean bInstantly = False ) = 0;

		//! @brief フォースをクリアします
		//! @param[in] bInstantly 即座に実行したい場合は True
		//! @note 通常この操作は Mix::Scene::IActorModel::Refresh で行われます。
		virtual void ClearForce( Boolean bInstantly = False ) = 0;
		//! @brief モーションをクリアします
		//! @param[in] bInstantly 即座に実行したい場合は True
		//! @note
		//! 「フォース」「速度」をクリアします。
		//! 通常この操作は Mix::Scene::IActorModel::Refresh で行われます。
		virtual void ClearMotion( Boolean bInstantly = False ) = 0;

		//! @brief 移動を停止する速度を取得します
		//! @return 移動を停止する速度を返します
		virtual Float32 GetLinearSleepingThresholds( void ) const = 0;
		//! @brief 移動を停止する速度を設定します
		//! @param[in] threshold 移動を停止する速度
		virtual void SetLinearSleepingThresholds( Float32 threshold ) = 0;

		//! @brief 回転を停止する速度を取得します
		//! @return 回転を停止する速度を返します
		virtual Float32 GetAngularSleepingThresholds( void ) const = 0;
		//! @brief 回転を停止する速度を設定します
		//! @param[in] threshold 回転を停止する速度
		virtual void SetAngularSleepingThresholds( Float32 threshold ) = 0;
	};

}}
