#pragma once

//! @file Mix/Scene/IParticleSystem.h
//! @brief パーティクルシステムインターフェースインクルードファイル

#include "Mix/Reference.h"

namespace Mix{ namespace Scene{

	//! @class IParticleSystem
	//! @brief パーティクルシステムタインターフェース
	class IParticleSystem : public Mix::Reference
	{
	public:
		//! @enum BASE_FLAGS
		//! @brief ベースフラグ列挙定数
		enum BASE_FLAGS
		{
			//! @brief 常にカメラの方向を向きます
			BILLBOARD	= 0x00000001,

			//! @brief 発生元の回転、移動の影響を受けない
			//! @note このフラグはリービングパーティクルのみ有効です。
			SIMULATION_WORLD_SPACE	= 0x00000002,
		};

		//! @enum BEHAVIOR_FLAGS
		//! @brief 振る舞いフラグ列挙定数
		//! @note リービングパーティクルのみ有効です。
		enum BEHAVIOR_FLAGS
		{
			//! @brief 視界に入っていない場合( Mix::Scene::IParticle::IsVisible() == False )は更新を行わない
			INVISIBLE_SLEEP	=	0x00000001,

			//! @brief 遠い場合( CONFIG::farMinDist 〜 CONFIG::farMaxDist )は指定された値( CONFIG::maxSkipFrames )だけフレームをスキップする
			//! @note スキップされるフレーム数は CONFIG::farMaxDist 以上で最大になります。
			FAR_SKIP_FRAMES	=	0x00000002,
		};

		//! @struct CONFIG
		//! @brief 設定構造体
		struct CONFIG
		{
			//! @brief ベースフラグ( Mix::Scene::IParticleSystem::BASE_FLAGS 列挙定数の組み合わせ )
			//! @note このフラグの組み合わせは途中で変更することはできません。
			UInt32 baseFlags;

			//! @brief 振る舞いフラグ( Mix::Scene::IParticleSystem::BEHAVIOR_FLAGS 列挙定数の組み合わせ )
			//! @note リービングパーティクルのみ有効です。
			UInt32 behaviorFlags;

			//! @brief 遠いと判断する最小距離( farMinDist > farMaxDist )
			//! @note この値は Mix::Scene::IParticle::IsFar Mix::Scene::IParticle::GetFarRatio で返される値にも使用されます。
			Float32 farMinDist;
			//! @brief 遠いと判断する最大距離( farMinDist < farMaxDist )
			//! @note この値は Mix::Scene::IParticle::IsFar Mix::Scene::IParticle::GetFarRatio で返される値にも使用されます。
			Float32 farMaxDist;

			//! @brief スキップする最大フレーム数
			UInt32 maxSkipFrames;
		};

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

	public:
		//! @brief 設定を取得します
		//! @return 設定を表す Mix::Scene::IParticleSystem::CONFIG 構造体を返します
		virtual const Mix::Scene::IParticleSystem::CONFIG& GetConfig( void ) const = 0;

		//! @brief ジェネレーターを取得します
		//! @param[out] ppGenerator 取得したジェネレーターを渡す Mix::Scene::IParticleGenerator インターフェースのポインタのアドレス
		//! @note
		//! このメソッドはパーティクル( Mix::Scene::IParticle )の内部から呼び出されるため、外部からの呼び出しは行わないでください。<br>
		//! またジェネレーターは基本的に常駐するかたちをとってください。
		virtual void Internal_GetGenerator( Mix::Scene::IParticleGenerator** ppGenerator ) = 0;
		//! @brief プロセッサーを作成します
		//! @param[out] ppProcessor 作成したプロセッサーを渡す Mix::Scene::IParticleProcessor インターフェースのポインタのアドレス
		//! @return 成功した場合は True を返します
		//! @note
		//! このメソッドはパーティクル( Mix::Scene::IParticle )の内部から呼び出されるため、外部からの呼び出しは行わないでください。<br>
		//! またプロセッサーはこのメソッドが呼び出されるごとに新しく作成してください。
		virtual Boolean Internal_CreateProcessor( Mix::Scene::IParticleProcessor** ppProcessor ) = 0;

		//! @brief 生成する間隔(秒単位)を取得します
		//! @return 生成する間隔を返します
		//! @note このメソッドはパーティクル( Mix::Scene::IParticle )の内部から呼び出されるため、外部からの呼び出しは行わないでください。
		virtual Float32 Internal_GetGenerateInterval( void ) const = 0;
		//! @brief 生成する数を取得します
		//! @return 生成する数を返します
		//! @note このメソッドはパーティクル( Mix::Scene::IParticle )の内部から呼び出されるため、外部からの呼び出しは行わないでください。
		virtual UInt32 Internal_GetGenerateCount( void ) const = 0;
	};

}}
