#pragma once

#include "Mix/Private/Scene/Standard/Common/DefaultMaterial.h"

namespace Mix{ namespace Scene{ namespace Standard{ namespace DX11{

	class DefaultMaterial : public Mix::Scene::Standard::Common::DefaultMaterial
	{
	private:
		enum PSR
		{
			//////////////////////////////

			PSCB_SLOT			= 3,	//定数バッファのレジスタ番号

			//////////////////////////////

			DIFFUSE_PI_FI		= 0,
			DIFFUSE_PI_RL_H		= 1,
			DIFFUSE_PI_RL_S		= 2,

			SPECULAR_PI0_H		= 0,
			SPECULAR_PI0_S		= 1,

			SPECULAR_PI1_CT_F	= 0,
			SPECULAR_PI1_CT_RI	= 1,
			SPECULAR_PI1_CT_R2	= 2,

			REFLECT_PI_S		= 0,
			REFLECT_PI_I		= 1,
			REFLECT_PI_B		= 2,
			REFLECT_PI_E		= 3,

			EMISSIVE_PI_S		= 0,

			BUMP_PI0_HS			= 0,
			BUMP_PI0_SC			= 1,
			BUMP_PI0_RL_F		= 2,
			BUMP_PI0_WAVE_O		= 3,

			BUMP_PI1_WAVE_U		= 0,
			BUMP_PI1_WAVE_V		= 1,
			BUMP_PI1_WAVE_G		= 2,
			BUMP_PI1_RR_I		= 3,

			PARTICLE_PI_T		= 0,

			//////////////////////////////
		};

		struct PS
		{
			Mix::Vector4 ambientColor;		//アンビエント( XYZ=RGB )
			Mix::Vector4 diffuseColor;		//ディフューズ( XYZW=RGBA )
			Mix::Vector4 diffuseParam;		//ディフューズ( X=FresnelRatio Y=RLHardness Z=RLScale )
			Mix::Vector4 specularColor;		//スペキュラー( XYZ=RGB W=Intensity )
			Mix::Vector4 specularParam0;	//スペキュラー( X=Hardness Y=Scale )
			Mix::Vector4 specularParam1;	//スペキュラー( X=CT_Fresnel Y=CT_RoughnessInv Z=CT_Roughness2 )
			Mix::Vector4 reflectParam;		//リフレクト( X=Scale Y=Intensity Z=Bias W=Exprosure )
			Mix::Vector4 emissiveColor;		//エミッシブ( XYZW=RGBA )
			Mix::Vector4 emissiveParam;		//エミッシブ( X=Scale )
			Mix::Vector4 bumpParam0;		//バンプ( X=HeightScale Y=HeightSample Z=ReflectRatio W=WaveOffset )
			Mix::Vector4 bumpParam1;		//バンプ( XY=WavwUV Z=RefractRatio )
			Mix::Vector4 particleParam;		//パーティクル( X=SodtCoiffe )
		};

		Float32 m_SpecularCTRoughness;

		Mix::Scene::Standard::DX11::DefaultMaterial::PS m_PS;
		Mix::Graphics::IShaderConstant* m_pConstantPS;
		Boolean m_bValidConstantPS;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::Standard::Standard::DX9::DefaultMaterial
		////////////////////////////////////////////////////////////////////////////////////////////////////

	public:
		static DefaultMaterial* CreateInstance(	Mix::Graphics::IDevice* pDevice,
												Mix::Scene::Common::EffectPackage* pEffectPackage,
												Mix::IO::IReader* pReader,
												Boolean bWithMagicNumber,
												const wchar_t* pNameLabel,
												const wchar_t* pName );

	private:
		DefaultMaterial( void );
		virtual ~DefaultMaterial( void );

		Boolean Initialize( const wchar_t* pName, Mix::Graphics::IDevice* pDevice );
		void UpdateConstantPS( void );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::IDefaultMaterial
		////////////////////////////////////////////////////////////////////////////////////////////////////

	public:
		virtual const Mix::Vector4& GetAmbientColor( void ) const;
		virtual void SetAmbientColor( const Mix::Vector4& color );

		virtual const Mix::Vector4& GetDiffuseColor( void ) const;
		virtual void SetDiffuseColor( const Mix::Vector4& color );
		virtual Float32 GetDiffuseFresnelIntensity( void ) const;
		virtual void SetDiffuseFresnelIntensity( Float32 intensity );
		virtual Float32 GetDiffuseRLHardness( void ) const;
		virtual void SetDiffuseRLHardness( Float32 hardness );
		virtual Float32 GetDiffuseRLScale( void ) const;
		virtual void SetDiffuseRLScale( Float32 scale );

		virtual const Mix::Vector4& GetSpecularColor( void ) const;
		virtual void SetSpecularColor( const Mix::Vector4& color );
		virtual Float32 GetSpecularHardness( void ) const;
		virtual void SetSpecularHardness( Float32 hardness );
		virtual Float32 GetSpecularScale( void ) const;
		virtual void SetSpecularScale( Float32 scale );
		virtual Float32 GetSpecularCTFresnel( void ) const;
		virtual void SetSpecularCTFresnel( Float32 fresnel );
		virtual Float32 GetSpecularCTRoughness( void ) const;
		virtual void SetSpecularCTRoughness( Float32 roughness );

		virtual Float32 GetReflectScale( void ) const;
		virtual void SetReflectScale( Float32 scale );
		virtual Float32 GetReflectIntensity( void ) const;
		virtual void SetReflectIntensity( Float32 intensity );
		virtual Float32 GetReflectBias( void ) const;
		virtual void SetReflectBias( Float32 bias );
		virtual Float32 GetReflectExprosure( void ) const;
		virtual void SetReflectExprosure( Float32 exprosure );

		virtual const Mix::Vector4& GetEmissiveColor( void ) const;
		virtual void SetEmissiveColor( const Mix::Vector4& color );
		virtual Float32 GetEmissiveScale( void ) const;
		virtual void SetEmissiveScale( Float32 scale );

		virtual Float32 GetBumpHeightScale( void ) const;
		virtual void SetBumpHeightScale( Float32 scale );
		virtual Int32 GetBumpSampleCount( void ) const;
		virtual void SetBumpSampleCount( Int32 sampleCount );
		virtual Float32 GetBumpReflectFactor( void ) const;
		virtual void SetBumpReflectFactor( Float32 factor );

		virtual Float32 GetWaveUVOffset( void ) const;
		virtual void SetWaveUVOffset( Float32 uvOffset );
		virtual Float32 GetWaveGap( void ) const;
		virtual void SetWaveGap( Float32 gap );
		virtual Float32 GetWaveRefractiveIndex( void ) const;
		virtual void SetWaveRefractiveIndex( Float32 index );

		virtual Float32 GetSoftParticleThickness( void ) const;
		virtual void SetSoftParticleThickness( Float32 tickness );

		////////////////////////////////////////////////////////////////////////////////////////////////////
		// Mix::Scene::IMaterial
		////////////////////////////////////////////////////////////////////////////////////////////////////

		virtual void Update( Float32 dt );

		virtual void RenderShadow( Mix::Graphics::IDevice* pDevice, Mix::Scene::IMaterial::TRANSFORM_TYPE trType );
		virtual void RenderColor( Mix::Graphics::IDevice* pDevice, Mix::Scene::IMaterial::TRANSFORM_TYPE trType );

		virtual Boolean BeginConstant( void );
		virtual Boolean EndConstant( void );

		virtual Boolean Clone( Mix::Scene::IMaterial** ppMaterial );
	};

}}}}
