#pragma once

//! @file Mix/Scene/ILeavingParticle.h
//! @brief リービングパーティクルインターフェースインクルードファイル

#include "Mix/Scene/IParticle.h"
#include "Mix/Geometry/AABB.h"

namespace Mix{ namespace Scene{

	//! @class ILeavingParticle
	//! @brief リービングパーティクルインターフェース
	//! @note
	//! 据え置きタイプのパーティクルになります。<br>
	//! 個々に配置する、炎や煙などに最適です。
	class ILeavingParticle : public Mix::Scene::IParticle
	{
	public:
		//! @enum CLONE_FLAGS
		//! @brief クローンフラグ列挙定数
		enum CLONE_FLAGS
		{
			//! @brief マテリアルを共有する
			C_SHARED_MATERIAL			= 0x00000001,

			//! @brief プロセッサーを複製する
			//! @note
			//! プロサッセーを複製した場合は、現在のパーティクルの発生状態がそのままコピーされます。<br>
			//! また、このフラグを指定しなかった場合は、プロセッサーは新規に作成され、初期( なにも発生していない )状態になります。<br>
			//! <br>
			//! <b>※ Mix::Scene::ILeavingParticleSystem::CONFIG の behaviorFlags に Mix::Scene::ILeavingParticleSystem::B_INDIVIDUAL が設定されている場合は機能しません。</b>
			C_DUPLICATE_PROCESSOR		= 0x00000002,

			//!< 全てのクローンフラグ
			C_ALL						= ( C_SHARED_MATERIAL | C_DUPLICATE_PROCESSOR ),
		};

		//! @struct STATE
		//! @brief ステート構造体
		struct STATE
		{
			UInt32 quadCount;			//!< クワッドの数
			UInt32 quadCapacity;		//!< クワッドのキャパシティ

			Boolean bSleep;				//!< スリープ中の場合は True

			Float32 farRatio;			//!< 遠さ( 0.0f 〜 1.0f )

			Float32 deltaTimer;			//!< スキップしたフレームのデルタタイムの合計

			UInt32 skipFrames;			//!< スキップしたフレーム数
			UInt32 curMaxSkipFrames;	//!< 現在のスキップする最大フレーム数
		};

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

	public:
		//! @brief ワールド行列を取得します
		//! @return ワールド行列を表す Mix::Matrix4x4 クラスを返します
		virtual const Mix::Matrix4x4& GetWorldMatrix( void ) const = 0;
		//! @brief ワールド行列を設定します
		//! @param[in] worldMat ワールド行列を表す Mix::Matrix4x4 クラス
		virtual void SetWorldMatrix( const Mix::Matrix4x4& worldMat ) = 0;

		//! @brief 再生しているかどうかを確認します
		//! @return 再生している場合は True を返します
		virtual Boolean IsPlay( void ) const = 0;
		//! @brief 再生します
		//! @param[in] bLoop 継続して再生する場合は True
		virtual void Play( Boolean bLoop ) = 0;
		//! @brief 再生します
		//! @param[in] bLoop 継続して再生する場合は True
		//! @param[in] dt デルタタイム( 秒単位 )
		//! @param[in] stepCount ステップ数
		virtual void Play( Boolean bLoop, Float32 dt, UInt32 stepCount ) = 0;
		//! @brief 停止します
		//! @param[in] bForce 強制的に停止する場合は True
		virtual void Stop( Boolean bForce = False ) = 0;

		//! @brief ステートを取得します
		//! @return ステートを表す Mix::Scene::ILeavingParticle::STATE 構造体を返します
		virtual const Mix::Scene::ILeavingParticle::STATE& GetState( void ) const = 0;

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

		//! @brief 視界に入っているかどうかを確認します
		//! @return 視界に入っている場合は True を返します
		virtual Boolean IsVisible( void ) const = 0;
		//! @brief 視界に入っているかどうかを確認します
		//! @param[in] id ビューの識別子
		//! @return 視界に入っている場合は True を返します
		virtual Boolean IsVisible( UInt32 id ) const = 0;
		//! @brief 圏外かどうかを確認します
		//! @return 圏外の場合は True を返します
		//! @note 圏外とは描画判定に使用される八分木の範囲を超えて配置されている状態のことを表します。
		virtual Boolean IsIgnored( void ) const = 0;

		//! @brief 自身のクローンを作成します
		//! @param[out] ppParticle 自身のクローンを渡す Mix::Scene::ILeavingParticle インターフェースのポインタのアドレス
		//! @param[in] flags クローンのフラグを表す Mix::Scene::IActorModel::CLONE_FLAGS 列挙定数の組み合わせ
		//! @return 成功した場合は True を返します
		virtual Boolean Clone( Mix::Scene::ILeavingParticle** ppParticle, UInt32 flags = Mix::Scene::ILeavingParticle::C_ALL ) = 0;
	};

}}
