#include "Mix/Tool/CLR/Core/Graphics/Material.h"

namespace Mix{ namespace Tool{ namespace Graphics{

////////////////////////////////////////////////////////////////////////////////////////////////////
// Material::TextureMapping
////////////////////////////////////////////////////////////////////////////////////////////////////

Material::TextureMappingProperty::TextureMappingProperty( Mix::Tool::Win32::Graphics::Material* _impl ) :
impl( _impl )
{
}

Material::TextureMappingProperty::~TextureMappingProperty( void )
{
	impl = nullptr;
}

Mix::Tool::Graphics::TextureFilterTypes Material::TextureMappingProperty::FilterType::get( void )
{
	Mix::Tool::Graphics::TextureFilterTypes type;

	switch( impl->GetTextureFilterType() )
	{
	case D3DTEXF_POINT:
		type = Mix::Tool::Graphics::TextureFilterTypes::Point;
		break;
	case D3DTEXF_LINEAR:
		type = Mix::Tool::Graphics::TextureFilterTypes::Linear;
		break;
	case D3DTEXF_ANISOTROPIC:
		type = Mix::Tool::Graphics::TextureFilterTypes::Anisotropic;
		break;
	}

	return type;
}

void Material::TextureMappingProperty::FilterType::set( Mix::Tool::Graphics::TextureFilterTypes value )
{
	D3DTEXTUREFILTERTYPE type;

	switch( value )
	{
	case Mix::Tool::Graphics::TextureFilterTypes::Point:
		type = D3DTEXF_POINT;
		break;
	case Mix::Tool::Graphics::TextureFilterTypes::Linear:
		type = D3DTEXF_LINEAR;
		break;
	case Mix::Tool::Graphics::TextureFilterTypes::Anisotropic:
		type = D3DTEXF_ANISOTROPIC;
		break;
	}

	impl->SetTextureFilterType( type );
}

Mix::Tool::Graphics::TextureAddressTypes Material::TextureMappingProperty::AddressType::get( void )
{
	Mix::Tool::Graphics::TextureAddressTypes type;

	switch( impl->GetTextureAddressType() )
	{
	case D3DTADDRESS_WRAP:
		type = Mix::Tool::Graphics::TextureAddressTypes::Wrap;
		break;
	case D3DTADDRESS_CLAMP:
		type = Mix::Tool::Graphics::TextureAddressTypes::Clamp;
		break;
	}

	return type;
}

void Material::TextureMappingProperty::AddressType::set( Mix::Tool::Graphics::TextureAddressTypes value )
{
	D3DTEXTUREADDRESS type;

	switch( value )
	{
	case Mix::Tool::Graphics::TextureAddressTypes::Wrap:
		type = D3DTADDRESS_WRAP;
		break;
	case Mix::Tool::Graphics::TextureAddressTypes::Clamp:
		type = D3DTADDRESS_CLAMP;
		break;
	}

	impl->SetTextureAddressType( type );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Material::DiffuseProperty
////////////////////////////////////////////////////////////////////////////////////////////////////

Material::DiffuseProperty::DiffuseProperty( Mix::Tool::Win32::Graphics::Material* _impl ) :
impl( _impl )
{
}

Material::DiffuseProperty::~DiffuseProperty( void )
{
	impl = nullptr;
}

Mix::Tool::Graphics::DiffuseTypes Material::DiffuseProperty::Type::get( void )
{
	Mix::Tool::Graphics::DiffuseTypes type;

	switch( impl->GetDiffuseType() )
	{
	case Mix::Tool::Win32::Graphics::DIFFUSE_LAMBERT:
		type = Mix::Tool::Graphics::DiffuseTypes::Lambert;
		break;
	case Mix::Tool::Win32::Graphics::DIFFUSE_HALF_LAMBERT:
		type = Mix::Tool::Graphics::DiffuseTypes::HalfLambert;
		break;
	}

	return type;
}

void Material::DiffuseProperty::Type::set( Mix::Tool::Graphics::DiffuseTypes value )
{
	Mix::Tool::Win32::Graphics::DIFFUSE_TYPE type;

	switch( value )
	{
	case Mix::Tool::Graphics::DiffuseTypes::Lambert:
		type = Mix::Tool::Win32::Graphics::DIFFUSE_LAMBERT;
		break;
	case Mix::Tool::Graphics::DiffuseTypes::HalfLambert:
		type = Mix::Tool::Win32::Graphics::DIFFUSE_HALF_LAMBERT;
		break;
	}

	impl->SetDiffuseType( type );
}

Mix::Tool::Math::Vector^ Material::DiffuseProperty::Color::get( void )
{
	const D3DXVECTOR4& c = impl->GetDiffuseColor();

	return gcnew Mix::Tool::Math::Vector( c.x, c.y, c.z, c.w );
}

void Material::DiffuseProperty::Color::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetDiffuseColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

System::String^ Material::DiffuseProperty::TextureFileName::get( void )
{
	return gcnew System::String( impl->GetDiffuseTextureFileName() );
}

void Material::DiffuseProperty::LoadTexture( void )
{
	impl->LoadDiffuseTexture();
}

void Material::DiffuseProperty::LoadTexture( System::String^ fileName )
{
	pin_ptr<const wchar_t> wFileName = PtrToStringChars( fileName );
	impl->LoadDiffuseTexture( wFileName );
}

bool Material::DiffuseProperty::Fresnel::get( void )
{
	return impl->GetDiffuseFresnel();
}

void Material::DiffuseProperty::Fresnel::set( bool value )
{
	impl->SetDiffuseFresnel( value );
}

float Material::DiffuseProperty::FresnelRatio::get( void )
{
	return impl->GetDiffuseFresnelRatio();
}

void Material::DiffuseProperty::FresnelRatio::set( float value )
{
	impl->SetDiffuseFresnelRatio( value );
}

bool Material::DiffuseProperty::RimLighting::get( void )
{
	return impl->GetDiffuseRL();
}

void Material::DiffuseProperty::RimLighting::set( bool value )
{
	impl->SetDiffuseRL( value );
}

float Material::DiffuseProperty::RimLightingHardness::get( void )
{
	return impl->GetDiffuseRLHardness();
}

void Material::DiffuseProperty::RimLightingHardness::set( float value )
{
	impl->SetDiffuseRLHardness( value );
}

float Material::DiffuseProperty::RimLightingScale::get( void )
{
	return impl->GetDiffuseRLScale();
}

void Material::DiffuseProperty::RimLightingScale::set( float value )
{
	impl->SetDiffuseRLScale( value );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Material::SpecularProperty
////////////////////////////////////////////////////////////////////////////////////////////////////

Material::SpecularProperty::SpecularProperty( Mix::Tool::Win32::Graphics::Material* _impl ) :
impl( _impl )
{
}

Material::SpecularProperty::~SpecularProperty( void )
{
	impl = nullptr;
}

Mix::Tool::Graphics::SpecularTypes Material::SpecularProperty::Type::get( void )
{
	Mix::Tool::Graphics::SpecularTypes type;

	switch( impl->GetSpecularType() )
	{
	case Mix::Tool::Win32::Graphics::SPECULAR_NONE:
		type = Mix::Tool::Graphics::SpecularTypes::None;
		break;
	case Mix::Tool::Win32::Graphics::SPECULAR_PHONG:
		type = Mix::Tool::Graphics::SpecularTypes::Phong;
		break;
	case Mix::Tool::Win32::Graphics::SPECULAR_BLINN_PHONG:
		type = Mix::Tool::Graphics::SpecularTypes::BlinnPhong;
		break;
	case Mix::Tool::Win32::Graphics::SPECULAR_COOK_TORRANCE:
		type = Mix::Tool::Graphics::SpecularTypes::CookTorrance;
		break;
	}

	return type;
}

void Material::SpecularProperty::Type::set( Mix::Tool::Graphics::SpecularTypes value )
{
	Mix::Tool::Win32::Graphics::SPECULAR_TYPE type;

	switch( value )
	{
	case Mix::Tool::Graphics::SpecularTypes::None:
		type = Mix::Tool::Win32::Graphics::SPECULAR_NONE;
		break;
	case Mix::Tool::Graphics::SpecularTypes::Phong:
		type = Mix::Tool::Win32::Graphics::SPECULAR_PHONG;
		break;
	case Mix::Tool::Graphics::SpecularTypes::BlinnPhong:
		type = Mix::Tool::Win32::Graphics::SPECULAR_BLINN_PHONG;
		break;
	case Mix::Tool::Graphics::SpecularTypes::CookTorrance:
		type = Mix::Tool::Win32::Graphics::SPECULAR_COOK_TORRANCE;
		break;
	}

	impl->SetSpecularType( type );
}

Mix::Tool::Math::Vector^ Material::SpecularProperty::Color::get( void )
{
	const D3DXVECTOR4& c = impl->GetSpecularColor();

	return gcnew Mix::Tool::Math::Vector( c.x, c.y, c.z, c.w );
}

void Material::SpecularProperty::Color::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetSpecularColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

System::String^ Material::SpecularProperty::TextureFileName::get( void )
{
	return gcnew System::String( impl->GetSpecularTextureFileName() );
}

void Material::SpecularProperty::LoadTexture( void )
{
	impl->LoadSpecularTexture();
}

void Material::SpecularProperty::LoadTexture( System::String^ fileName )
{
	pin_ptr<const wchar_t> wFileName = PtrToStringChars( fileName );

	impl->LoadSpecularTexture( wFileName );
}

float Material::SpecularProperty::Hardness::get( void )
{
	return impl->GetSpecularHardness();
}

void Material::SpecularProperty::Hardness::set( float value )
{
	impl->SetSpecularHardness( value );
}

float Material::SpecularProperty::Scale::get( void )
{
	return impl->GetSpecularScale();
}

void Material::SpecularProperty::Scale::set( float value )
{
	impl->SetSpecularScale( value );
}

float Material::SpecularProperty::CookTorranceFresnel::get( void )
{
	return impl->GetSpecularCTFresnel();
}

void Material::SpecularProperty::CookTorranceFresnel::set( float value )
{
	impl->SetSpecularCTFresnel( value );
}

float Material::SpecularProperty::CookTorranceRoughness::get( void )
{
	return impl->GetSpecularCTRoughness();
}

void Material::SpecularProperty::CookTorranceRoughness::set( float value )
{
	impl->SetSpecularCTRoughness( value );
}

Mix::Tool::Graphics::ReflectTypes Material::SpecularProperty::ReflectType::get( void )
{
	Mix::Tool::Graphics::ReflectTypes type;

	switch( impl->GetReflectType() )
	{
	case Mix::Tool::Win32::Graphics::REFLECT_NONE:
		type = Mix::Tool::Graphics::ReflectTypes::None;
		break;
	case Mix::Tool::Win32::Graphics::REFLECT_NORMAL:
		type = Mix::Tool::Graphics::ReflectTypes::Normal;
		break;
	case Mix::Tool::Win32::Graphics::REFLECT_FRESNEL:
		type = Mix::Tool::Graphics::ReflectTypes::Fresnel;
		break;
	}

	return type;
}

void Material::SpecularProperty::ReflectType::set( Mix::Tool::Graphics::ReflectTypes value )
{
	Mix::Tool::Win32::Graphics::REFLECT_TYPE type;

	switch( value )
	{
	case Mix::Tool::Graphics::ReflectTypes::None:
		type = Mix::Tool::Win32::Graphics::REFLECT_NONE;
		break;
	case Mix::Tool::Graphics::ReflectTypes::Normal:
		type = Mix::Tool::Win32::Graphics::REFLECT_NORMAL;
		break;
	case Mix::Tool::Graphics::ReflectTypes::Fresnel:
		type = Mix::Tool::Win32::Graphics::REFLECT_FRESNEL;
		break;
	}

	impl->SetReflectType( type );
}

float Material::SpecularProperty::ReflectScale::get( void )
{
	return impl->GetReflectScale();
}

void Material::SpecularProperty::ReflectScale::set( float value )
{
	impl->SetReflectScale( value );
}

float Material::SpecularProperty::ReflectIntensity::get( void )
{
	return impl->GetReflectIntensity();
}

void Material::SpecularProperty::ReflectIntensity::set( float value )
{
	impl->SetReflectIntensity( value );
}

float Material::SpecularProperty::ReflectBias::get( void )
{
	return impl->GetReflectBias();
}

void Material::SpecularProperty::ReflectBias::set( float value )
{
	impl->SetReflectBias( value );
}

float Material::SpecularProperty::ReflectExprosure::get( void )
{
	return impl->GetReflectExprosure();
}

void Material::SpecularProperty::ReflectExprosure::set( float value )
{
	impl->SetReflectExprosure( value );
}

float Material::SpecularProperty::ReflectBumpRatio::get( void )
{
	return impl->GetReflectBumpRatio();
}

void Material::SpecularProperty::ReflectBumpRatio::set( float value )
{
	impl->SetReflectBumpRatio( value );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Material::EmissiveProperty
////////////////////////////////////////////////////////////////////////////////////////////////////

Material::EmissiveProperty::EmissiveProperty( Mix::Tool::Win32::Graphics::Material* _impl ) :
impl( _impl )
{
}

Material::EmissiveProperty::~EmissiveProperty( void )
{
	impl = nullptr;
}

Mix::Tool::Math::Vector^ Material::EmissiveProperty::Color::get( void )
{
	const D3DXVECTOR4& c = impl->GetEmissiveColor();

	return gcnew Mix::Tool::Math::Vector( c.x, c.y, c.z, c.w );
}

void Material::EmissiveProperty::Color::set( Mix::Tool::Math::Vector^ value )
{
	impl->SetEmissiveColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

float Material::EmissiveProperty::Scale::get( void )
{
	return impl->GetEmissiveScale();
}

void Material::EmissiveProperty::Scale::set( float value )
{
	impl->SetEmissiveScale( value );
}

System::String^ Material::EmissiveProperty::TextureFileName::get( void )
{
	return gcnew System::String( impl->GetEmissiveTextureFileName() );
}

void Material::EmissiveProperty::LoadTexture( void )
{
	impl->LoadEmissiveTexture();
}

void Material::EmissiveProperty::LoadTexture( System::String^ fileName )
{
	pin_ptr<const wchar_t> wFileName = PtrToStringChars( fileName );
	impl->LoadEmissiveTexture( wFileName );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Material::BumpProperty
////////////////////////////////////////////////////////////////////////////////////////////////////

Material::BumpProperty::BumpProperty( Mix::Tool::Win32::Graphics::Material* _impl ) :
impl( _impl )
{
}

Material::BumpProperty::~BumpProperty( void )
{
	impl = nullptr;
}

System::String^ Material::BumpProperty::TextureFileName::get( void )
{
	return gcnew System::String( impl->GetBumpTextureFileName() );
}

void Material::BumpProperty::LoadTexture( void )
{
	impl->LoadBumpTexture();
}

void Material::BumpProperty::LoadTexture( System::String^ fileName )
{
	pin_ptr<const wchar_t> wFileName = PtrToStringChars( fileName );
	impl->LoadBumpTexture( wFileName );
}

bool Material::BumpProperty::ParallaxEnabled::get( void )
{
	return ( impl->GetBumpType() == Mix::Tool::Win32::Graphics::BUMP_PARALLAX_MAPPING );
}

void Material::BumpProperty::ParallaxEnabled::set( bool value )
{
	Mix::Tool::Win32::Graphics::BUMP_TYPE type;

	if( value == false )
	{
		type = Mix::Tool::Win32::Graphics::BUMP_NORMAL_MAPPING;
	}
	else
	{
		type = Mix::Tool::Win32::Graphics::BUMP_PARALLAX_MAPPING;
	}

	impl->SetBumpType( type );
}

float Material::BumpProperty::ParallaxHeightScale::get( void )
{
	return impl->GetBumpHeightScale();
}

void Material::BumpProperty::ParallaxHeightScale::set( float value )
{
	impl->SetBumpHeightScale( value );
}

int Material::BumpProperty::ParallaxSample::get( void )
{
	return impl->GetBumpSample();
}

void Material::BumpProperty::ParallaxSample::set( int value )
{
	impl->SetBumpSample( value );
}

Mix::Tool::Graphics::WaveTypes Material::BumpProperty::WaveType::get( void )
{
	Mix::Tool::Graphics::WaveTypes type;

	switch( impl->GetBumpWaveType() )
	{
	case Mix::Tool::Win32::Graphics::WAVE_NORMAL:
		type = Mix::Tool::Graphics::WaveTypes::Normal;
		break;
	case Mix::Tool::Win32::Graphics::WAVE_REFRACT:
		type = Mix::Tool::Graphics::WaveTypes::Refract;
		break;
	}

	return type;
}

void Material::BumpProperty::WaveType::set( Mix::Tool::Graphics::WaveTypes value )
{
	Mix::Tool::Win32::Graphics::WAVE_TYPE type;

	switch( value )
	{
	case Mix::Tool::Graphics::WaveTypes::Normal:
		type = Mix::Tool::Win32::Graphics::WAVE_NORMAL;
		break;
	case Mix::Tool::Graphics::WaveTypes::Refract:
		type = Mix::Tool::Win32::Graphics::WAVE_REFRACT;
		break;
	}

	impl->SetBumpWaveType( type );
}

Mix::Tool::Graphics::WaveDirs Material::BumpProperty::WaveDir::get( void )
{
	Mix::Tool::Graphics::WaveDirs dir;

	switch( impl->GetBumpWaveDir() )
	{
	case Mix::Tool::Win32::Graphics::WAVE_NEGATIVE_U:
		dir = Mix::Tool::Graphics::WaveDirs::NegativeU;
		break;
	case Mix::Tool::Win32::Graphics::WAVE_POSITIVE_U:
		dir = Mix::Tool::Graphics::WaveDirs::PositiveU;
		break;
	case Mix::Tool::Win32::Graphics::WAVE_NEGATIVE_V:
		dir = Mix::Tool::Graphics::WaveDirs::NegativeV;
		break;
	case Mix::Tool::Win32::Graphics::WAVE_POSITIVE_V:
		dir = Mix::Tool::Graphics::WaveDirs::PositiveV;
		break;
	}

	return dir;
}

void Material::BumpProperty::WaveDir::set( Mix::Tool::Graphics::WaveDirs value )
{
	Mix::Tool::Win32::Graphics::WAVE_DIR dir;

	switch( value )
	{
	case Mix::Tool::Graphics::WaveDirs::NegativeU:
		dir = Mix::Tool::Win32::Graphics::WAVE_NEGATIVE_U;
		break;
	case Mix::Tool::Graphics::WaveDirs::PositiveU:
		dir = Mix::Tool::Win32::Graphics::WAVE_POSITIVE_U;
		break;
	case Mix::Tool::Graphics::WaveDirs::NegativeV:
		dir = Mix::Tool::Win32::Graphics::WAVE_NEGATIVE_V;
		break;
	case Mix::Tool::Graphics::WaveDirs::PositiveV:
		dir = Mix::Tool::Win32::Graphics::WAVE_POSITIVE_V;
		break;
	}

	impl->SetBumpWaveDir( dir );
}

float Material::BumpProperty::WaveVelocity::get( void )
{
	return impl->GetBumpWaveVelocity();
}

void Material::BumpProperty::WaveVelocity::set( float value )
{
	impl->SetBumpWaveVelocity( value );
}

float Material::BumpProperty::WaveUVOffset::get( void )
{
	return impl->GetBumpWaveUVOffset();
}

void Material::BumpProperty::WaveUVOffset::set( float value )
{
	impl->SetBumpWaveUVOffset( value );
}

float Material::BumpProperty::WaveGap::get( void )
{
	return impl->GetBumpWaveGap();
}

void Material::BumpProperty::WaveGap::set( float value )
{
	impl->SetBumpWaveGap( value );
}

float Material::BumpProperty::WaveRefraction::get( void )
{
	return impl->GetBumpRefractRatio();
}

void Material::BumpProperty::WaveRefraction::set( float value )
{
	impl->SetBumpRefractRatio( value );
}

bool Material::BumpProperty::WaveInvert::get( void )
{
	return impl->GetBumpWaveInvert();
}

void Material::BumpProperty::WaveInvert::set( bool value )
{
	impl->SetBumpWaveInvert( value );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Material::ShadowMappingProperty
////////////////////////////////////////////////////////////////////////////////////////////////////

Material::ShadowMappingProperty::ShadowMappingProperty( Mix::Tool::Win32::Graphics::Material* _impl ) :
impl( _impl )
{
}

Material::ShadowMappingProperty::~ShadowMappingProperty( void )
{
	impl = nullptr;
}

bool Material::ShadowMappingProperty::Receive::get( void )
{
	return impl->GetShadowReceive();
}

void Material::ShadowMappingProperty::Receive::set( bool value )
{
	impl->SetShadowReceive( value );
}

bool Material::ShadowMappingProperty::Cast::get( void )
{
	return impl->GetShadowCast();
}

void Material::ShadowMappingProperty::Cast::set( bool value )
{
	impl->SetShadowCast( value );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Material
////////////////////////////////////////////////////////////////////////////////////////////////////

Material::Material( Mix::Tool::Win32::Graphics::Material* _impl ) :
impl( _impl )
{
	m_TextureMappingProp = gcnew Material::TextureMappingProperty( impl );
	m_ShadowMappingProp = gcnew Material::ShadowMappingProperty( impl );
	m_DiffuseProp = gcnew Material::DiffuseProperty( impl );
	m_SpecularProp = gcnew Material::SpecularProperty( impl );
	m_EmissiveProp = gcnew Material::EmissiveProperty( impl );
	m_BumpProp = gcnew Material::BumpProperty( impl );
}

Material::~Material( void )
{
	delete m_BumpProp;
	delete m_EmissiveProp;
	delete m_SpecularProp;
	delete m_DiffuseProp;
	delete m_ShadowMappingProp;
	delete m_TextureMappingProp;

	impl = NULL;
}

System::String^ Material::DefaultName::get( void )
{
	return gcnew System::String( impl->GetDefaultName() );
}

System::String^ Material::Name::get( void )
{
	return gcnew System::String( impl->GetName() );
}

void Material::Name::set( System::String^ value )
{
	pin_ptr<const wchar_t> wpName = PtrToStringChars( value );
	impl->SetName( wpName );
}

System::String^ Material::SaveFilePath::get( void )
{
	return gcnew System::String( impl->GetSaveFilePath() );
}

void Material::SaveFilePath::set( System::String^ value )
{
	pin_ptr<const wchar_t> wpValue = PtrToStringChars( value );

	impl->SetSaveFilePath( wpValue );
}

bool Material::AutoUpdate::get( void )
{
	return impl->GetAutoUpdate();
}

void Material::AutoUpdate::set( bool value )
{
	impl->SetAutoUpdate( value );
}

bool Material::IsDefault::get( void )
{
	return impl->GetDefault();
}

bool Material::IsActive::get( void )
{
	return impl->GetActive();
}

void Material::Update( void )
{
	impl->Update();
}

void Material::Activate( void )
{
	return impl->SetActive();
}

// Material : General //

Mix::Tool::Graphics::ShaderTypes Material::ShaderType::get( void )
{
	Mix::Tool::Graphics::ShaderTypes type;

	switch( impl->GetShaderType() )
	{
	case Mix::Tool::Win32::Graphics::SHADER_NORMAL:
		type = Mix::Tool::Graphics::ShaderTypes::Normal;
		break;
	case Mix::Tool::Win32::Graphics::SHADER_WATER:
		type = Mix::Tool::Graphics::ShaderTypes::Water;
		break;
	case Mix::Tool::Win32::Graphics::SHADER_SHADELESS:
		type = Mix::Tool::Graphics::ShaderTypes::Shadeless;
		break;
	}

	return type;
}

void Material::ShaderType::set( Mix::Tool::Graphics::ShaderTypes value )
{
	Mix::Tool::Win32::Graphics::SHADER_TYPE type;

	switch( value )
	{
	case Mix::Tool::Graphics::ShaderTypes::Normal:
		type = Mix::Tool::Win32::Graphics::SHADER_NORMAL;
		break;
	case Mix::Tool::Graphics::ShaderTypes::Water:
		type = Mix::Tool::Win32::Graphics::SHADER_WATER;
		break;
	case Mix::Tool::Graphics::ShaderTypes::Shadeless:
		type = Mix::Tool::Win32::Graphics::SHADER_SHADELESS;
		break;
	}

	impl->SetShaderType( type );
}

Mix::Tool::Math::Vector^ Material::AmbientColor::get( void )
{
	const D3DXVECTOR4& col = impl->GetAmbientColor();

	return gcnew Mix::Tool::Math::Vector( col.x, col.y, col.z, col.w );
}

void Material::AmbientColor::set( Mix::Tool::Math::Vector^ value )
{
	if( value == nullptr )
	{
		throw gcnew System::ArgumentNullException( L"value" );
	}

	impl->SetAmbientColor( D3DXVECTOR4( value->X, value->Y, value->Z, value->W ) );
}

bool Material::BothLighting::get( void )
{
	return impl->GetBothLighting();
}

void Material::BothLighting::set( bool value )
{
	impl->SetBothLighting( value );
}

Mix::Tool::Graphics::BlendModes Material::BlendMode::get( void )
{
	Mix::Tool::Graphics::BlendModes mode;

	switch( impl->GetBlendMode() )
	{
	case Mix::Tool::Win32::Graphics::BLEND_COPY:
		mode = Mix::Tool::Graphics::BlendModes::Copy;
		break;
	case Mix::Tool::Win32::Graphics::BLEND_NORMAL:
		mode = Mix::Tool::Graphics::BlendModes::Normal;
		break;
	case Mix::Tool::Win32::Graphics::BLEND_ADD:
		mode = Mix::Tool::Graphics::BlendModes::Add;
		break;
	case Mix::Tool::Win32::Graphics::BLEND_SUB:
		mode = Mix::Tool::Graphics::BlendModes::Sub;
		break;
	case Mix::Tool::Win32::Graphics::BLEND_MUL:
		mode = Mix::Tool::Graphics::BlendModes::Mul;
		break;
	case Mix::Tool::Win32::Graphics::BLEND_SCREEN:
		mode = Mix::Tool::Graphics::BlendModes::Screen;
		break;
	}

	return mode;
}

void Material::BlendMode::set( Mix::Tool::Graphics::BlendModes value )
{
	Mix::Tool::Win32::Graphics::BLEND_MODE mode;

	switch( value )
	{
	case Mix::Tool::Graphics::BlendModes::Copy:
		mode = Mix::Tool::Win32::Graphics::BLEND_COPY;
		break;
	case Mix::Tool::Graphics::BlendModes::Normal:
		mode = Mix::Tool::Win32::Graphics::BLEND_NORMAL;
		break;
	case Mix::Tool::Graphics::BlendModes::Add:
		mode = Mix::Tool::Win32::Graphics::BLEND_ADD;
		break;
	case Mix::Tool::Graphics::BlendModes::Sub:
		mode = Mix::Tool::Win32::Graphics::BLEND_SUB;
		break;
	case Mix::Tool::Graphics::BlendModes::Mul:
		mode = Mix::Tool::Win32::Graphics::BLEND_MUL;
		break;
	case Mix::Tool::Graphics::BlendModes::Screen:
		mode = Mix::Tool::Win32::Graphics::BLEND_SCREEN;
		break;
	}

	impl->SetBlendMode( mode );
}

bool Material::TransparencyEnabled::get( void )
{
	return impl->GetTransparency();
}

void Material::TransparencyEnabled::set( bool value )
{
	impl->SetTransparency( value );
}

Mix::Tool::Graphics::TransparencyMethods Material::TransparencyMethod::get( void )
{
	Mix::Tool::Graphics::TransparencyMethods method;

	switch( impl->GetTransparencyMethod() )
	{
	case Mix::Tool::Win32::Graphics::TRANSPARENCY_LUMP:
		method = Mix::Tool::Graphics::TransparencyMethods::Lump;
		break;
	case Mix::Tool::Win32::Graphics::TRANSPARENCY_INDIVIDUAL:
		method = Mix::Tool::Graphics::TransparencyMethods::Individual;
		break;
	}

	return method;
}

void Material::TransparencyMethod::set( Mix::Tool::Graphics::TransparencyMethods value )
{
	Mix::Tool::Win32::Graphics::TRANSPARENCY_METHOD method;

	switch( value )
	{
	case Mix::Tool::Graphics::TransparencyMethods::Lump:
		method = Mix::Tool::Win32::Graphics::TRANSPARENCY_LUMP;
		break;
	case Mix::Tool::Graphics::TransparencyMethods::Individual:
		method = Mix::Tool::Win32::Graphics::TRANSPARENCY_INDIVIDUAL;
		break;
	}

	impl->SetTransparencyMethod( method );
}

bool Material::ZWrite::get( void )
{
	return impl->GetZWrite();
}

void Material::ZWrite::set( bool value )
{
	impl->SetZWrite( value );
}

bool Material::SoftEdgeEnabled::get( void )
{
	return impl->GetSoftEdge();
}

void Material::SoftEdgeEnabled::set( bool value )
{
	impl->SetSoftEdge( value );
}

float Material::SoftEdgeTickness::get( void )
{
	return impl->GetSoftEdgeThickness();
}

void Material::SoftEdgeTickness::set( float value )
{
	impl->SetSoftEdgeThickness( value );
}

bool Material::Backculling::get( void )
{
	return impl->GetBackculling();
}

void Material::Backculling::set( bool value )
{
	impl->SetBackculling( value );
}

// Material : Diffuse //

Material::DiffuseProperty^ Material::Diffuse::get( void )
{
	return m_DiffuseProp;
}

// Material : Specular //

Material::SpecularProperty^ Material::Specular::get( void )
{
	return m_SpecularProp;
}

// Material : Emissive //

Material::EmissiveProperty^ Material::Emissive::get( void )
{
	return m_EmissiveProp;
}

// Material : Bump //

Material::BumpProperty^ Material::Bump::get( void )
{
	return m_BumpProp;
}

// Material : TextureMapping //

Material::TextureMappingProperty^ Material::TextureMapping::get( void )
{
	return m_TextureMappingProp;
}

// Material : ShadowMapping //

Material::ShadowMappingProperty^ Material::ShadowMapping::get( void )
{
	return m_ShadowMappingProp;
}

}}}
