#pragma once

//! @file Mix/Scene/IDefaultMaterial.h
//! @brief デフォルトマテリアルインターフェースインクルードファイル

#include "Mix/Scene/IMaterial.h"

namespace Mix{ namespace Scene{

	//! @class IDefaultMaterial
	//! @brief デフォルトマテリアルインターフェース
	//! @note
	//! <ul>
	//!   <li>BeginConstant EndConstant に対して有効なメソッド</li><br>
	//!   SetAmbientColor<br>
	//!   SetDiffuseColor<br>
	//!   SetDiffuseFresnelIntensity<br>
	//!   SetDiffuseRLHardness<br>
	//!   SetDiffuseRLScale<br>
	//!   SetSpecularColor<br>
	//!   SetSpecularHardness<br>
	//!   SetSpecularScale<br>
	//!   SetSpecularCTFresnel<br>
	//!   SetSpecularCTRoughness<br>
	//!   SetReflectTint<br>
	//!   SetReflectIntensity<br>
	//!   SetReflectBias<br>
	//!   SetReflectExprosure<br>
	//!   SetReflectScale<br>
	//!   SetEmissiveColor<br>
	//!   SetEmissiveScale<br>
	//!   SetBumpHeightScale<br>
	//!   SetBumpSampleCount<br>
	//!   SetBumpReflectFactor<br>
	//!   SetWaveUVOffset<br>
	//!   SetRefractIntensity<br>
	//!   SetSoftParticleThickness<br>
	//! </ul>
	class IDefaultMaterial : public Mix::Scene::IMaterial
	{
	public:
		//! @enum SHADER_TYPE
		//! @brief シェーダータイプ列挙定数
		enum SHADER_TYPE
		{
			SHADER_NORMAL		= 0,	//!< 通常
			SHADER_WATER		= 1,	//!< ウォーター
			SHADER_SHADELESS	= 2,	//!< シェードレス
		};

		//! @enum DIFFUSE_TYPE
		//! @brief ディフューズタイプ列挙定数
		enum DIFFUSE_TYPE
		{
			DIFFUSE_LAMBERT			= 0,	//!< ランバート
			DIFFUSE_HALF_LAMBERT	= 1,	//!< ハーフランバート
		};

		//! @enum SPECULAR_TYPE
		//! @brief スペキュラータイプ列挙定数
		enum SPECULAR_TYPE
		{
			SPECULAR_NONE			= 0,	//!< 無し
			SPECULAR_PHONG			= 1,	//!< フォン
			SPECULAR_BLINN_PHONG	= 2,	//!< ブリンフォン
			SPECULAR_COOKTORRANCE	= 3,	//!< クックトランス
		};

		//! @enum REFLECT_TYPE
		//! @brief 反射タイプ列挙定数
		enum REFLECT_TYPE
		{
			REFLECT_NONE		= 0,	//!< 無し
			REFLECT_NORMAL		= 1,	//!< 通常
			REFLECT_FRESNEL		= 2,	//!< フレネル
		};

		//! @enum BUMP_TYPE
		//! @brief ンプタイプ列挙定数
		enum BUMP_TYPE
		{
			BUMP_NORMAL		= 0,		//!< 法線マッピング
			BUMP_PARALLAX	= 1,		//!< 視差遮断マッピング
		};

		//! @enum WAVE_TYPE
		//! @brief ウェーブタイプ列挙定数
		enum WAVE_TYPE
		{
			WAVE_NORMAL		= 0,	//!< 通常
			WAVE_REFRACT	= 1,	//!< 屈折効果
		};

		//! @enum WAVE_DIR
		//! @brief ウェーブ方向列挙定数
		enum WAVE_DIR
		{
			WAVE_NEGATIVE_U = 0,	//!< テクスチャ空間の左方向
			WAVE_POSITIVE_U = 1,	//!< テクスチャ空間の右方向
			WAVE_NEGATIVE_V = 2,	//!< テクスチャ空間の上方向
			WAVE_POSITIVE_V = 3,	//!< テクスチャ空間の下方向
		};

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

	public:
		//! @brief 名前を取得します
		//! @return 名前を返します
		virtual const wchar_t* GetName( void ) const = 0;

		//! @brief シェーダータイプを取得します
		//! @return シェーダータイプを表す Mix::Scene::IDefaultMaterial::SHADER_TYPE 列挙定数を返します
		virtual Mix::Scene::IDefaultMaterial::SHADER_TYPE GetShaderType( void ) const = 0;

		//! @brief ブレンドタイプを取得します
		//! @return ブレンドタイプを表す Mix::Graphics::BLEND_TYPE 列挙定数を返します
		virtual Mix::Graphics::BLEND_TYPE GetBlendType( void ) const = 0;
		//! @brief ブレンドタイプを設定します
		//! @param[in] type ブレンドタイプを表す Mix::Graphics::BLEND_TYPE 列挙定数
		virtual void SetBlendType( Mix::Graphics::BLEND_TYPE type ) = 0;

		//! @brief カリングタイプを取得します
		//! @return カリングタイプを表す Mix::Graphics::CULL_TYPE 列挙定数を返します
		virtual Mix::Graphics::CULL_TYPE GetCullingType( void ) const = 0;
		//! @brief カリングタイプを設定します
		//! @param[in] type カリングタイプを表す Mix::Graphics::CULL_TYPE 列挙定数
		virtual void SetCullingType( Mix::Graphics::CULL_TYPE type ) = 0;

		//! @brief 深度を書き込むかどうかを確認します
		//! @return 深度を書き込む場合は True を返します
		virtual Boolean IsZWrite( void ) const = 0;
		//! @brief 深度を書き込むかどうかを確認します
		//! @param[in] state 深度を書き込む場合は True
		virtual void SetZWrite( Boolean state ) = 0;

		//! @brief テクスチャフィルターを取得します
		//! @return テクスチャフィルターを表す Mix::Graphics::TEXTURE_FILTER 列挙定数を返します
		virtual Mix::Graphics::TEXTURE_FILTER_TYPE GetTextureFilterType( void ) const = 0;
		//! @brief テクスチャフィルターを設定します
		//! @param[in] filter テクスチャフィルターを表す Mix::Graphics::TEXTURE_FILTER_TYPE 列挙定数
		virtual void SetTextureFilterType( Mix::Graphics::TEXTURE_FILTER_TYPE filter ) = 0;

		//! @brief テクスチャ座標の解決方法を取得します
		//! @return Mix::Graphics::TEXTURE_ADDRESS テクスチャ座標の解決方法を表す Mix::Graphics::TEXTURE_ADDRESS 列挙定数を返します
		virtual Mix::Graphics::TEXTURE_ADDRESS_TYPE GetTextureAddressType( void ) const = 0;
		//! @brief テクスチャ座標の解決方法を設定します
		//! @param[in] address テクスチャ座標の解決方法を表す Mix::Graphics::TEXTURE_ADDRESS_TYPE 列挙定数
		virtual void SetTextureAddressType( Mix::Graphics::TEXTURE_ADDRESS_TYPE address ) = 0;

		//! @brief 両面ライティングかどうかを確認します
		//! @return 両面ライティングの場合は True を返します
		virtual Boolean IsBothFacesLighting( void ) const = 0;

		//! @brief 自身に影を落とすかどうかを確認します
		//! @return 自身に影を落とす場合は True
		virtual Boolean IsReceiveShadow( void ) const = 0;
		//! @brief 他者に影を落とすかどうかを確認します
		//! @return 他者に影を落とす場合は True
		virtual Boolean IsCastShadow( void ) const = 0;

		//! @brief アンビエントカラーを取得します
		//! @return アンビエントカラーを表す Mix::Vector4 クラスを返します
		virtual const Mix::Vector4& GetAmbientColor( void ) const = 0;
		//! @brief アンビエントカラーを設定します
		//! @param[in] color アンビエントカラー( rgb=色 )
		virtual void SetAmbientColor( const Mix::Vector4& color ) = 0;

		//! @brief ディフューズタイプを取得します
		//! @return ディフューズタイプを表す Mix::Scene::IDefaultMaterial::DIFFUSE_TYPE 列挙定数を返します
		virtual Mix::Scene::IDefaultMaterial::DIFFUSE_TYPE GetDiffuseType( void ) const = 0;
		//! @brief ディフューズカラーを取得します
		//! @return ディフューズカラーを表す Mix::Vector4 クラスを返します
		virtual const Mix::Vector4& GetDiffuseColor( void ) const = 0;
		//! @brief ディフューズカラーを設定します
		//! @param[in] color ディフューズカラー( rgb=色 a=不透明度 )
		virtual void SetDiffuseColor( const Mix::Vector4& color ) = 0;
		//! @brief ディフューズテクスチャを取得します
		//! @param[out] ppTexture 取得したディフューズテクスチャを渡す Mix::Graphics::ITexture インターフェースのポインタのアドレス
		//! @return 取得に成功した場合は True を返します
		virtual Boolean GetDiffuseTexture( Mix::Graphics::ITexture** ppTexture ) = 0;
		//! @brief ディフューズテクスチャを設定します
		//! @param[in] pTexture 設定するディフューズテクスチャを表す Mix::Graphics::ITexture インターフェースのポインタ
		//! @return 成功した場合は True を返します
		//! @note
		//! 成功した場合は、ディフューズテクスチャの参照カウンタを +1 します。<br>
		//! 失敗した場合は、シェーダーがディフューズテクスチャに対応していないことが考えられます。
		virtual Boolean SetDiffuseTexture( Mix::Graphics::ITexture* pTexture ) = 0;
		//! @brief ディフューズにフレネル効果かあるかどうかを取得します
		//! @return フレネル効果がある場合は True を返します
		virtual Boolean IsDiffuseFresnel( void ) const = 0;
		//! @brief ディフューズのフレネル効果の強度を取得します
		//! @return 強度を返します
		virtual Float32 GetDiffuseFresnelIntensity( void ) const = 0;
		//! @brief ディフューズのフレネル効果の強度を設定します
		//! @param[in] intensity 強度( 0.0f〜1.0f )
		virtual void SetDiffuseFresnelIntensity( Float32 intensity ) = 0;
		//! @brief ディフューズのリムライティングが有効かどうかを取得します
		//! @return リムライティングが有効な場合は True を返します
		virtual Boolean IsDiffuseRL( void ) const = 0;
		//! @brief ディフューズのリムライティングの鋭さを取得します
		//! @return リムライティングの鋭さを返します
		virtual Float32 GetDiffuseRLHardness( void ) const = 0;
		//! @brief ディフューズのリムライティングの鋭さを設定します
		//! @param[in] hardness 鋭さ( 0.01f以上 )
		virtual void SetDiffuseRLHardness( Float32 hardness ) = 0;
		//! @brief ディフューズのリムライティングのスケールを取得します
		//! @return リムライティングのスケールを返します
		virtual Float32 GetDiffuseRLScale( void ) const = 0;
		//! @brief ディフューズのリムライティングのスケールを設定します
		//! @param[in] scale( 0.0f以上 )
		virtual void SetDiffuseRLScale( Float32 scale ) = 0;

		//! @brief スペキュラーのタイプを取得します
		//! @return スペキュラーのタイプを表す Mix::Scene::IStandardMaterial::SPECULAR_TYPE 列挙定数を返します
		virtual Mix::Scene::IDefaultMaterial::SPECULAR_TYPE GetSpecularType( void ) const = 0;
		//! @brief スペキュラーカラーを取得します
		//! @return スペキュラーカラーを表す Mix::Vector4 クラスを返します
		virtual const Mix::Vector4& GetSpecularColor( void ) const = 0;
		//! @brief スペキュラーカラーを設定します
		//! @param[in] color スペキュラーカラーを表す Mix::Vector4 クラス( rgb=色 a=1.0f )
		virtual void SetSpecularColor( const Mix::Vector4& color ) = 0;
		//! @brief スペキュラーテクスチャを取得します
		//! @param[out] ppTexture 取得したスペキュラーテクスチャを渡す Mix::Graphics::ITexture インターフェースのポインタのアドレス
		//! @return 取得に成功した場合は True を返します
		virtual Boolean GetSpecularTexture( Mix::Graphics::ITexture** ppTexture ) = 0;
		//! @brief スペキュラーテクスチャを設定します
		//! @param[in] pTexture 設定するスペキュラーテクスチャを表す Mix::Graphics::ITexture インターフェースのポインタ
		//! @return 成功した場合は True を返します
		//! @note
		//! 成功した場合は、スペキュラーテクスチャの参照カウンタを +1 します。<br>
		//! 失敗した場合は、シェーダーがスペキュラーテクスチャに対応していないことが考えられます。
		virtual Boolean SetSpecularTexture( Mix::Graphics::ITexture* pTexture ) = 0;
		//! @brief スペキュラーの鋭さを取得します
		//! @return 鋭さを返します
		virtual Float32 GetSpecularHardness( void ) const = 0;
		//! @brief スペキュラーの鋭さを設定します
		//! @param[in] hardness 鋭さ( 0.01f以上 )
		virtual void SetSpecularHardness( Float32 hardness ) = 0;
		//! @brief スペキュラーのスケールを取得します
		//! @return スケールを返します
		virtual Float32 GetSpecularScale( void ) const = 0;
		//! @brief スペキュラーのスケールを設定します
		//! @param[in] scale スケール( 0.0f〜1.0f )
		virtual void SetSpecularScale( Float32 scale ) = 0;
		//! @brief スペキュラー( クックトランス )の反射強度を取得します
		//! @return 反射強度を返します
		virtual Float32 GetSpecularCTFresnel( void ) const = 0;
		//! @brief スペキュラー( クックトランス )の反射強度を設定します
		//! @param[in] fresnel 反射強度( 0.01f以上 )
		virtual void SetSpecularCTFresnel( Float32 fresnel ) = 0;
		//! @brief スペキュラー( クックトランス )の粗さを設定します
		//! @return 粗さを返します
		virtual Float32 GetSpecularCTRoughness( void ) const = 0;
		//! @brief スペキュラー( クックトランス )の粗さを設定します
		//! @param[in] roughness 粗さ( 0.0f〜1.0f )
		virtual void SetSpecularCTRoughness( Float32 roughness ) = 0;

		//! @brief 反射タイプを取得します
		//! @return 反射タイプを表す Mix::Scene::IStandardMaterial::REFLECT_TYPE 列挙定数を返します
		virtual Mix::Scene::IDefaultMaterial::REFLECT_TYPE GetReflectType( void ) const = 0;
		//! @brief 反射のスケールを取得します
		//! @return スケールを返します
		virtual Float32 GetReflectScale( void ) const = 0;
		//! @brief 反射のスケールを設定します
		//! @param[in] scale スケール( 0.0f以上 )
		virtual void SetReflectScale( Float32 scale ) = 0;
		//! @brief 反射の強さを取得します
		//! @return 反射の強さを返します
		virtual Float32 GetReflectIntensity( void ) const = 0;
		//! @brief 反射の強さを設定します
		//! @param[in] intensity 反射の強さ( 0.0f〜1.0f )
		virtual void SetReflectIntensity( Float32 intensity ) = 0;
		//! @brief 反射のバイアスを取得します
		//! @return 反射のバイアスを返します
		virtual Float32 GetReflectBias( void ) const = 0;
		//! @brief 反射のバイアスを設定します
		//! @param[in] bias 反射のバイアス( 0.0f〜1.0f )
		virtual void SetReflectBias( Float32 bias ) = 0;
		//! @brief 反射の露光を取得します
		//! @return 反射の露光を返します
		virtual Float32 GetReflectExprosure( void ) const = 0;
		//! @brief 反射の露光を設定します
		//! @param[in] exprosure 反射の露光( 0.0f〜1.0f )
		virtual void SetReflectExprosure( Float32 exprosure ) = 0;

		//! @brief エミッシブのカラーを取得します
		//! @return カラーを表す Mix::Vector4 クラスを返します
		virtual const Mix::Vector4& GetEmissiveColor( void ) const = 0;
		//! @brief エミッシブのカラーを設定します
		//! @param[in] color カラーを表す Mix::Vector4 クラス( rgb=色 a=スケール )
		virtual void SetEmissiveColor( const Mix::Vector4& color ) = 0;
		//! @brief エミッシブのスケールを取得します
		//! @return スケールを返します
		virtual Float32 GetEmissiveScale( void ) const = 0;
		//! @brief エミッシブのスケールを設定します
		//! @param[in] scale スケール
		virtual void SetEmissiveScale( Float32 scale ) = 0;
		//! @brief エミッシブテクスチャを取得します
		//! @param[out] ppTexture 取得したエミッシブテクスチャを渡す Mix::Graphics::ITexture インターフェースのポインタのアドレス
		//! @return 取得に成功した場合は True を返します
		virtual Boolean GetEmissiveTexture( Mix::Graphics::ITexture** ppTexture ) = 0;
		//! @brief エミッシブテクスチャを設定します
		//! @param[in] pTexture 設定するエミッシブテクスチャを表す Mix::Graphics::ITexture インターフェースのポインタ
		//! @return 成功した場合は True を返します
		//! @note
		//! 成功した場合は、エミッシブテクスチャの参照カウンタを +1 します。<br>
		//! 失敗した場合は、シェーダーがエミッシブテクスチャに対応していないことが考えられます。
		virtual Boolean SetEmissiveTexture( Mix::Graphics::ITexture* pTexture ) = 0;

		//! @brief バンプかどうかを確認します
		//! @return バンプが有効な場合は True を返します
		virtual Boolean IsBump( void ) const = 0;
		//! @brief バンプの種類を取得します
		//! @return バンプの種類を表す Mix::Scene::IStandardMaterial::BUMP_TYPE 列挙定数を返します
		virtual Mix::Scene::IDefaultMaterial::BUMP_TYPE GetBumpType( void ) const = 0;
		//! @brief バンプテクスチャを取得します
		//! @param[out] ppTexture 取得したバンプテクスチャを渡す Mix::Graphics::ITexture インターフェースのポインタのアドレス
		//! @return 取得に成功した場合は True を返します
		virtual Boolean GetBumpTexture( Mix::Graphics::ITexture** ppTexture ) = 0;
		//! @brief バンプテクスチャを設定します
		//! @param[in] pTexture 設定するバンプテクスチャを表す Mix::Graphics::ITexture インターフェースのポインタ
		//! @return 成功した場合は True を返します
		//! @note
		//! 成功した場合は、バンプテクスチャの参照カウンタを +1 します。<br>
		//! 失敗した場合は、シェーダーがバンプテクスチャに対応していないことが考えられます。
		virtual Boolean SetBumpTexture( Mix::Graphics::ITexture* pTexture ) = 0;
		//! @brief バンプのヘイトスケールを取得します
		//! @return ヘイトスケールを返します
		virtual Float32 GetBumpHeightScale( void ) const = 0;
		//! @brief バンプのヘイトスケールを設定します
		//! @param[in] scale ヘイトスケール( 0.0f〜1.0f )
		virtual void SetBumpHeightScale( Float32 scale ) = 0;
		//! @brief バンプのサンプル数を取得します
		//! @return サンプル数を返します
		virtual Int32 GetBumpSampleCount( void ) const = 0;
		//! @brief バンプのサンプル数を設定します
		//! @param[in] sampleCount サンプル数( 1〜8 )
		virtual void SetBumpSampleCount( Int32 sampleCount ) = 0;
		//! @brief バンプの反射への影響度を取得します
		//! @return 反射への影響度を返します
		virtual Float32 GetBumpReflectFactor( void ) const = 0;
		//! @brief バンプの反射への影響度を設定します
		//! @param[in] factor 反射への影響度( 0.0f〜1.0f )
		virtual void SetBumpReflectFactor( Float32 factor ) = 0;

		//! @brief ウェーブをするかどうかを確認します
		//! @return ウェーブをする場合は True を返します
		virtual Boolean IsWave( void ) const = 0;
		//! @brief ウェーブのタイプを取得します
		//! @return タイプを表す Mix::Scene::IDefaultMaterial::WAVE_TYPE 列挙定数を返します
		virtual Mix::Scene::IDefaultMaterial::WAVE_TYPE GetWaveType( void ) const = 0;
		//! @brief ウェーブの方向を取得します
		//! @return 方向を表す Mix::Scene::IDefaultMaterial::WAVE_DIR 列挙定数を返します
		virtual Mix::Scene::IDefaultMaterial::WAVE_DIR GetWaveDir( void ) const = 0;
		//! @brief ウェーブの方向を設定します
		//! @param[in] dir 方向を表す Mix::Scene::IDefaultMaterial::WAVE_DIR 列挙定数
		virtual void SetWaveDir( Mix::Scene::IDefaultMaterial::WAVE_DIR dir ) = 0;
		//! @brief ウェーブのペアの方向を逆転しているかどうかを確認します
		//! @return 逆転している場合は True を返します
		virtual Boolean IsWaveInvert( void ) const = 0;
		//! @brief ウェーブの速度(毎秒)を取得します
		//! @return 速度を返します
		virtual Float32 GetWaveVelocity( void ) const = 0;
		//! @brief ウェーブの速度(毎秒)を設定します
		//! @param[in] vel 速度( 0.0f〜1.0f )
		virtual void SetWaveVelocity( Float32 vel ) = 0;
		//! @brief ウェーブのペアのUVオフセットを取得します
		//! @return UVオフセットを返します
		virtual Float32 GetWaveUVOffset( void ) const = 0;
		//! @brief ウェーブのペアのUVオフセットを設定します
		//! @param[in] uvOffset UVオフセット( 0.0f〜1.0f )
		virtual void SetWaveUVOffset( Float32 uvOffset ) = 0;
		//! @brief ウェーブのペアとの相対速度を取得します
		//! @return ずれを返します
		virtual Float32 GetWaveGap( void ) const = 0;
		//! @brief ウェーブのペアとの相対速度を設定します
		//! @param[in] gap ずれ( 0 以上 )
		virtual void SetWaveGap( Float32 gap ) = 0;
		//! @brief ウェーブの屈折率を取得します
		//! @return 屈折強度を返します
		virtual Float32 GetWaveRefractiveIndex( void ) const = 0;
		//! @brief ウェーブの屈折率を設定します
		//! @param[in] index 屈折率( 0.0f〜1.0f )
		virtual void SetWaveRefractiveIndex( Float32 index ) = 0;

		//! @brief ソフトパーティクルかどうかを確認します
		//! @return ソフトパーティクルの場合は True を返します
		virtual Boolean IsSoftParticle( void ) const = 0;
		//! @brief ソフトパーティクルの厚みを取得します
		//! @return ソフトパーティクルの厚みを返します
		virtual Float32 GetSoftParticleThickness( void ) const = 0;
		//! @brief ソフトパーティクルの厚みを設定します
		//! @param[in] tickness ソフトパーティクルの厚み( 0.0f以上 )
		virtual void SetSoftParticleThickness( Float32 tickness ) = 0;
	};

}}
