#pragma once
#define MLR_MLRSTATE_HPP

#if !defined(MLR_MLR_HPP)
	#include <MLR\MLR.hpp>
#endif

namespace MidLevelRenderer {class MLRStateBase;}

namespace GetHashFunctions {
	unsigned
		GetHashValue(const MidLevelRenderer::MLRStateBase &value);
}

namespace MidLevelRenderer {

	void SetDefaultRenderStates();

	class MLRState;
	class MLRSorter;
	class MLRSortByOrder;
	class MLRTexturePool;

	//##########################################################################
	//########################    MLRState    ###############################
	//##########################################################################

	class MLRStateBase
		#if defined(_ARMOR)
			: public Stuff::Signature
		#endif
	{
		friend class MLRSorter;
		friend class MLRSortByOrder;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructors/Destructors
	//
	protected:
		MLRStateBase(
			Stuff::MemoryStream *stream,
			int version
		);

	public:
		MLRStateBase();
		MLRStateBase(const MLRStateBase&);
		~MLRStateBase() {};

		static MLRStateBase*
			Make(
				Stuff::MemoryStream *stream,
				int version
			);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Render state
	//
	public:
		enum {
			TextureNumberBit = 0,
			TextureNumberBits = Limits::Max_Number_Of_Texture_Bits,
			TextureMask =
				(0xFFFFFFFF >> (Stuff::INT_BITS - TextureNumberBits)) << TextureNumberBit,

			AlphaBit = TextureNumberBit + TextureNumberBits,
			AlphaBits = 3,
			AlphaMask =  (0xFFFFFFFF >> (Stuff::INT_BITS - AlphaBits)) << AlphaBit,

			FilterBit = AlphaBit + AlphaBits,
			FilterBits = 2,
			FilterMask = (0xFFFFFFFF >> (Stuff::INT_BITS - FilterBits)) << FilterBit,

			FogBit = FilterBit + FilterBits,
			FogBits = 2,
			FogMask = (0xFFFFFFFF >> (Stuff::INT_BITS - FogBits)) << FogBit,

			TextureWrapBit = FogBit + FogBits,
			TextureWrapMask = 1 << TextureWrapBit,

			DitherBit = TextureWrapBit+1,
			DitherMask = 1<<DitherBit,

			TextureCorrectionBit = DitherBit+1,
			TextureCorrectionMask = 1<<TextureCorrectionBit,

			WireFrameBit = TextureCorrectionBit + 1,
			WireFrameBits = 2,
			WireFrameMask =
				(0xFFFFFFFF >> (Stuff::INT_BITS - WireFrameBits)) << WireFrameBit,

			ZBufferWriteBit = WireFrameBit + WireFrameBits,
			ZBufferWriteMask = 1<<ZBufferWriteBit,

			ZBufferCompareBit = ZBufferWriteBit + 1,
			ZBufferCompareMask = 1<<ZBufferCompareBit,

			SpecularBit = ZBufferCompareBit + 1,
			SpecularMask = 1 << SpecularBit,

			FlatColoringBit = SpecularBit + 1,
			FlatColoringMask = 1 << FlatColoringBit,

			BumpMapBit = FlatColoringBit + 1,
			BumpMapMask = 1 << BumpMapBit,

			UsedRenderBits = BumpMapBit + 1,
			UsedRenderMask = 0xFFFFFFFF >> (Stuff::INT_BITS - UsedRenderBits)
		};

		enum AlphaMode {
			OneZeroMode = 0,
			OneOneMode = 1 << AlphaBit,
			AlphaOneMode = 2 << AlphaBit,
			OneAlphaMode = 3 << AlphaBit,
			AlphaInvAlphaMode = 4 << AlphaBit,
			OneInvAlphaMode = 5 << AlphaBit,
			KeyedAlphaMode = 6 << AlphaBit,

			FirstAlphaAlphaMode = OneOneMode
		};

		enum FilterMode {
			NoFilterMode = 0,
			BiLinearFilterMode = 1 << FilterBit,
			TriLinearFilterMode = 2 << FilterBit
		};

		enum SpecularMode {
			SpecularOffMode = 0,
			SpecularOnMode = 1 << SpecularBit
		};

		enum TextureWrapMode {
			TextureWrap = 0,
			TextureClamp = 1 << TextureWrapBit
		};

		enum DitherMode {
			DitherOffMode = 0,
			DitherOnMode = 1 << DitherBit
		};

		enum TextureCorrectionMode {
			TextureCorrectionOffMode = 0,
			TextureCorrectionOnMode = 1 << TextureCorrectionBit
		};

		enum WireFrameMode {
			WireFrameOffMode = 0,
			WireFrameOnlyMode = 1 << WireFrameBit,
			WireFrameAddMode = 2 << WireFrameBit
		};

		enum ZBufferWriteMode {
			ZBufferWriteOffMode = 0,
			ZBufferWriteOnMode = 1 << ZBufferWriteBit
		};

		enum ZBufferCompareMode {
			ZBufferCompareOffMode = 0,
			ZBufferCompareOnMode = 1 << ZBufferCompareBit
		};

		enum FlatColoringMode {
			FlatColoringOffMode = 0,
			FlatColoringOnMode = 1 << FlatColoringBit
		};

		enum BumpMapMode {
			BumpMapOffMode = 0,
			BumpMapOnMode = 1 << BumpMapBit,
		};

// manipulate render state
		void
			SetTextureHandle(unsigned texture)
				{
					Check_Object(this); renderState &= ~TextureMask;
					Verify(texture <= TextureMask);
					renderState |= texture;
				}

		void
			SetAlphaMode(AlphaMode alpha)
				{Check_Object(this); renderState &= ~AlphaMask; renderState |= alpha; }

		void
			SetFilterMode(FilterMode filter)
				{Check_Object(this); renderState &= ~FilterMask; renderState |= filter; }

		void
			SetFogMode(int fog)
				{Check_Object(this); renderState &= ~FogMask; renderState |= (fog<<FogBit); }

		void
			SetSpecularOn()
				{Check_Object(this); renderState |= SpecularOnMode; }
		void
			SetSpecularOff()
				{Check_Object(this); renderState &= ~SpecularOnMode; }
		void
			SetTextureWrapMode(TextureWrapMode TextureWrap)
				{Check_Object(this); renderState &= ~TextureWrapMask; renderState |= TextureWrap; }
		void
			SetDitherOn()
				{Check_Object(this); renderState |= DitherOnMode; }
		void
			SetDitherOff()
				{Check_Object(this); renderState &= ~DitherOnMode; }
		void
			SetTextureCorrectionOn()
				{Check_Object(this); renderState |= TextureCorrectionOnMode; }
		void
			SetTextureCorrectionOff()
				{Check_Object(this); renderState &= ~TextureCorrectionOnMode; }
		void
			SetWireFrameMode(WireFrameMode wire)
				{Check_Object(this); renderState &= ~WireFrameMask; renderState |= wire; }
		void
			SetZBufferWriteOn()
				{Check_Object(this); renderState |= ZBufferWriteOnMode; ;}
		void
			SetZBufferWriteOff()
				{Check_Object(this); renderState &= ~ZBufferWriteOnMode; }
		void
			SetZBufferCompareOn()
				{Check_Object(this); renderState |= ZBufferCompareOnMode; }
		void
			SetZBufferCompareOff()
				{Check_Object(this); renderState &= ~ZBufferCompareOnMode; }
		void
			SetFlatColoringOn()
				{Check_Object(this); renderState |= FlatColoringOnMode; }
		void
			SetFlatColoringOff()
				{Check_Object(this); renderState &= ~FlatColoringOnMode; }
		void
			SetBumpMapOn()
				{Check_Object(this); renderState |= BumpMapOnMode; }
		void
			SetBumpMapOff()
				{Check_Object(this); renderState &= ~BumpMapOnMode; }
		
		void
			SetRenderStateFlags(DWORD render_state)
				{Check_Object(this); renderState = render_state; }

//==============================================================================================

		unsigned
			GetTextureHandle() const
				{Check_Object(this); return renderState & TextureMask;}

		AlphaMode
			GetAlphaMode() const
				{
					Check_Object(this);
					return static_cast<AlphaMode>(renderState & AlphaMask);
				}

		FilterMode
			GetFilterMode() const
				{
					Check_Object(this);
					return static_cast<FilterMode>(renderState & FilterMask);
				}
		int
			GetFogMode() const
				{Check_Object(this); return (renderState & FogMask)>>FogBit;}

		SpecularMode
			GetSpecularMode() const
				{Check_Object(this); return static_cast<SpecularMode>(renderState & SpecularMask);}

		TextureWrapMode
			GetTextureWrapMode() const
				{
					Check_Object(this);
					return static_cast<TextureWrapMode>(renderState & TextureWrapMask);
				}

		DitherMode
			GetDitherMode() const
				{Check_Object(this); return static_cast<DitherMode>(renderState & DitherMask);}

		TextureCorrectionMode
			GetTextureCorrectionMode() const
				{Check_Object(this); return static_cast<TextureCorrectionMode>(renderState & TextureCorrectionMask);}

		WireFrameMode
			GetWireFrameMode() const
				{
					Check_Object(this);
					return static_cast<WireFrameMode>(renderState & WireFrameMask);
				}

		ZBufferWriteMode
			GetZBufferWriteMode() const
				{Check_Object(this); return static_cast<ZBufferWriteMode>(renderState & ZBufferWriteMask);}

		ZBufferCompareMode
			GetZBufferCompareMode() const
				{Check_Object(this); return static_cast<ZBufferCompareMode>(renderState & ZBufferCompareMask);}

		FlatColoringMode
			GetFlatColoringMode() const
				{Check_Object(this); return static_cast<FlatColoringMode>(renderState & FlatColoringMask);}

		BumpMapMode
			GetBumpMapMode() const
				{Check_Object(this); return static_cast<BumpMapMode>(renderState & BumpMapOnMode);}

		DWORD
			GetRenderStateFlags() const
				{Check_Object(this); return renderState;}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Process state
	//
	public:
		enum {
			PriorityBit = 0,
			PriorityBits = 4,
			PriorityMask =
				(0xFFFFFFFF >> (Stuff::INT_BITS - PriorityBits)) << PriorityBit,

			BackFaceBit = PriorityBit + PriorityBits,
			BackFaceMask = 1<<BackFaceBit,

			LightingBit = BackFaceBit + 1,
			LightingBits = 5,
			LightingMask =
				(0xFFFFFFFF >> (Stuff::INT_BITS - LightingBits)) << LightingBit,

			MultitextureBit = LightingBit + LightingBits,
			MultitextureBits = 4,
			MultitextureMask =
				(0xFFFFFFFF >> (Stuff::INT_BITS - MultitextureBits)) << MultitextureBit,

			DrawNowBit = MultitextureBit + MultitextureBits,
			DrawNowMask = 1<<DrawNowBit,

			MatTwoSidedBit = DrawNowBit + 1,
			MatTwoSidedMask = 1<<MatTwoSidedBit,

			MovieTextureBit = MatTwoSidedBit + 1,
			MovieTextureMask = 1<<MovieTextureBit,

			UsedProcessBits = MovieTextureBit + 1,
			UsedProcessMask = 0xFFFFFFFF >> (Stuff::INT_BITS - UsedProcessBits)
		};

		enum BackFaceMode {
			BackFaceOffMode = 0,
			BackFaceOnMode = 1 << BackFaceBit,
		};

		enum MatTwoSidedMode {
			MatTwoSidedOffMode = 0,
			MatTwoSidedOnMode = 1 << MatTwoSidedBit,
		};

		enum {
			DefaultPriority = 0,
			DetailPrority = 1,
			AlphaPriority = 2,
			FirstApplicationPriority = 4,
			PriorityCount = 1<<PriorityBits,
		};

		enum LightingMode {
			LightingOffMode = 0,
			VertexLightingMode = 1 << LightingBit,
			LightMapLightingMode = 2 << LightingBit,
			LookupLightingMode = 4 << LightingBit,
			FaceLightingMode = 8 << LightingBit,
			TerrainLightingMode = 16 << LightingBit
		};

//	if cards are multi texture capable so use this mode
		enum MultiTextureMode {
			MultiTextureOffMode = 0,
			MultiTextureLightmapMode = 1 << MultitextureBit,
			MultiTextureSpecularMode = 2 << MultitextureBit,
			MultiTextureDetailMode = 4 << MultitextureBit,
		};

		enum DrawNowMode {
			DrawNowOffMode = 0,
			DrawNowOnMode = 1 << DrawNowBit,
		};

		enum MovieTextureMode {
			MovieTexturewOffMode = 0,
			MovieTextureOnMode = 1 << MovieTextureBit,
		};

// manipulate process state
		void
			SetMatTwoSidedOn()
				{Check_Object(this); processState |= MatTwoSidedOnMode; }
		void
			SetMatTwoSidedOff()
				{Check_Object(this); processState &= ~MatTwoSidedOnMode; }

		void
			SetBackFaceOn()
				{Check_Object(this); processState |= BackFaceOnMode; }
		void
			SetBackFaceOff()
				{Check_Object(this); processState &= ~BackFaceOnMode; }

		void
			SetPriority(unsigned priority)
				{
					Check_Object(this); processState &= ~PriorityMask;
					Verify(priority < PriorityCount);
					processState |= priority;
				}

		void
			SetLightingMode(int lighting)
				{Check_Object(this); processState &= ~LightingMask; processState |= lighting; }
		 

		void
			SetMultiTextureMode(MultiTextureMode multiTex)
				{Check_Object(this); processState &= ~MultitextureMask; processState |= multiTex; }
		 
		void
			SetDrawNowOn()
				{Check_Object(this); processState |= DrawNowOnMode; }
		void
			SetDrawNowOff()
				{Check_Object(this); processState &= ~DrawNowOnMode; }

		void
			SetMovieTextureOn()
				{Check_Object(this); processState |= MovieTextureOnMode; }
		void
			SetMovieTextureOff()
				{Check_Object(this); processState &= ~MovieTextureOnMode; }

		void
			SetProcessStateFlags(DWORD process_state)
				{Check_Object(this); processState = process_state; }

//==============================================================================================		
		
		MatTwoSidedMode
			GetMatTwoSidedMode() const
				{Check_Object(this); return static_cast<MatTwoSidedMode>(processState & MatTwoSidedOnMode);}

		BackFaceMode
			GetBackFaceMode() const
				{Check_Object(this); return static_cast<BackFaceMode>(processState & BackFaceOnMode);}

		unsigned
			GetPriority() const
				{Check_Object(this); return processState & PriorityMask;}

		int
			GetLightingMode() const
				{
					Check_Object(this);
					return static_cast<LightingMode>(processState & LightingMask);
				}
		 
		MultiTextureMode
			GetMultiTextureMode() const
				{
					Check_Object(this);
					return static_cast<MultiTextureMode>(processState & MultitextureMask);
				}

		DrawNowMode
			GetDrawNowMode() const
				{Check_Object(this); return static_cast<DrawNowMode>(processState & DrawNowOnMode);}

		MovieTextureMode
			GetMovieTextureMode() const
				{Check_Object(this); return static_cast<MovieTextureMode>(processState & MovieTextureOnMode);}

		DWORD
			GetProcessStateFlags() const
				{Check_Object(this); return processState;}

		void
			SetRendererState(MLRTexturePool*, DWORD tex2=0, DWORD tex3=0);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// System flags set at begin of every frame
	//

		enum {
			HasAGPAvailable = 1<<0,				//	FALSE when no AGP memory available (assume a low end card)
			CanMultitextureLightMap = 1<<1,		//	TRUE when single pass light mapping is available
			CanMultitextureSpecularMap = 1<<2,	//	TRUE when single pass specular mapping is available
			HasMaxUVs = 1<<3,					//	TRUE if video card has certain limits on UVs
			CanMultitextureDetailMap = 1<<4,	//	TRUE when single pass detail texturing is available	
			CanBumpEnvMap = 1<<5,				//	TRUE when current mode supports bump environment maps
			CanBumpDotMap = 1<<6				//	TRUE if the current mode supports normal maps (dotproduct3)
		};

		static void
			SetAGPAvailable(bool b)
				{ if(b==true) systemFlags |= HasAGPAvailable; else systemFlags &= ~HasAGPAvailable; }

		static void
			SetMultitextureLightMap(bool b)
				{ if(b==true) systemFlags |= CanMultitextureLightMap; else systemFlags &= ~CanMultitextureLightMap; }

		static void
			SetMultitextureSpecularMap(bool b)
				{ if(b==true) systemFlags |= CanMultitextureSpecularMap; else systemFlags &= ~CanMultitextureSpecularMap; }

		static void
			SetMultitextureDetailMap(bool b)
				{ if(b==true) systemFlags |= CanMultitextureDetailMap; else systemFlags &= ~CanMultitextureDetailMap; }

		static void
			SetHasMaxUVs(bool b)
				{ if(b==true) systemFlags |= HasMaxUVs; else systemFlags &= ~HasMaxUVs; }

		static void
			SetCanBumpEnvMap(bool b)
				{ if(b==true) systemFlags |= CanBumpEnvMap; else systemFlags &= ~CanBumpEnvMap; }

		static void
			SetCanBumpDotMap(bool b)
				{ if(b==true) systemFlags |= CanBumpDotMap; else systemFlags &= ~CanBumpDotMap; }

		static bool
			GetAGPAvailable()
				{ return (systemFlags & HasAGPAvailable)>0; }

		static bool
			GetMultitextureLightMap()
				{ return (systemFlags & CanMultitextureLightMap)>0; }

		static bool
			GetMultitextureSpecularMap()
				{ return (systemFlags & CanMultitextureSpecularMap)>0; }

		static bool
			GetMultitextureDetailMap()
				{ return (systemFlags & CanMultitextureDetailMap)>0; }

		static bool
			GetHasMaxUVs()
				{ return (systemFlags & HasMaxUVs)>0; }

		static bool
			GetCanBumpEnvMap()
				{ return (systemFlags & CanBumpEnvMap)>0; }

		static bool
			GetCanBumpDotMap()
				{ return (systemFlags & CanBumpDotMap)>0; }

		static void
			SetMaxUV(float mUV)
				{ maxUV = mUV; SetHasMaxUVs(mUV > 0.0f); }

		static float
			GetMaxUV()
				{ return maxUV*currentTextureSize; }

		static void
			SetCurrentTextureSize(int size)
				{
					if(size>=256) currentTextureSize = 1; else
						if(size>=128) currentTextureSize = 2; else
							if(size>=64) currentTextureSize = 4; else
								if(size>=32) currentTextureSize = 8; else
									if(size>=16) currentTextureSize = 16; else
										if(size>=8) currentTextureSize = 32; else
											currentTextureSize = 64;
				}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Assignment operators
	//
		MLRStateBase&
			operator=(const int &s)
				{Check_Pointer(this); renderState = s; return *this;}

		bool
			operator==(const MLRStateBase &s) const
				{
					Check_Pointer(this);
					return
						renderState == s.renderState
						 && processState == s.processState;
				}

		bool
			operator>(const MLRStateBase &s) const
				{
					Check_Pointer(this);
					return
						renderState > s.renderState
						 || renderState == s.renderState
							 && processState > s.processState;
				}

		bool
			operator!=(const MLRStateBase &s) const
				{
					Check_Pointer(this);
					return
						renderState != s.renderState
						 || processState != s.processState;
				}

		friend unsigned
			GetHashFunctions::GetHashValue(const MLRStateBase &value)
				{
					Verify(sizeof(unsigned) == sizeof(DWORD));
					return
						(
							((value.processState & MidLevelRenderer::MLRStateBase::UsedProcessMask) << MidLevelRenderer::MLRStateBase::UsedRenderBits)
							 | (value.renderState & MidLevelRenderer::MLRStateBase::UsedRenderMask)
						) & 0x7FFFFFFF;
				}

		MLRStateBase&
			CombineIntoBase(
				const MLRState &master,
				const MLRState &slave
			);

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Testing
	//
	public:
		void
			TestInstance() const
				{}

	protected:
		DWORD
			renderState,
			processState;

		static int
			systemFlags;
		static float
			maxUV;

		static int
			currentTextureSize; //	1-256 2-128 4-64 8-32 16-16 32-8

#ifdef OLDFOG
		unsigned int
			fogColor;
		Stuff::Scalar
			fogDensity,
			nearFog,
			farFog;
#else
	public:
		static unsigned int
			fogColor;
#endif
	};

	class MLRState
 		: public MLRStateBase
	{
		friend class MLRStateBase;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructors/Destructors
	//
	protected:
		MLRState(
			Stuff::MemoryStream *stream,
			int version
		);

	public:
		MLRState();
		MLRState(const MLRState&);
		~MLRState() {};

		static MLRState*
			Make(
				Stuff::MemoryStream *stream,
				int version
			);

		void
			Save(Stuff::MemoryStream *stream);
		void
			Load(
				Stuff::MemoryStream *stream,
				int version
			);

// manipulate render state
		void
			SetTextureHandle(unsigned texture)
				{
					Check_Object(this); renderState &= ~TextureMask;
					renderDeltaMask |= TextureMask;
					Verify(texture <= TextureMask); renderState |= texture;
				}

		void
			SetAlphaMode(AlphaMode alpha)
				{Check_Object(this); renderState &= ~AlphaMask; renderState |= alpha; renderDeltaMask |= AlphaMask;}

		void
			SetFilterMode(FilterMode filter)
				{Check_Object(this); renderState &= ~FilterMask; renderState |= filter; renderDeltaMask |= FilterMask;}

		void
			SetFogMode(int fog)
				{Check_Object(this); renderState &= ~FogMask; renderState |= (fog<<FogBit); renderDeltaMask |= FogMask;}

		void
			SetSpecularOn()
				{Check_Object(this); renderState |= SpecularOnMode; renderDeltaMask |= SpecularMask;}
		void
			SetSpecularOff()
				{Check_Object(this); renderState &= ~SpecularOnMode; renderDeltaMask |= SpecularMask;}
		void
			SetTextureWrapMode(TextureWrapMode TextureWrap)
				{Check_Object(this); renderState &= ~TextureWrapMask; renderState |= TextureWrap; renderDeltaMask |= TextureWrapMask;}
		void
			SetDitherOn()
				{Check_Object(this); renderState |= DitherOnMode; renderDeltaMask |= DitherMask;}
		void
			SetDitherOff()
				{Check_Object(this); renderState &= ~DitherOnMode; renderDeltaMask |= DitherMask;}
		void
			SetTextureCorrectionOn()
				{Check_Object(this); renderState |= TextureCorrectionOnMode; renderDeltaMask |= TextureCorrectionMask;}
		void
			SetTextureCorrectionOff()
				{Check_Object(this); renderState &= ~TextureCorrectionOnMode; renderDeltaMask |= TextureCorrectionMask;}
		void
			SetWireFrameMode(WireFrameMode wire)
				{Check_Object(this); renderState &= ~WireFrameMask; renderState |= wire; renderDeltaMask |= WireFrameMask;}
		void
			SetZBufferWriteOn()
				{Check_Object(this); renderState |= ZBufferWriteOnMode; renderDeltaMask |= ZBufferWriteMask;}
		void
			SetZBufferWriteOff()
				{Check_Object(this); renderState &= ~ZBufferWriteOnMode; renderDeltaMask |= ZBufferWriteMask;}
		void
			SetZBufferCompareOn()
				{Check_Object(this); renderState |= ZBufferCompareOnMode; renderDeltaMask |= ZBufferCompareMask;}
		void
			SetZBufferCompareOff()
				{Check_Object(this); renderState &= ~ZBufferCompareOnMode; renderDeltaMask |= ZBufferCompareMask;}
		void
			SetFlatColoringOn()
				{Check_Object(this); renderState |= FlatColoringOnMode; renderDeltaMask |= FlatColoringMask;}
		void
			SetFlatColoringOff()
				{Check_Object(this); renderState &= ~FlatColoringOnMode; renderDeltaMask |= FlatColoringMask;}
		void
			SetBumpMapOn()
				{Check_Object(this); renderState |= BumpMapOnMode; renderDeltaMask |= BumpMapMask;}
		void
			SetBumpMapOff()
				{Check_Object(this); renderState &= ~BumpMapOnMode; renderDeltaMask |= BumpMapMask;}
		
		void
			SetRenderDeltaMask(int mask)
				{ Check_Object(this); renderDeltaMask = mask; }

		int
			GetRenderDeltaMask() const
				{ Check_Object(this); return renderDeltaMask; }

		void
			SetRenderPermissionMask(int mask)
				{ Check_Object(this); renderPermissionMask = mask; }

		int
			GetRenderPermissionMask() const
				{ Check_Object(this); return renderPermissionMask; }

// manipulate process state
		void
			SetMatTwoSidedOn()
				{Check_Object(this); processState |= MatTwoSidedOnMode; processDeltaMask |= MatTwoSidedMask;}
		void
			SetMatTwoSidedOff()
				{Check_Object(this); processState &= ~MatTwoSidedOnMode; processDeltaMask |= MatTwoSidedMask;}

		void
			SetBackFaceOn()
				{Check_Object(this); processState |= BackFaceOnMode; processDeltaMask |= BackFaceMask;}
		void
			SetBackFaceOff()
				{Check_Object(this); processState &= ~BackFaceOnMode; processDeltaMask |= BackFaceMask;}

		void
			SetPriority(unsigned priority)
				{
					Check_Object(this); processState &= ~PriorityMask;
					processDeltaMask |= PriorityMask;
					Verify(priority < PriorityCount); processState |= priority;
				}

		void
			SetLightingMode(int lighting)
				{Check_Object(this); processState &= ~LightingMask; processState |= lighting; processDeltaMask |= LightingMask;}
		 

		void
			SetMultiTextureMode(MultiTextureMode multiTex)
				{Check_Object(this); processState &= ~MultitextureMask; processState |= multiTex; processDeltaMask |= MultitextureMask;}
		 
		void
			SetDrawNowOn()
				{Check_Object(this); processState |= DrawNowOnMode; processDeltaMask |= DrawNowMask;}
		void
			SetDrawNowOff()
				{Check_Object(this); processState &= ~DrawNowOnMode; processDeltaMask |= DrawNowMask;}

		void
			SetMovieTextureOn()
				{Check_Object(this); processState |= MovieTextureOnMode; processDeltaMask |= MovieTextureMask;}
		void
			SetMovieTextureOff()
				{Check_Object(this); processState &= ~MovieTextureOnMode; processDeltaMask |= MovieTextureMask;}

		void
			SetProcessDeltaMask(int mask)
				{ Check_Object(this); processDeltaMask = mask; }

		int
			GetProcessDeltaMask() const
				{ Check_Object(this); return processDeltaMask; }

		void
			SetProcessPermissionMask(int mask)
				{ Check_Object(this); processPermissionMask = mask; }

		int
			GetProcessPermissionMask() const
				{ Check_Object(this); return processPermissionMask; }

		int
			GetProcessStateFlags() const
				{Check_Object(this); return processState;}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Assignment operators
	//
		MLRState&
			operator=(const int &s)
				{Check_Pointer(this); renderState = s; return *this;}


	public:
		MLRState&
			Combine(
				const MLRState &master,
				const MLRState &slave
			);

	protected:
		DWORD
			renderDeltaMask,
			renderPermissionMask,
			processDeltaMask,
			processPermissionMask;
	};
}
