#pragma once

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

#include "Mix/Reference.h"

namespace Mix{ namespace Scene{

	//! @class IMaterial
	//! @brief マテリアルインターフェース
	class IMaterial : public Mix::Reference
	{
	public:
		//! @enum TYPE
		//! @brief タイプ列挙定数
		enum TYPE
		{
			DEFAULT	= 0,	//!< デフォルト( Mix::Scene::IDefaultMaterial )
		};

		//! @enum TRANSFORM_TYPE
		//! @brief トランスフォームタイプ列挙定数
		enum TRANSFORM_TYPE
		{
			TR_SIMPLE	= 0,	//!< モデルに設定されているワールド行列でトランスフォーム
			TR_SKINNING	= 1,	//!< ボーンのワールド行列でトランスフォーム

			TR_MAX		= 2,	//!< トランスフォームタイプの最大数
		};

		//! @enum TRANSPARENCY_METHOD
		//! @brief 半透明メソッド列挙定数
		enum TRANSPARENCY_METHOD
		{
			TM_LUMP			= 0,	//!< 一括描画
			TM_INDIVIDUAL	= 1,	//!< ポリゴン単位描画
		};

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

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

		//! @brief 指定したタイプのトランスフォームを実行できるかどうかを確認します
		//! @return 実行できる場合は True を返します
		virtual Boolean IsTransformable( Mix::Scene::IMaterial::TRANSFORM_TYPE type ) const = 0;

		//! @brief １頂点のサイズを取得します
		//! @return サイズを返します
		virtual UInt32 GetVertexStride( Mix::Scene::IMaterial::TRANSFORM_TYPE type ) const = 0;
		//! @brief 頂点の入力シグネチャを取得します
		//! @return Mix::Graphics::IVertexLayout::GetElementSemanticFlags で取得できる値を返します
		virtual UInt32 GetVertexInputSigunature( Mix::Scene::IMaterial::TRANSFORM_TYPE type ) const = 0;

		//! @brief 更新( Update )が必要かどうかを確認します
		//! @return 必要な場合は True を返します
		virtual Boolean NeedsUpdate( void ) const = 0;

		//! @brief 影を落とすかどうかを確認します
		//! @return 影を落とす場合は True を返します
		//! @note このメソッドが True を返す場合は RenderShadow が実行されます。
		virtual Boolean IsShadowing( void ) const = 0;
		//! @brief ライティングをするかどうかを確認します
		//! @return ライティングをする場合は True を返します
		//! @note このメソッドが True を返す場合は ポイントライト、スポットライトの収集をします。
		virtual Boolean IsLighting( void ) const = 0;
		//! @brief 屈折するかどうかを確認します
		//! @return 屈折する場合は True を返します
		//! @note このメソッドが True を返す場合は RenderMask RenderColor が実行されます。
		virtual Boolean IsRefractive( void ) const = 0;
		//! @brief 不透明かどうかを確認します
		//! @return 不透明である場合は True を返します
		//! @note このメソッドが True を返す場合は 半透明として処理します。
		virtual Boolean IsTransparency( void ) const = 0;
		//! @brief 不透明メソッドを取得します
		//! @return 不透明メソッドを表す Mix::Scene::IDefaultMaterial::TRANSPARENCY_METHOD 列挙定数を返します
		virtual Mix::Scene::IMaterial::TRANSPARENCY_METHOD GetTransparencyMethod( void ) const = 0;

		//! @brief 更新される際の呼び出されます
		//! @param[in] dt デルタタイム
		virtual void Update( Float32 dt ) = 0;

		//! @brief 影の描画設定をします
		//! @param[in] pDevice グラフックスデバイスを表す Mix::Graphics::IDevice インターフェースのポインタ
		//! @param[in] trType トランスフォームタイプを表す Mix::Scene::IMaterial::TRANSFORM_TYPE 列挙定数
		virtual void RenderShadow( Mix::Graphics::IDevice* pDevice, Mix::Scene::IMaterial::TRANSFORM_TYPE trType ) = 0;
		//! @brief マスクの描画設定をします
		//! @param[in] pDevice グラフックスデバイスを表す Mix::Graphics::IDevice インターフェースのポインタ
		//! @param[in] trType トランスフォームタイプを表す Mix::Scene::IMaterial::TRANSFORM_TYPE 列挙定数
		virtual void RenderMask( Mix::Graphics::IDevice* pDevice, Mix::Scene::IMaterial::TRANSFORM_TYPE trType ) = 0;
		//! @brief カラーの描画設定をします
		//! @param[in] pDevice グラフックスデバイスを表す Mix::Graphics::IDevice インターフェースのポインタ
		//! @param[in] trType トランスフォームタイプを表す Mix::Scene::IMaterial::TRANSFORM_TYPE 列挙定数
		virtual void RenderColor( Mix::Graphics::IDevice* pDevice, Mix::Scene::IMaterial::TRANSFORM_TYPE trType ) = 0;

		//! @brief 定数の変更を開始します
		//! @return 変更の開始が成功した場合は True を返します
		//! @note
		//! 複数のパラメータを変更する際に、BeginConstant EndConstant で括ることで、<br>
		//! シェーダー定数( Mix::Graphics::IShaderConstant )のロックを減らし、パフォーマンスを向上させることができます。<br>
		//! またこの処理は、シェーダーモデル４、５に対して有効です。
		virtual Boolean BeginConstant( void ) = 0;
		//! @brief 定数の変更を終了します
		//! @return 変更の終了が成功した場合は True を返します
		virtual Boolean EndConstant( void ) = 0;

		//! @brief 自身のクローンを作成します
		//! @param[out] ppMaterial 自身のクローンを渡す Mix::Scene::IMaterial インターフェースのポインタのアドレス
		//! @return 成功した場合は True を返します
		virtual Boolean Clone( Mix::Scene::IMaterial** ppMaterial ) = 0;
	};

}}
