#pragma once

#include "Mix/Tool/Win32/Core/Graphics/Material.h"
#include "Mix/Tool/CLR/Core/Graphics/ShaderTypes.h"
#include "Mix/Tool/CLR/Core/Graphics/BlendModes.h"
#include "Mix/Tool/CLR/Core/Graphics/TransparencyMethods.h"
#include "Mix/Tool/CLR/Core/Graphics/DiffuseTypes.h"
#include "Mix/Tool/CLR/Core/Graphics/SpecularTypes.h"
#include "Mix/Tool/CLR/Core/Graphics/ReflectTypes.h"
#include "Mix/Tool/CLR/Core/Graphics/WaveTypes.h"
#include "Mix/Tool/CLR/Core/Graphics/WaveDirs.h"
#include "Mix/Tool/CLR/Core/Graphics/TextureFilterTypes.h"
#include "Mix/Tool/CLR/Core/Graphics/TextureAddressTypes.h"

using namespace System;

namespace Mix{ namespace Tool{ namespace Graphics {

	public ref class Material
	{
	public:
		ref class TextureMappingProperty
		{
		private:
			Mix::Tool::Win32::Graphics::Material* impl;

		internal:
			TextureMappingProperty( Mix::Tool::Win32::Graphics::Material* _impl );
			~TextureMappingProperty( void );

		public:
			property Mix::Tool::Graphics::TextureFilterTypes FilterType
			{
				Mix::Tool::Graphics::TextureFilterTypes get( void );
				void set( Mix::Tool::Graphics::TextureFilterTypes value );
			}

			property Mix::Tool::Graphics::TextureAddressTypes AddressType
			{
				Mix::Tool::Graphics::TextureAddressTypes get( void );
				void set( Mix::Tool::Graphics::TextureAddressTypes value );
			}
		};

		ref class ShadowMappingProperty
		{
		private:
			Mix::Tool::Win32::Graphics::Material* impl;

		internal:
			ShadowMappingProperty( Mix::Tool::Win32::Graphics::Material* _impl );
			~ShadowMappingProperty( void );

		public:
			property bool Receive
			{
				bool get( void );
				void set( bool value );
			}

			property bool Cast
			{
				bool get( void );
				void set( bool value );
			}
		};

		ref class DiffuseProperty
		{
		private:
			Mix::Tool::Win32::Graphics::Material* impl;

		internal:
			DiffuseProperty( Mix::Tool::Win32::Graphics::Material* _impl );
			~DiffuseProperty( void );

		public:
			property Mix::Tool::Graphics::DiffuseTypes Type
			{
				Mix::Tool::Graphics::DiffuseTypes get( void );
				void set( Mix::Tool::Graphics::DiffuseTypes value );
			}

			property Mix::Tool::Math::Vector^ Color
			{
				Mix::Tool::Math::Vector^ get( void );
				void set( Mix::Tool::Math::Vector^ value );
			}

			property System::String^ TextureFileName
			{
				System::String^ get( void );
			}

			void LoadTexture( void );
			void LoadTexture( System::String^ fileName );

			property bool Fresnel
			{
				bool get( void );
				void set( bool value );
			}

			property float FresnelRatio
			{
				float get( void );
				void set( float value );
			};

			property bool RimLighting
			{
				bool get( void );
				void set( bool value );
			}

			property float RimLightingHardness
			{
				float get( void );
				void set( float value );
			};

			property float RimLightingScale
			{
				float get( void );
				void set( float value );
			};
		};

		ref class SpecularProperty
		{
		private:
			Mix::Tool::Win32::Graphics::Material* impl;

		internal:
			SpecularProperty( Mix::Tool::Win32::Graphics::Material* _impl );
			~SpecularProperty( void );

		public:
			property Mix::Tool::Graphics::SpecularTypes Type
			{
				Mix::Tool::Graphics::SpecularTypes get( void );
				void set( Mix::Tool::Graphics::SpecularTypes value );
			}

			property Mix::Tool::Math::Vector^ Color
			{
				Mix::Tool::Math::Vector^ get( void );
				void set( Mix::Tool::Math::Vector^ value );
			}

			property System::String^ TextureFileName
			{
				System::String^ get( void );
			}

			void LoadTexture( void );
			void LoadTexture( System::String^ fileName );

			property float Hardness
			{
				float get( void );
				void set( float value );
			}

			property float Scale
			{
				float get( void );
				void set( float value );
			}

			property float CookTorranceFresnel
			{
				float get( void );
				void set( float value );
			}

			property float CookTorranceRoughness
			{
				float get( void );
				void set( float value );
			}

			// Reflection //

			property Mix::Tool::Graphics::ReflectTypes ReflectType
			{
				Mix::Tool::Graphics::ReflectTypes get( void );
				void set( Mix::Tool::Graphics::ReflectTypes value );
			}

			property float ReflectScale
			{
				float get( void );
				void set( float value );
			};

			property float ReflectIntensity
			{
				float get( void );
				void set( float value );
			};

			property float ReflectBias
			{
				float get( void );
				void set( float value );
			};

			property float ReflectExprosure
			{
				float get( void );
				void set( float value );
			};

			property float ReflectBumpRatio
			{
				float get( void );
				void set( float value );
			}
		};

		ref class EmissiveProperty
		{
		private:
			Mix::Tool::Win32::Graphics::Material* impl;

		internal:
			EmissiveProperty( Mix::Tool::Win32::Graphics::Material* _impl );
			~EmissiveProperty( void );

		public:
			property Mix::Tool::Math::Vector^ Color
			{
				Mix::Tool::Math::Vector^ get( void );
				void set( Mix::Tool::Math::Vector^ value );
			}

			property System::String^ TextureFileName
			{
				System::String^ get( void );
			}

			void LoadTexture( void );
			void LoadTexture( System::String^ fileName );

			property float Scale
			{
				float get( void );
				void set( float value );
			}
		};

		ref class BumpProperty
		{
		private:
			Mix::Tool::Win32::Graphics::Material* impl;

		internal:
			BumpProperty( Mix::Tool::Win32::Graphics::Material* _impl );
			~BumpProperty( void );

		public:
			property System::String^ TextureFileName
			{
				System::String^ get( void );
			}

			void LoadTexture( void );
			void LoadTexture( System::String^ fileName );

			// Parallax //

			property bool ParallaxEnabled
			{
				bool get( void );
				void set( bool value );
			}

			property float ParallaxHeightScale
			{
				float get( void );
				void set( float value );
			}

			property int ParallaxSample
			{
				int get( void );
				void set( int value );
			}

			// Wave //

			property Mix::Tool::Graphics::WaveTypes WaveType
			{
				Mix::Tool::Graphics::WaveTypes get( void );
				void set( Mix::Tool::Graphics::WaveTypes value );
			}

			property Mix::Tool::Graphics::WaveDirs WaveDir
			{
				Mix::Tool::Graphics::WaveDirs get( void );
				void set( Mix::Tool::Graphics::WaveDirs value );
			}

			property float WaveVelocity
			{
				float get( void );
				void set( float value );
			}

			property float WaveUVOffset
			{
				float get( void );
				void set( float value );
			}

			property float WaveGap
			{
				float get( void );
				void set( float value );
			}

			property float WaveRefraction
			{
				float get( void );
				void set( float value );
			}

			property bool WaveInvert
			{
				bool get( void );
				void set( bool value );
			}
		};

	private:
		Mix::Tool::Win32::Graphics::Material* impl;

		Material::TextureMappingProperty^ m_TextureMappingProp;
		Material::ShadowMappingProperty^ m_ShadowMappingProp;

		Material::DiffuseProperty^ m_DiffuseProp;
		Material::SpecularProperty^ m_SpecularProp;
		Material::EmissiveProperty^ m_EmissiveProp;
		Material::BumpProperty^ m_BumpProp;

	internal:
		Material( Mix::Tool::Win32::Graphics::Material* _impl );
		~Material( void );

	public:
		property System::String^ DefaultName
		{
			System::String^ get( void );
		}

		property System::String^ Name
		{
			System::String^ get( void );
			void set( System::String^ value );
		}

		property System::String^ SaveFilePath
		{
			System::String^ get( void );
			void set( System::String^ value );
		}

		property bool AutoUpdate
		{
			bool get( void );
			void set( bool value );
		}

		property bool IsDefault
		{
			bool get( void );
		}

		property bool IsActive
		{
			bool get( void );
		}

		void Update( void );
		void Activate( void );

		// General //

		property Mix::Tool::Graphics::ShaderTypes ShaderType
		{
			Mix::Tool::Graphics::ShaderTypes get( void );
			void set( Mix::Tool::Graphics::ShaderTypes value );
		}

		property Mix::Tool::Math::Vector^ AmbientColor
		{
			Mix::Tool::Math::Vector^ get( void );
			void set( Mix::Tool::Math::Vector^ value );
		}

		property bool BothLighting
		{
			bool get( void );
			void set( bool value );
		}

		property Mix::Tool::Graphics::BlendModes BlendMode
		{
			Mix::Tool::Graphics::BlendModes get( void );
			void set( Mix::Tool::Graphics::BlendModes value );
		}

		property bool TransparencyEnabled
		{
			bool get( void );
			void set( bool value );
		}

		property Mix::Tool::Graphics::TransparencyMethods TransparencyMethod
		{
			Mix::Tool::Graphics::TransparencyMethods get( void );
			void set( Mix::Tool::Graphics::TransparencyMethods value );
		}

		property bool ZWrite
		{
			bool get( void );
			void set( bool value );
		}

		property bool SoftEdgeEnabled
		{
			bool get( void );
			void set( bool value );
		}

		property float SoftEdgeTickness
		{
			float get( void );
			void set( float value );
		}

		property bool Backculling
		{
			bool get( void );
			void set( bool value );
		}

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

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

		// Diffuse //

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

		// Specular //

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

		// Emissive //

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

		// Bump //

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

}}}
