#pragma once

#include "Mix/Scene/ICollider.h"

namespace Mix{ namespace Scene{

	//! @class IKineticCollider
	//! @brief キネティックコライダー
	class IKineticCollider :  public Mix::Scene::ICollider
	{
	public:
		//! @brief 質量を取得します
		//! @return 質量を取得します
		virtual Float32 GetMass( void ) const = 0;
		//! @brief 質量を設定します
		//! @param[in] mass 質量( mass >= 0.0f )
		virtual void SetMass( Float32 mass ) = 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 常に活動状態に設定されている場合は True を返します
		virtual Boolean IsAlwaysActive( void ) const = 0;
		//! @brief 活動設定をします
		//! @param[in] state 常に活動状態にする場合は True
		//! @return 成功した場合は True を返します
		//! @note ステータスが「スタティック」の場合、このメソッドは False を返します
		virtual Boolean SetAlwaysActive( Boolean state ) = 0;

		//! @brief 活動状態を取得します
		//! @return 活動状態の場合は True を返します
		virtual Boolean IsActive( void ) const = 0;
		//! @brief 活動状態にします
		//! @return 成功した場合は True を返します
		//! @note ステータスが「スタティック」の場合、このメソッドは False を返します
		virtual Boolean Activate( void ) = 0;
		//! @brief 非活動状態にします
		//! @param[in] bFroce 強制的に非活動状態にする場合は True
		//! @return 成功した場合は True を返します
		//! @note ステータスが「スタティック」「キネマティック」の場合、このメソッドは False を返します
		virtual Boolean Deactivate( Boolean bFroce = False ) = 0;

		//! @brief 移動のファクタを設定します
		//! @return 移動のファクタを表す Mix::Vector3 クラスを返します
		virtual Mix::Vector3 GetLinearFactor( void ) const = 0;
		//! @brief 移動のファクタを設定します
		//! @param[in] factor 移動のファクタを表す Mix::Vector3 クラス
		//! @note Mix::Vector3( 0.0f, 0.0f, 0.0f ) を指定すると移動しなくなります
		virtual void SetLinearFactor( const Mix::Vector3& factor ) = 0;

		//! @brief 移動の減衰値を取得します
		//! @return 移動の減衰値を返します
		virtual Float32 GetLinearDamping( void ) const = 0;
		//! @brief 移動の減衰値を設定します
		//! @param[in] damping 移動における減衰値( 0.0f <= damping < 1.0f )
		virtual void SetLinearDamping( Float32 damping ) = 0;

		//! @brief 移動速度を取得します
		//! @return 移動速度を表す Mix::Vector3 クラスを返します
		virtual Mix::Vector3 GetLinearVelocity( void ) = 0;
		//! @brief 移動速度を設定します
		//! @param[in] velocity 線形速度を表す Mix::Vector3 クラス
		virtual Boolean SetLinearVelocity( const Mix::Vector3& velocity ) = 0;

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

		//! @brief 回転のファクタを設定します
		//! @return 回転のファクタを表す Mix::Vector3 クラスを返します
		virtual Mix::Vector3 GetAngularFactor( void ) const = 0;
		//! @brief 回転のファクタを設定します
		//! @param[in] factor 回転のファクタを表す Mix::Vector3 クラス
		//! @note Mix::Vector3( 0.0f, 0.0f, 0.0f ) を設定すると回転しなくなります
		virtual void SetAngularFactor( const Mix::Vector3& factor ) = 0;

		//! @brief 回転の減衰値を取得します
		//! @return 回転の減衰値を返します
		virtual Float32 GetAngularDamping( void ) const = 0;
		//! @brief 回転の減衰値を設定します
		//! @param[in] damping 回転運動における減衰値( 0.0f <= damping < 1.0f )
		virtual void SetAngularDamping( Float32 damping ) = 0;

		//! @brief 回転速度を取得します
		//! @return 回転速度を表す Mix::Vector3 クラスを返します
		virtual Mix::Vector3 GetAngularVelocity( void ) = 0;
		//! @brief 回転速度を設定します
		//! @param[in] velocity 回転速度を表す Mix::Vector3 クラス
		virtual Boolean SetAngularVelocity( const Mix::Vector3& velocity ) = 0;

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

		//! @brief 移動に撃力を適用します
		//! @param[in] impulse 適用する撃力を表す Mix::Vector3 クラス
		virtual Boolean ApplyLinearImpulse( const Mix::Vector3& impulse ) = 0;
		//! @brief 回転に撃力を適用します
		//! @param[in] impulse 適用する撃力を表す Mix::Vector3 クラス
		virtual Boolean ApplyAngularImpulse( const Mix::Vector3& impulse ) = 0;
		//! @brief 指定した位置に撃力を適用します
		//! @param[in] impulse 適用する撃力を表す Mix::Vector3 クラス
		//! @param[in] pos 撃力を適用する位置を表す Mix::Vector3 クラス
		virtual Boolean ApplyImpulse( const Mix::Vector3& impulse, const Mix::Vector3& pos ) = 0;

		//! @brief 移動に適用されている力を取得します
		//! @return 力を表す Mix::Vector3 クラスを返します
		virtual Mix::Vector3 GetTotalLinearForce( void ) = 0;
		//! @brief 回転に適用されている力を取得します
		//! @return 力を表す Mix::Vector3 クラスを返します
		virtual Mix::Vector3 GetTotalAngularForce( void ) = 0;
		//! @brief 移動に力を適用します
		//! @param[in] force 適用する力を表す Mix::Vector3 クラス
		virtual Boolean ApplyLinearForce( const Mix::Vector3& force ) = 0;
		//! @brief 回転に力を適用します
		//! @param[in] force 適用する力を表す Mix::Vector3 クラス
		virtual Boolean ApplyAngularForce( const Mix::Vector3& force ) = 0;
		//! @brief 指定した位置に力を適用します
		//! @param[in] force 適用する力を表す Mix::Vector3 クラス
		//! @param[in] pos 力を適用する位置を表す Mix::Vector3 クラス
		virtual Boolean ApplyForce( const Mix::Vector3& force, const Mix::Vector3& pos ) = 0;
		//! @brief 適用されている力をクリアします
		virtual void ClearForce( void ) = 0;

		//! @brief モーションをクリアします
		//! @note 全ての速度、全てのフォース、補間用パラメータをクリアします
		virtual void ClearMotion( void ) = 0;
		//! @brief モーションをクリアします
		//! @param[in] rot クリア後の回転を表す Mix::Quaternion クラス
		//! @param[in] pos クリア後の位置を表す Mix::Vector3 クラス
		virtual void ClearMotion( const Mix::Quaternion& rot, const Mix::Vector3& pos ) = 0;
	};

}}
