#pragma once

//! @file Mix/Scene/ISkyDome.h
//! @brief スカイドームインターフェースインクルードファイル

#include "Mix/Scene/IRendererObject.h"

namespace Mix{ namespace Scene{

	//! @class ISkyDome
	//! @brief スカイドームインターフェース
	class ISkyDome : public Mix::Scene::IRendererObject
	{
	public:
		//! @enum QUALITY
		//! @brief 品質列挙定数
		enum QUALITY
		{
			QL_LOW		= 0,	//!< 低 : ドーム( 10分割 ) 遠景(  6分割 )
			QL_MIDDLE	= 1,	//!< 中 : ドーム( 20分割 ) 遠景(  8分割 )
			QL_HIGH		= 2,	//!< 高 : ドーム( 30分割 ) 遠景( 12分割 )
		};

		//! @enum CONSTRAINT_TYPE
		//! @brief コンストレイントタイプ
		enum CONSTRAINT_TYPE
		{
			CR_XYZ	= 0,	//!< XYZ固定
			CR_XZ	= 1,	//!< XZ固定
		};

		//! @struct HEMISPHERE_SETTINGS
		//! @brief 半球設定構造体
		struct HEMISPHERE_SETTINGS
		{
			Float32 radius;	//!< 水平線の半径
			Float32 height;	//!< 地表から空への高さ
		};

		//! @struct PLANET_INFO
		//! @brief 惑星情報構造体
		struct PLANET_INFO
		{
			Float32 innerRadius;		//!< 内側の半径( 地表 )
			Float32 outerRadius;		//!< 外側の半径( 大気を含む )
			Mix::Vector3 coreOffset;	//!< 惑星の中心座標のオフセット
		};

		//! @struct BASE_SETTINGS
		//! @brief 基本設定構造体
		struct BASE_SETTINGS
		{
			Mix::Vector4 color;	//!< 色

			Float32 texScale;	//!< テクスチャのスケール( 0.0f 以上 )
			Float32 texOpacity;	//!< テクスチャの不透明度( 0.0f 以上 )
		};

		//! @struct SUN_LIGHT
		//! @brief サンライト構造体
		struct SUN_LIGHT
		{
			Mix::Vector3 pos;	//!< 光源の位置( ワールド座標 )
			Mix::Vector3 dir;	//!< 照らしている方向
			Float32 height;		//!< 光源の高度( COS値 )
		};

		//! @struct CLOUD_LAYER_SETTINGS
		//! @brief 雲レイヤーパラメータ構造体
		struct CLOUD_LAYER_SETTINGS
		{
			//! @brief 最初のテクスチャ座標
			//! @note ResetCloud で使用されます
			Mix::Vector2 initialTex;

			Mix::Vector2 vel;			//!< 毎秒の移動速度
			Float32 scale;				//!< スカイドームに貼り付ける際のＵＶ座標のスケール( 0.0f以上 )
			Float32 opacity;			//!< 不透明度( 0.0f以上 )
		};

		//! @struct CLOUD_GLOBAL_SETTINGS
		//! @brief 雲グローバル設定構造体
		struct CLOUD_GLOBAL_SETTINGS
		{
			Mix::Vector4 color;	//!< 色

			Float32 speed;	//!< スピード

			//! @brief 大気散乱シミュレーションの影響を受ける場合は True
			//! @note　大気 ( 太陽光 ) の影響を受けて、雲の色が変化します。<br>
			Boolean asEffect;
			//! @brief 太陽によるライティングを行う場合は True
			//! @note
			//! 大気散乱シミュレーションが利用可能であり、asEffect == True の場合に機能します。<br>
			//! また、ライティングには以下のパラメータが影響します。<br>
			//! <br>
			//! asCornerThreshold<br>
			//! asDarknessStart<br>
			//! asDarknessEnd<br>
			Boolean asSunLighting;

			//! @brief 夜の雲の暗さ( 0.0f〜1.0f )
			//! @note
			//! 値が大きいほど暗く、小さいほど明るくなります。<br>
			//! また、大気散乱シミュレーションが利用可能であり、asEffect(True) の場合に機能します。
			Float32 asNightness;

			//! @brief 隅の閾値( 0.0f〜1.0f )
			//! @note
			//! 逆光を浴びた際に光が遮断されず、通過してくる透明度の閾値になります。<br>
			//! また、大気散乱シミュレーションが利用可能であり、asEffect(True) asLighting(True) の場合に機能します。
			Float32 asCornerThreshold;
			//! @brief 光が遮断されている部分の暗さの開始値( 0.0f〜1.0f )
			//! @note
			//! 光が遮断される部分は、太陽が真上にあるほど明るく、水平線に近くなるほど暗くなります。( asDarknessStart〜asDarknessEnd )<br>
			//! また、大気散乱シミュレーションが利用可能であり、asEffect(True) asLighting(True) の場合に機能します。
			Float32 asDarknessStart;
			//! @brief 光が遮断されている部分の暗さの終了値( asDarknessStart〜1.0f )
			//! @note
			//! 光の遮断の動作については asDarknessStart の説明を読んでください。<br>
			//! また、大気散乱シミュレーションが利用可能であり、asEffect(True) asLighting(True) の場合に機能します。
			Float32 asDarknessEnd;
		};

		//! @struct PANORAMA_SETTINGS
		//! @brief 遠景設定構造体
		struct PANORAMA_SETTINGS
		{
			Mix::Vector4 color;		//!< 色

			Mix::Vector2 scale;		//!< スケール
			Float32 offsetY;		//!< Y方向のオフセット
			Float32 dist;			//!< 距離( フォグのかかり具合に影響します )

			//! @brief テクスチャの横方向へのリピート数
			//! @note
			//! この値はパノラマのクオリティに依存します。
			//! <ul>
			//!   <li>QL_LOW</li> 0 1 2 3 6<br>
			//!   <li>QL_MIDDLE</li> 0 1 2 4 8<br>
			//!   <li>QL_HIGH</li> 0 1 2 3 4 6 12<br>
			//! </ul>
			//! ※ 0 はリピートしないことを意味します
			UInt32 texRepeatNum;
		};

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

	public:
		//! @name 全般
		//! @{

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

		//! @brief 拘束タイプを取得します
		//! @return タイプを表す Mix::Scene::ISkyDome::CONSTRAINT_TYPE 列挙定数を返します
		virtual Mix::Scene::ISkyDome::CONSTRAINT_TYPE GetConstraintType( void ) const = 0;
		//! @brief 拘束タイプを設定します
		//! @param[in] type タイプを表す Mix::Scene::ISkyDome::CONSTRAINT_TYPE 列挙定数
		virtual void SetConstraintType( Mix::Scene::ISkyDome::CONSTRAINT_TYPE type ) = 0;

		//! @brief 半球の品質を取得します
		//! @return 品質を表す Mix::Scene::ISkyDome::QUALITY 列挙定数を返します
		virtual Mix::Scene::ISkyDome::QUALITY GetHemisphereQuality( void ) const = 0;
		//! @brief 半球の設定を取得します
		//! @return 設定を表す Mix::Scene::ISkyDome::HEMISPHERE_SETTINGS 構造体を返します
		virtual const Mix::Scene::ISkyDome::HEMISPHERE_SETTINGS& GetHemisphereSettings( void ) const = 0;
		//! @brief 半球を設定します
		//! @param[in] settings 設定を表す Mix::Scene::ISkyDome::HEMISPHERE_SETTINGS 構造体
		virtual void SetHemisphereSettings( const Mix::Scene::ISkyDome::HEMISPHERE_SETTINGS& settings ) = 0;

		//! @brief 惑星の情報を取得します
		//! @return 情報を表す Mix::Scene::ISkyDome::PLANET_INFO 構造体を返します
		//! @note 惑星の情報は半球の設定により更新されます。
		virtual const Mix::Scene::ISkyDome::PLANET_INFO& GetPlanetInfo( void ) const = 0;

		//! @}

		//! @name 太陽
		//! @{

		//! @brief 太陽の位置を取得します
		//! @return 位置を表す Mix::Vector3 クラスを返します
		virtual const Mix::Vector3& GetSunPosition( void ) const = 0;
		//! @brief 太陽の位置を設定します
		//! @param[in] pos 位置を表す Mix::Vector3 クラス
		//! @note
		//! ここで設定される位置は原点( 0.0f, 0.0f, 0.0f )を中心とした位置ではなく、<br>
		//! 惑星の中心( PLANET_INFO::coreOffset )を原点とした相対位置になります。
		virtual void SetSunPosition( const Mix::Vector3& pos ) = 0;

		//! @brief 太陽によるライティングを取得します
		//! @return ライティングを表す Mix::Scene::ISkyDome::SUN_LIGHT 構造体を返します
		virtual const Mix::Scene::ISkyDome::SUN_LIGHT& GetSunLight( void ) const = 0;

		//! @}

		//! @name ベース
		//! @{

		//! @brief ベースの設定を取得します
		//! @return 設定を表す Mix::Scene::ISkyDome::BASE_SETTINGS 構造体を返します
		virtual const Mix::Scene::ISkyDome::BASE_SETTINGS& GetBaseSettings( void ) const = 0;
		//! @brief ベースを設定します
		//! @param[in] settings 設定を表す Mix::Scene::ISkyDome::BASE_SETTINGS 構造体
		virtual void SetBaseSettings( const Mix::Scene::ISkyDome::BASE_SETTINGS& settings ) = 0;
		//! @brief ベースのテクスチャを取得します
		//! @param[out] ppTexture 取得したテクスチャを渡す Mix::Graphics::ITexture インターフェースのポインタのアドレス
		//! @return 成功した場合は True を返します
		//! @note 取得に成功した場合は、テクスチャの参照カウンタを +1 します
		virtual Boolean GetBaseTexture( Mix::Graphics::ITexture** ppTexture ) = 0;
		//! @brief ベースのテクスチャを設定します
		//! @param[in] pTexture 設定するテクスチャを表す Mix::Graphics::ITexture インターフェースのポインタ
		//! @note 設定されたテクスチャは、参照カウンタを +1 します
		virtual void SetBaseTexture( Mix::Graphics::ITexture* pTexture ) = 0;

		//! @}

		//! @name クラウド ( 雲 )
		//! @{

		//! @brief 雲が有効かどうかを確認します
		//! @return 有効な場合は True を返します
		virtual Boolean IsCloudEnabled( void ) const = 0;
		//! @brief 雲を有効にするかどうかを設定します
		//! @param[in] state 有効にする場合は True
		virtual void SetCloudEnabled( Boolean state ) = 0;
		//! @brief 雲のレイヤー数を取得します
		//! @return レイヤーの数を返します
		virtual UInt32 GetCloudLayerNum( void ) const = 0;
		//! @brief 雲のレイヤーテクスチャを取得します
		//! @param[in] layerIndex レイヤーのインデックス( 0〜1 )
		//! @param[out] ppTex 取得したテクスチャを渡す Mix::Graphics::ITexture インターフェースのポインタのアドレス
		//! @return 成功した場合は True を返します
		virtual Boolean GetCloudLayerTexture( UInt32 layerIndex, Mix::Graphics::ITexture** ppTex ) = 0;
		//! @brief 雲のレイヤーテクスチャを設定します
		//! @param[in] layerIndex レイヤーのインデックス( 0〜1 )
		//! @param[in] pTex 設定するテクスチャを表す Mix::Graphics::ITexture インターフェースのポインタ( NULL 指定可能 )
		//! @return 成功した場合は True を返します
		virtual Boolean SetCloudLayerTexture( UInt32 layerIndex, Mix::Graphics::ITexture* pTex ) = 0;
		//! @brief 雲のレイヤーの設定を取得します
		//! @param[in] layerIndex レイヤーのインデックス( 0〜1 )
		//! @return 設定を表す Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS 構造体を返します
		virtual const Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS& GetCloudLayerSettings( UInt32 layerIndex ) const = 0;
		//! @brief 雲のレイヤーを設定します
		//! @param[in] settings 設定を表す Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS 構造体の配列
		//! @param[in] num 設定の数( num <= 2 )
		//! @return 実際に設定したパラメータの数を返します
		virtual UInt32 SetCloudLayerSettings( const Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS* settings, UInt32 num ) = 0;
		//! @brief 雲のレイヤー設定をロックします
		//! @param[out] settings ロックしたパラメータを表す Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS 構造体のポインタのアドレス
		//! @param[in] num ロックする設定の数
		//! @return 実際にロックした設定の数を返します
		//! @note このメソッドは設定配列を取得すると同時にレイヤー数( num )を設定します
		virtual UInt32 LockCloudLayerSettings( Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS** settings, UInt32 num ) = 0;
		//! @brief 雲のグローバル設定を取得します
		//! @return 雲の設定を表す Mix::Scene::ISkyDome::CLOUD_GLOBAL_SETTINGS 構造体を返します
		virtual const Mix::Scene::ISkyDome::CLOUD_GLOBAL_SETTINGS& GetCloudGlobalSettings( void ) const = 0;
		//! @brief 雲のグローバル設定をします
		//! @param[in] settings 設定を表す Mix::Scene::ISkyDome::CLOUD_GLOBAL_SETTINGS 構造体
		virtual void SetCloudGlobalSettings( const Mix::Scene::ISkyDome::CLOUD_GLOBAL_SETTINGS& settings ) = 0;
		//! @brief 雲をリセットします
		//! @note Mix::Scene::ISkyDome::CLOUD_LAYER_SETTINGS 構造体の initialTex の値を雲のテクスチャ座標に反映します。
		virtual void ResetCloud( void ) = 0;

		//! @}

		//! @name パノラマ ( 遠景 )
		//! @{

		//! @brief 遠景が存在しているかどうかを確認します
		//! @return 存在している場合は True を返します
		virtual Boolean ExistsPanorama( void ) const = 0;
		//! @brief 遠景の品質を取得します
		//! @return 品質を表す Mix::Scene::ISkyDome::QUALITY 列挙定数を返します
		virtual Mix::Scene::ISkyDome::QUALITY GetPanoramaQuality( void ) const = 0;
		//! @brief 遠景が有効かどうかを取得します
		//! @return 有効な場合は True を返します
		virtual Boolean IsPanoramaEnabled( void ) const = 0;
		//! @brief 遠景を有効にするかどうかを設定します
		//! @param[in] state 有効にする場合は True
		virtual void SetPanoramaEnabled( Boolean state ) = 0;
		//! @brief 遠景の設定を取得します
		//! @return パラメータを表す Mix::Scene::ISkyDome::PANORAMA_SETTINGS 構造体を返します
		virtual const Mix::Scene::ISkyDome::PANORAMA_SETTINGS& GetPanoramaSettings( void ) const = 0;
		//! @brief 遠景を設定します
		//! @param[in] settings 設定を表す Mix::Scene::ISkyDome::PANORAMA_SETTINGS 構造体
		virtual void SetPanoramaSettings( const Mix::Scene::ISkyDome::PANORAMA_SETTINGS& settings ) = 0;
		//! @brief 遠景のテクスチャを取得します
		//! @param[out] ppTex テクスチャを表す Mix::Graphics::ITexture インターフェースのポインタのアドレス
		//! @return 成功した場合は True を返します
		virtual Boolean GetPanoramaTexture( Mix::Graphics::ITexture** ppTex ) = 0;
		//! @brief 遠景のテクスチャを設定します
		//! @param[in] pTex テクスチャを表す Mix::Graphics::ITexture インターフェース
		virtual void SetPanoramaTexture( Mix::Graphics::ITexture* pTex ) = 0;
		//! @brief 現在設定されている遠景のパラメータに基づいて、テクスチャのアスペクト比を取得します
		//! @return アスペクト比を表す Mix::Vector2 クラスを返します
		virtual Mix::Vector2 GetPanoramaTextureAspectRatio( void ) const = 0;

		//! @}
	};

}}
