#pragma once

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

namespace Mix{ namespace Scene{ namespace Standard{ namespace DX9{

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

			PSR_HEAD				= 68,
			PSR_NUM					= 12,

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

			PSR_AMBIENT_COLOR		= 0,

			PSR_DIFFUSE_COLOR		= 1,

			PSR_DIFFUSE_PARAM		= 2,
			PSR_DIFFUSE_PI_FI		= 0,
			PSR_DIFFUSE_PI_RL_H		= 1,
			PSR_DIFFUSE_PI_RL_S		= 2,

			PSR_SPECULAR_COLOR		= 3,

			PSR_SPECULAR_PARAM0		= 4,
			PSR_SPECULAR_PI0_H		= 0,
			PSR_SPECULAR_PI0_S		= 1,

			PSR_SPECULAR_PARAM1		= 5,
			PSR_SPECULAR_PI1_CT_F	= 0,
			PSR_SPECULAR_PI1_CT_RI	= 1,
			PSR_SPECULAR_PI1_CT_R2	= 2,

			PSR_REFLECT_PARAM	= 6,
			PSR_REFLECT_PI_S	= 0,
			PSR_REFLECT_PI_I	= 1,
			PSR_REFLECT_PI_B	= 2,
			PSR_REFLECT_PI_E	= 3,

			PSR_EMISSIVE_COLOR	= 7,
			PSR_EMISSIVE_PARAM	= 8,
			PSR_EMISSIVE_PI_S	= 0,

			PSR_BUMP_PARAM0		= 9,
			PSR_BUMP_PI0_HS		= 0,
			PSR_BUMP_PI0_SC		= 1,
			PSR_BUMP_PI0_RL_F	= 2,
			PSR_BUMP_PI0_WAVE_O	= 3,

			PSR_BUMP_PARAM1		= 10,
			PSR_BUMP_PI1_WAVE_U	= 0,
			PSR_BUMP_PI1_WAVE_V	= 1,
			PSR_BUMP_PI1_WAVE_G	= 2,
			PSR_BUMP_PI1_RR_I	= 3,

			PSR_PARTICLE_PARAM	= 11,
			PSR_PARTICLE_PI_T	= 0,

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

		Float32 m_SpecularCTRoughness;
		Mix::Vector4 m_PSR[PSR_NUM];

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

		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:
		virtual ~DefaultMaterial( 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 ) { return True; }
		virtual Boolean EndConstant( void ) { return True; }

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

}}}}
