#pragma once

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

#include "Mix/Reference.h"

namespace Mix{ namespace Dynamics{

	//! @class IJoint
	//! @brief ジョイントインターフェース
	class IJoint : public Mix::Reference
	{
	public:
		//! @enum TYPE
		//! @brief タイプ列挙定数
		enum TYPE
		{
			POINT	= 0,	//!< ポイント
			HINGE	= 1,	//!< ヒンジ
			BALL	= 2,	//!< ボール
			SLIDER	= 3,	//!< スライダー
			DOF		= 4,	//!< DOF
		};

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

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

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

		//! @brief 接続が有効かどうかを確認します
		//! @return 有効な場合は True を返します
		virtual Boolean IsEnabled( void ) const = 0;
		//! @brief 接続を有効にするかどうかを設定します
		//! @param[in] state 有効にする場合は True
		virtual void SetEnabled( Boolean state ) = 0;

		//! @brief 接続が解除される力を取得します
		//! @return 解除される力を返します
		virtual Float32 GetBreakingImpulseThreshold( void ) const = 0;
		//! @brief 接続を解除する力を設定します
		//! @param[in] threshold 解除される力( 単位はニュートン )
		//! @note 重力よりも大きい値を設定する必要があります
		virtual void SetBreakingImpulseThreshold( Float32 threshold ) = 0;

		//! @brief シングルかどうかを取得します
		//! @return シングルの場合は True を返します
		//! @note シングルとは、リジッドボディＡのみ指定されていてで、リジッドボディＢが指定されていない場合のことを言います
		virtual Boolean IsSingle( void ) const = 0;

		//! @brief リジッドボディAを取得します
		//! @param[out] ppRigidBody 取得したリジッドボディAを表す Mix::Dynamics::IRigidBody インターフェースのポインタのアドレス
		//! @note 取得したリジッドボディは、参照カウンタを +1 します
		virtual void GetRigidBodyA( Mix::Dynamics::IRigidBody** ppRigidBody ) = 0;
		//! @brief リジッドボディBを取得します
		//! @param[out] ppRigidBody 取得したリジッドボディBを表す Mix::Dynamics::IRigidBody インターフェースのポインタのアドレス
		//! @note 取得したリジッドボディは、参照カウンタを +1 します
		virtual void GetRigidBodyB( Mix::Dynamics::IRigidBody** ppRigidBody ) = 0;

		//! @brief リジッドボディＡのピボットを取得します
		//! @return ピボットを表す Mix::Vectro3 クラスを返します
		virtual const Mix::Vector3& GetPivotA( void ) const = 0;
		//! @brief リジッドボディＡのピボットを設定します
		//! @param[in] pivot ピボットを表す Mix::Vectro3 クラス
		virtual void SetPivotA( const Mix::Vector3& pivot ) = 0;

		//! @brief リジッドボディＢのピボットを取得します
		//! @return ピボットを表す Mix::Vectro3 クラスを返します
		virtual const Mix::Vector3& GetPivotB( void ) const = 0;
		//! @brief リジッドボディＢのピボットを設定します
		//! @param[in] pivot ピボットを表す Mix::Vectro3 クラス
		virtual void SetPivotB( const Mix::Vector3& pivot ) = 0;

	public:
		//! @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_GetDrawFrameMinSize( void ) const = 0;
		//! @brief デバッグ : フレームを描画する際の最小サイズを設定します
		//! @param[in] minSize フレームを描画する際の最小サイズ( 0.0f以上 )
		virtual void Debug_SetDrawFrameMinSize( Float32 minSize ) = 0;

		//! @brief デバッグ : リミットを描画する際のを取得します
		//! @return リミットを描画する際のスケールを返します
		virtual Float32 Debug_GetDrawLimitScaling( void ) const = 0;
		//! @brief デバッグ : リミットを描画する際のスケールを設定します
		//! @param[in] scaling リミットを描画する際のスケール( 0.0f以上 )
		virtual void Debug_SetDrawLimitScaling( 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;
	};

}}
