#include "ElementProxyHeaders.hpp"

#include <MLR\MLRTexturePool.hpp>
#include <MLR\MLRTexture.hpp>

//
//############################################################################
//############################    MLRStateProxy    ##############################
//############################################################################
//

MemoryBlock*
	MLRStateProxy::AllocatedMemory = NULL;
MLRStateProxy::ClassData*
	MLRStateProxy::DefaultData = NULL;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::InitializeClass()
{
	Verify(!AllocatedMemory);
	AllocatedMemory =
		new MemoryBlock(
			sizeof(MLRStateProxy),
			10,
			10,
			"MLRStateProxy"
		);
	Register_Object(AllocatedMemory);

	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			MLRStateProxyClassID,
			"MLRStateProxy",
			StateProxy::DefaultData
		);
	Register_Object(DefaultData);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;

	Unregister_Object(AllocatedMemory);
	delete AllocatedMemory;
	AllocatedMemory = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::Destroy()
{
	Check_Object(this);
	Verify(referenceCount == 1);
//	STOP(("Not implemented"));
	DetachReference();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRStateProxy::MLRStateProxy(
	MLRStatePoolProxy *library,
	const MLRState &state
):
	StateProxy(DefaultData, library)
{
	Check_Pointer(this);
	mlrState = state;

	//
	//----------------------------------------------------------------------
	// If no blend mode is specified in the state, check to see if we are
	// using an alpha texture.  If so, we will automatically set up the RGBA
	// blending mode
	//----------------------------------------------------------------------
	//
	if (!(mlrState.GetRenderDeltaMask()&MLRState::AlphaMask))
	{
		MLRTexturePoolProxy *texture_pool =
			Cast_Object(MLRTexturePoolProxy*, library->GetTextureLibrary());
		Check_Object(&mlrState);
		unsigned texture_handle = mlrState.GetTextureHandle();
		if (texture_handle)
		{
			MLRTexture *mlr_texture = (*MLRTexturePool::Instance)[texture_handle];
			Check_Object(mlr_texture);
			TextureProxy *texture =
				texture_pool->UseTextureProxy(mlr_texture->GetProxyNumber());
			Check_Object(texture);
			unsigned
				red,
				green,
				blue,
				alpha;
			texture->GetChannelDepth(&red, &green, &blue, &alpha);
			if (alpha>0)
			{
				mlrState.SetAlphaMode(MLRState::AlphaInvAlphaMode);
				mlrState.SetPriority(MLRState::AlphaPriority);
				mlrState.SetBackFaceOff();
			}
			texture->DetachReference();
		}
	}
	Check_Object(this);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRStateProxy::~MLRStateProxy()
{
	Check_Object(this);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::TestInstance() const
{
	Verify(IsDerivedFrom(DefaultData));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetName(MString *name)
{
	Check_Object(this);
	Check_Object(name);

	//STOP(("Not implemented"));
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetName(const char* name)
{
	Check_Object(this);
	Check_Pointer(name);
	//STOP(("Not implemented"));
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetAlpha(AlphaMode *alphaMode)
{
	Check_Object(this);
	Check_Pointer(alphaMode);

	switch(mlrState.GetAlphaMode())
	{
		case MLRState::OneZeroMode:
			*alphaMode = StateProxy::OneZeroMode;
		break;
		case MLRState::OneOneMode:
			*alphaMode = StateProxy::OneOneMode;
		break;
		case MLRState::AlphaOneMode:
			*alphaMode = StateProxy::AlphaOneMode;
		break;
		case MLRState::OneAlphaMode:
			*alphaMode = StateProxy::OneAlphaMode;
		break;
		case MLRState::AlphaInvAlphaMode:
			*alphaMode = StateProxy::AlphaInvAlphaMode;
		break;
		case MLRState::OneInvAlphaMode:
			*alphaMode = StateProxy::OneInvAlphaMode;
		break;
		case MLRState::KeyedAlphaMode:
			*alphaMode = StateProxy::KeyedAlphaMode;
		break;
	}

	if(mlrState.GetRenderDeltaMask() & MLRState::AlphaMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetAlpha(AlphaMode alphaMode)
{
	Check_Object(this);

	switch(alphaMode)
	{
		case StateProxy::OneZeroMode:
			mlrState.SetAlphaMode(MLRState::OneZeroMode);
		break;
		case StateProxy::OneOneMode:
			mlrState.SetAlphaMode(MLRState::OneOneMode);
		break;
		case StateProxy::AlphaOneMode:
			mlrState.SetAlphaMode(MLRState::AlphaOneMode);
		break;
		case StateProxy::OneAlphaMode:
			mlrState.SetAlphaMode(MLRState::OneAlphaMode);
		break;
		case StateProxy::AlphaInvAlphaMode:
			mlrState.SetAlphaMode(MLRState::AlphaInvAlphaMode);
		break;
		case StateProxy::OneInvAlphaMode:
			mlrState.SetAlphaMode(MLRState::OneInvAlphaMode);
		break;
		case StateProxy::KeyedAlphaMode:
			mlrState.SetAlphaMode(MLRState::KeyedAlphaMode);
		break;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetAlphaChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::AlphaMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetAlphaChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::AlphaMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::AlphaMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetFilter(FilterMode *filterMode)
{
	Check_Object(this);
	Check_Pointer(filterMode);

	switch(mlrState.GetFilterMode())
	{
		case MLRState::NoFilterMode:
			*filterMode = StateProxy::NoFilterMode;
		break;
		case MLRState::BiLinearFilterMode:
			*filterMode = StateProxy::BiLinearFilterMode;
		break;
		case MLRState::TriLinearFilterMode:
			*filterMode = StateProxy::TriLinearFilterMode;
		break;
	}

	if(mlrState.GetRenderDeltaMask() & MLRState::FilterMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetFilter(FilterMode filterMode)
{
	Check_Object(this);

	switch(filterMode)
	{
		case StateProxy::NoFilterMode:
			mlrState.SetFilterMode(MLRState::NoFilterMode);
		break;
		case StateProxy::BiLinearFilterMode:
			mlrState.SetFilterMode(MLRState::BiLinearFilterMode);
		break;
		case StateProxy::TriLinearFilterMode:
			mlrState.SetFilterMode(MLRState::TriLinearFilterMode);
		break;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetFilterChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::FilterMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetFilterChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::FilterMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::FilterMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetFog(FogMode *mode)
{
	Check_Object(this);
	Check_Pointer(mode);
	
	if(!(mlrState.GetRenderDeltaMask() & MLRState::FogMask))
		return false;

	*mode = static_cast<FogMode>(mlrState.GetFogMode());
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetFog(FogMode mode)
{
	Check_Object(this);

	mlrState.SetFogMode(mode);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetFogChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::FogMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetFogChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::FogMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::FogMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetDither(bool *dither)
{
	Check_Object(this);
	Check_Pointer(dither);

	*dither = (mlrState.GetDitherMode() == MLRState::DitherOnMode) ? true : false;

	if(mlrState.GetRenderDeltaMask() & MLRState::DitherMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetDither(bool dither)
{
	Check_Object(this);

	if(dither == true)
	{
		mlrState.SetDitherOn();
	}
	else
	{
		mlrState.SetDitherOff();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetDitherChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::DitherMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetDitherChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::DitherMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::DitherMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetSpecular(bool *Specular)
{
	Check_Object(this);
	Check_Pointer(Specular);

	*Specular = (mlrState.GetSpecularMode() == MLRState::SpecularOnMode) ? true : false;

	if(mlrState.GetRenderDeltaMask() & MLRState::SpecularMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetSpecular(bool Specular)
{
	Check_Object(this);

	if(Specular == true)
	{
		mlrState.SetSpecularOn();
	}
	else
	{
		mlrState.SetSpecularOff();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetSpecularChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::SpecularMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetSpecularChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::SpecularMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::SpecularMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetTextureCorrection(bool *texCor)
{
	Check_Object(this);

	*texCor = (mlrState.GetTextureCorrectionMode() == MLRState::TextureCorrectionOnMode) ? true : false;

	if(mlrState.GetRenderDeltaMask() & MLRState::TextureCorrectionMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetTextureCorrection(bool texCor)
{
	Check_Object(this);

	if(texCor == true)
	{
		mlrState.SetTextureCorrectionOn();
	}
	else
	{
		mlrState.SetTextureCorrectionOff();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetTextureCorrectionChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::TextureCorrectionMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetTextureCorrectionChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::TextureCorrectionMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::TextureCorrectionMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetTextureWrap(TextureWrapMode *texWrap)
{
	Check_Object(this);

	MLRState::TextureWrapMode mlrTexWrap;

	mlrTexWrap = mlrState.GetTextureWrapMode();

	if(mlrTexWrap == MLRState::TextureWrap)
	{
		*texWrap = StateProxy::TextureWrap;
	}
	else
	{
		*texWrap = StateProxy::TextureClamp;
	}

	if(mlrState.GetRenderDeltaMask() & MLRState::TextureWrapMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetTextureWrap(TextureWrapMode texWrap)
{
	Check_Object(this);

	if(texWrap == StateProxy::TextureWrap)
	{
		mlrState.SetTextureWrapMode(MLRState::TextureWrap);
	}
	else
	{
		mlrState.SetTextureWrapMode(MLRState::TextureClamp);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetTextureWrapChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::TextureWrapMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetTextureWrapChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::TextureWrapMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::TextureWrapMask
		);
	}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetWireFrame(WireFrameMode *wireFrame)
{
	Check_Object(this);
	Check_Pointer(wireFrame);

	switch(mlrState.GetWireFrameMode())
	{
		case MLRState::WireFrameOffMode:
			*wireFrame = StateProxy::WireFrameOffMode;
		break;
		case MLRState::WireFrameOnlyMode:
			*wireFrame = StateProxy::WireFrameOnlyMode;
		break;
		case MLRState::WireFrameAddMode:
			*wireFrame = StateProxy::WireFrameAddMode;
		break;
	}

	if(mlrState.GetRenderDeltaMask() & MLRState::WireFrameMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetWireFrame(WireFrameMode wireFrame)
{
	Check_Object(this);

	switch(wireFrame)
	{
		case StateProxy::WireFrameOffMode:
			mlrState.SetWireFrameMode(MLRState::WireFrameOffMode);
		break;
		case StateProxy::WireFrameOnlyMode:
			mlrState.SetWireFrameMode(MLRState::WireFrameOnlyMode);
		break;
		case StateProxy::WireFrameAddMode:
			mlrState.SetWireFrameMode(MLRState::WireFrameAddMode);
		break;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetWireFrameChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::WireFrameMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetWireFrameChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::WireFrameMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::WireFrameMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetZBufferCompare(bool *z)
{
	Check_Object(this);
	Check_Pointer(z);

	*z = (mlrState.GetZBufferCompareMode() == MLRState::ZBufferCompareOnMode) ? true : false;

	if(mlrState.GetRenderDeltaMask() & MLRState::ZBufferCompareMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetZBufferCompare(bool z)
{
	Check_Object(this);

	if(z==true)
	{
		mlrState.SetZBufferCompareOn();
	}
	else
	{
		mlrState.SetZBufferCompareOff();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetZBufferCompareChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::ZBufferCompareMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetZBufferCompareChildPermission(bool override)
{
	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::ZBufferCompareMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::ZBufferCompareMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetZBufferWrite(bool *z)
{
	Check_Object(this);
	Check_Pointer(z);

	*z = (mlrState.GetZBufferWriteMode() == MLRState::ZBufferWriteOnMode) ? true : false;

	if(mlrState.GetRenderDeltaMask() & MLRState::ZBufferWriteMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetZBufferWrite(bool z)
{
	Check_Object(this);

	if(z==true)
	{
		mlrState.SetZBufferWriteOn();
	}
	else
	{
		mlrState.SetZBufferWriteOff();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetZBufferWriteChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::ZBufferWriteMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetZBufferWriteChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::ZBufferWriteMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::ZBufferWriteMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetFlatColoring(bool *z)
{
	Check_Object(this);
	Check_Pointer(z);

	*z = (mlrState.GetFlatColoringMode() == MLRState::FlatColoringOnMode) ? true : false;

	if(mlrState.GetRenderDeltaMask() & MLRState::FlatColoringMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetFlatColoring(bool z)
{
	Check_Object(this);

	if(z==true)
	{
		mlrState.SetFlatColoringOn();
	}
	else
	{
		mlrState.SetFlatColoringOff();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetFlatColoringChildPermission()
{
	Check_Object(this);

	return mlrState.GetRenderPermissionMask() & MLRState::FlatColoringMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetFlatColoringChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() & ~MLRState::FlatColoringMask
		);
	}
	else
	{
		mlrState.SetRenderPermissionMask(
			mlrState.GetRenderPermissionMask() | MLRState::FlatColoringMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetBackface(bool *onOff)
{
	Check_Object(this);
	Check_Pointer(onOff);

	if(mlrState.GetBackFaceMode() == MLRState::BackFaceOnMode)
	{
		*onOff = true;
	}
	else
	{
		*onOff = false;
	}

	if(mlrState.GetProcessDeltaMask() & MLRState::BackFaceMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetBackface(bool onOff)
{
	Check_Object(this);

	if(onOff==true)
	{
		mlrState.SetBackFaceOn();
	}
	else
	{
		mlrState.SetBackFaceOff();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetBackfaceChildPermission()
{
	Check_Object(this);

	return mlrState.GetProcessPermissionMask() & MLRState::BackFaceMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetBackfaceChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetProcessPermissionMask(
			mlrState.GetProcessPermissionMask() & ~MLRState::BackFaceMask
		);
	}
	else
	{
		mlrState.SetProcessPermissionMask(
			mlrState.GetProcessPermissionMask() | MLRState::BackFaceMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetMatTwoSided(bool *onOff)
{
	Check_Object(this);
	Check_Pointer(onOff);

	if(mlrState.GetMatTwoSidedMode() == MLRState::MatTwoSidedOnMode)
	{
		*onOff = true;
	}
	else
	{
		*onOff = false;
	}

	if(mlrState.GetProcessDeltaMask() & MLRState::MatTwoSidedMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetMatTwoSided(bool onOff)
{
	Check_Object(this);

	if(onOff==true)
	{
		mlrState.SetMatTwoSidedOn();
	}
	else
	{
		mlrState.SetMatTwoSidedOff();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetMatTwoSidedChildPermission()
{
	Check_Object(this);

	return mlrState.GetProcessPermissionMask() & MLRState::MatTwoSidedMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetMatTwoSidedChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetProcessPermissionMask(
			mlrState.GetProcessPermissionMask() & ~MLRState::MatTwoSidedMask
		);
	}
	else
	{
		mlrState.SetProcessPermissionMask(
			mlrState.GetProcessPermissionMask() | MLRState::MatTwoSidedMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetPriority(int *priority)
{
	Check_Object(this);
	Check_Pointer(priority);

	*priority = mlrState.GetPriority();

	if(mlrState.GetProcessDeltaMask() & MLRState::PriorityMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetPriority(int priority)
{
	Check_Object(this);

	mlrState.SetPriority(priority);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetPriorityChildPermission()
{
	Check_Object(this);

	return mlrState.GetProcessPermissionMask() & MLRState::PriorityMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetPriorityChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetProcessPermissionMask(
			mlrState.GetProcessPermissionMask() & ~MLRState::PriorityMask
		);
	}
	else
	{
		mlrState.SetProcessPermissionMask(
			mlrState.GetProcessPermissionMask() | MLRState::PriorityMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetLighting(int *lightingMode)
{
	Check_Object(this);
	Check_Pointer(lightingMode);

	int mlr_mode = mlrState.GetLightingMode();
	*lightingMode = 0;
	if (mlr_mode&MLRState::LightMapLightingMode)
		*lightingMode |= LightingLightMapMode;
	if (mlr_mode&MLRState::VertexLightingMode)
		*lightingMode |= LightingVertexMode;
	if (mlr_mode&MLRState::LookupLightingMode)
		*lightingMode |= LightingLookupMode;
	if (mlr_mode&MLRState::FaceLightingMode)
		*lightingMode |= LightingFaceMode;

	if(mlrState.GetProcessDeltaMask() & MLRState::LightingMask)
	{
		return true;
	}

	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetLighting(int lightingMode)
{
	Check_Object(this);

	int mlr_mode = 0;
	if (lightingMode&LightingLightMapMode)
		mlr_mode |= MLRState::LightMapLightingMode;
	if (lightingMode&LightingVertexMode)
		mlr_mode |= MLRState::VertexLightingMode;
	if (lightingMode&LightingLookupMode)
		mlr_mode |= MLRState::LookupLightingMode;
	if (lightingMode&LightingFaceMode)
		mlr_mode |= MLRState::FaceLightingMode;
	mlrState.SetLightingMode(mlr_mode);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetLightingChildPermission()
{
	Check_Object(this);

	return mlrState.GetProcessPermissionMask() & MLRState::LightingMask ? true : false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetLightingChildPermission(bool override)
{
	Check_Object(this);

	if(override == true)
	{
		mlrState.SetProcessPermissionMask(
			mlrState.GetProcessPermissionMask() & ~MLRState::LightingMask
		);
	}
	else
	{
		mlrState.SetProcessPermissionMask(
			mlrState.GetProcessPermissionMask() | MLRState::LightingMask
		);
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MLRStateProxy::GetSpecularColor(RGBColor *color)
{
	Check_Object(this);
	Check_Pointer(color);

//	STOP(("Not implemented"));
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetSpecularColor(const RGBColor &color)
{
	Check_Object(this);
	Check_Object(&color);
//	STOP(("Not implemented"));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Scalar
	MLRStateProxy::GetSpecularShininess()
{
	Check_Object(this);
//	STOP(("Not implemented"));
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStateProxy::SetSpecularShininess(Scalar shininess)
{
	Check_Object(this);
	Verify(shininess >= 0.0f && shininess <= 1.0f);
//	STOP(("Not implemented"));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TextureProxy*
	MLRStateProxy::UseTextureProxy()
{
	Check_Object(this);

	//
	//--------------------------
	// Return the state proxy
	//--------------------------
	//
	StateLibrary *states = GetStateLibrary();
	Check_Object(states);
	MLRTexturePoolProxy *library =
		Cast_Object(MLRTexturePoolProxy*, states->GetTextureLibrary());
	Check_Object(&mlrState);
	unsigned texture_handle = mlrState.GetTextureHandle();
	if (!texture_handle)
		return NULL;
	MLRTexture *mlr_texture = (*MLRTexturePool::Instance)[texture_handle];
	Check_Object(mlr_texture);
	return library->UseTextureProxy(mlr_texture->GetProxyNumber());
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TextureProxy*
	MLRStateProxy::SetToMatchTextureProxy(TextureProxy *texture)
{
	Check_Object(this);
	Check_Object(texture);

	Check_Object(&mlrState);
	MLRTextureProxy *MLRTexture = Cast_Object(MLRTextureProxy *,texture);

	MidLevelRenderer::MLRTexture *tex = MLRTexture->GetMLRTexture();
	mlrState.SetTextureHandle(tex->GetTextureHandle());

	return texture;
	//
	//----------------------------------------
	// Have the texture library make our proxy
	//----------------------------------------
	//
	STOP(("Not implemented"));
	return NULL;
#if 0
	MGPolygonMesh *mesh = GetPolygonMeshProxy();
	Check_Object(mesh);
	MGScene *database = mesh->GetSceneProxy();
	Check_Object(database);
	MGTextureLibrary *library =
		Cast_Object(MGTextureLibrary*, database->GetTextureLibrary());
	MGTexture *proxy =
		Cast_Object(
			MGTexture*,
			library->UseMatchingTextureProxy(texture)
		);

	//
	//----------------------------------------
	// Set our polyon to point at this texture
	//----------------------------------------
	//
	int count =
		mgSetAttList(
			proxiedPolygon,
			fltPolyTexture, static_cast<short>(proxy->GetTextureIndex()),
			mgNULL
		);
	Verify(count == 1);

	//
	//------------------------------------------------------------------
	// If the texture has an alpha channel, enable alpha blending on the
	// polygon
	//------------------------------------------------------------------
	//
	unsigned red,green,blue,alpha;
	proxy->GetChannelDepth(&red, &green, &blue, &alpha);
	if (alpha)
	{
		count = 
			mgSetAttList(
				proxiedPolygon,
				fltPolyMgTemplate, static_cast<char>(1),
				mgNULL
			);
		Verify(count == 1);
	}
	return proxy;
#endif
}

//
//############################################################################
//############################    MLRStateProxy    ##############################
//############################################################################
//

MLRStatePoolProxy::ClassData*
	MLRStatePoolProxy::DefaultData = NULL;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStatePoolProxy::InitializeClass()
{
	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			MLRStatePoolProxyClassID,
			"MLRStatePoolProxy",
			StateLibrary::DefaultData
		);
	Register_Object(DefaultData);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStatePoolProxy::TerminateClass()
{
	Unregister_Object(DefaultData);
	delete DefaultData;
	DefaultData = NULL;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStatePoolProxy::Destroy()
{
	Check_Object(this);
	Verify(referenceCount == 1);
	Verify(activeStateProxies.IsEmpty());
//	STOP(("Not implemented"));
	DetachReference();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRStatePoolProxy::MLRStatePoolProxy(
	ElementSceneProxy *scene,
	const char *path
):
	StateLibrary(DefaultData, scene),
	proxiedStates(101, NULL, true)
{
	Check_Pointer(this);
	Check_Object(scene);
	textureLibrary = MLRTexturePoolProxy::Instance;
	if (!textureLibrary)
	{
		textureLibrary = MLRTexturePoolProxy::MakeProxy(this, path);
		Register_Object(textureLibrary);
	}
	Check_Object(this);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRStatePoolProxy::MLRStatePoolProxy(ElementSceneProxy *scene):
	StateLibrary(DefaultData, scene),
	proxiedStates(101, NULL, true)
{
	Check_Pointer(this);
	Check_Object(scene);
	textureLibrary = MLRTexturePoolProxy::Instance;
	if (!textureLibrary)
	{
		textureLibrary = MLRTexturePoolProxy::MakeProxy(this);
		Register_Object(textureLibrary);
	}
	Check_Object(this);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MLRStatePoolProxy::~MLRStatePoolProxy()
{
	Check_Object(this);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStatePoolProxy::TestInstance() const
{
	Verify(IsDerivedFrom(DefaultData));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
StateProxy*
	MLRStatePoolProxy::UseMatchingStateProxy(
		StateProxy *state,
		TextureProxy *texture
	)
{
	Check_Object(this);
	Check_Object(state);

	//
	//------------------------------------
	// See if this state needs to be added
	//------------------------------------
	//
	MLRState mlr_state;
	CalculateMLRState(&mlr_state, state, texture);
	MLRStateProxy *our_state = proxiedStates.Find(mlr_state);
	if (!our_state)
	{
		our_state = MLRStateProxy::MakeProxy(this, mlr_state);
		Register_Object(our_state);
		proxiedStates.AddValue(our_state, mlr_state);
	}
	our_state->AttachReference();
	return our_state;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStatePoolProxy::CalculateMLRState(
		MLRState *state,
		StateProxy *proxy,
		TextureProxy *texture
	)
{
	Check_Object(this);
	Check_Pointer(state);
	Check_Object(proxy);

	//
	//-----------------------------------------------------------------------
	// Find the texture proxy from the state proxy unless there is a specific
	// texture override
	//-----------------------------------------------------------------------
	//
	if (!texture)
		texture = proxy->UseTextureProxy();
	else
	{
		Check_Object(texture);
		texture->AttachReference();
	}

	//
	//-------------------------------------------------------------------
	// Figure out if the texture is keyed, 
	// used to override alpha mode and render priority
	//-------------------------------------------------------------------
	//
	bool bKeyed = false;
	if (texture)
	{
		Proxies::TextureProxy::FormatType format;
		if (texture->GetFormat(&format)) {
			if (format == Proxies::TextureProxy::KeyedTexture)
				bKeyed = true;
		}
	}
	
	//
	//---------------------
	// Deal with the states
	//---------------------
	//

	state->SetRenderDeltaMask(0);
	state->SetProcessDeltaMask(0);

	state->SetRenderPermissionMask(0xffffffff);
	state->SetProcessPermissionMask(0xffffffff);

	bool permission, onOff;
	StateProxy::AlphaMode alphaMode;

	if(proxy->GetAlpha(&alphaMode))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::AlphaMask
		);

		switch(alphaMode)
		{
			case StateProxy::OneZeroMode:
				state->SetAlphaMode(MLRState::OneZeroMode);
			break;
			case StateProxy::OneOneMode:
				state->SetAlphaMode(MLRState::OneOneMode);
			break;
			case StateProxy::AlphaOneMode:
				state->SetAlphaMode(MLRState::AlphaOneMode);
			break;
			case StateProxy::OneAlphaMode:
				state->SetAlphaMode(MLRState::OneAlphaMode);
			break;
			case StateProxy::AlphaInvAlphaMode: {
				// If texture is keyed
				// Need to set Alpha mode to KeyedAlphaMode
				if (bKeyed)
					state->SetAlphaMode(MLRState::KeyedAlphaMode);
				else {
					bKeyed = false;
					state->SetAlphaMode(MLRState::AlphaInvAlphaMode);
				}
			}
			break;
			case StateProxy::OneInvAlphaMode:
				state->SetAlphaMode(MLRState::OneInvAlphaMode);
			break;
			case StateProxy::KeyedAlphaMode:
				state->SetAlphaMode(MLRState::KeyedAlphaMode);
			break;
		}
	}

	permission = proxy->GetAlphaChildPermission();
	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::AlphaMask
		);
	}
	else
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::AlphaMask
		);
	}

	StateProxy::FilterMode filterMode;

	if(proxy->GetFilter(&filterMode))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::FilterMask
		);

		switch(filterMode)
		{
			case StateProxy::NoFilterMode:
				state->SetFilterMode(MLRState::NoFilterMode);
			break;
			case StateProxy::BiLinearFilterMode:
				state->SetFilterMode(MLRState::BiLinearFilterMode);
			break;
			case StateProxy::TriLinearFilterMode:
				state->SetFilterMode(MLRState::TriLinearFilterMode);
			break;
		}
	}

	permission = proxy->GetFilterChildPermission();

	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::FilterMask
		);
	}
	else
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::FilterMask
		);
	}

	StateProxy::FogMode fogMode;
	if(proxy->GetFog(&fogMode))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::FogMask
		);
		state->SetFogMode(fogMode);
	}

	permission = proxy->GetFogChildPermission();

	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::FogMask
		);
	}
	else
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::FogMask
		);
	}

	if(proxy->GetDither(&onOff))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::DitherMask
		);

		if(onOff)
		{
			state->SetDitherOn();
		}
		else
		{
			state->SetDitherOff();
		}
	}

	permission = proxy->GetDitherChildPermission();

	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::DitherMask
		);
	}
	else
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::DitherMask
		);
	}

	if(proxy->GetSpecular(&onOff))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::SpecularMask
		);

		if(onOff)
		{
			state->SetSpecularOn();
		}
		else
		{
			state->SetSpecularOff();
		}
	}

	permission = proxy->GetSpecularChildPermission();

	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::SpecularMask
		);
	}
	else
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::SpecularMask
		);
	}

	if(proxy->GetTextureCorrection(&onOff))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::TextureCorrectionMask
		);

		if(onOff)
		{
			state->SetTextureCorrectionOn();
		}
		else
		{
			state->SetTextureCorrectionOff();
		}
	}

	permission = proxy->GetTextureCorrectionChildPermission();

	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::TextureCorrectionMask
		);
	}
	else
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::TextureCorrectionMask
		);
	}

	StateProxy::TextureWrapMode textureWrapMode;

	if(proxy->GetTextureWrap(&textureWrapMode))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::TextureWrapMask
		);

		if(textureWrapMode==StateProxy::TextureWrap)
		{
			state->SetTextureWrapMode(MLRState::TextureWrap);
		}
		else
		{
			state->SetTextureWrapMode(MLRState::TextureClamp);
		}
	}

	permission = proxy->GetTextureWrapChildPermission();

	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::TextureWrapMask
		);
	}
	else
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::TextureWrapMask
		);
	}

	StateProxy::WireFrameMode wireFrameMode;

	if(proxy->GetWireFrame(&wireFrameMode))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::WireFrameMask
		);

		switch(wireFrameMode)
		{
			case StateProxy::WireFrameOffMode:
				state->SetWireFrameMode(MLRState::WireFrameOffMode);
			break;
			case StateProxy::WireFrameOnlyMode:
				state->SetWireFrameMode(MLRState::WireFrameOnlyMode);
			break;
			case StateProxy::WireFrameAddMode:
				state->SetWireFrameMode(MLRState::WireFrameAddMode);
			break;
		}
	}

	permission = proxy->GetWireFrameChildPermission();

	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::WireFrameMask
		);
	}
	else
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::WireFrameMask
		);
	}

	if(proxy->GetZBufferCompare(&onOff))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::ZBufferCompareMask
		);

		if(onOff)
		{
			state->SetZBufferCompareOn();
		}
		else
		{
			state->SetZBufferCompareOff();
		}
	}

	permission = proxy->GetZBufferCompareChildPermission();

	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::ZBufferCompareMask
		);
	}
	else
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::ZBufferCompareMask
		);
	}

	if(proxy->GetZBufferWrite(&onOff))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::ZBufferWriteMask
		);

		if(onOff)
		{
			state->SetZBufferWriteOn();
		}
		else
		{
			state->SetZBufferWriteOff();
		}
	}

	permission = proxy->GetZBufferWriteChildPermission();

	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::ZBufferWriteMask
		);
	}
	else
	{
		state->SetProcessPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::ZBufferWriteMask
		);
	}

	if(proxy->GetFlatColoring(&onOff))
	{
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::FlatColoringMask
		);

		if(onOff)
		{
			state->SetFlatColoringOn();
		}
		else
		{
			state->SetFlatColoringOff();
		}
	}

	permission = proxy->GetFlatColoringChildPermission();

	if(permission==true)
	{
		state->SetRenderPermissionMask(
			state->GetRenderPermissionMask() | MLRState::FlatColoringMask
		);
	}
	else
	{
		state->SetProcessPermissionMask(
			state->GetRenderPermissionMask() & ~MLRState::FlatColoringMask
		);
	}

	// Material two sided
	if(proxy->GetMatTwoSided(&onOff))
	{
		state->SetProcessDeltaMask(
			state->GetProcessDeltaMask() | MLRState::MatTwoSidedMask
		);

		if(onOff)
		{
			state->SetMatTwoSidedOn();
		}
		else
		{
			state->SetMatTwoSidedOff();
		}
	}

	permission = proxy->GetMatTwoSidedChildPermission();

	if(permission==true)
	{
		state->SetProcessPermissionMask(
			state->GetProcessPermissionMask() | MLRState::MatTwoSidedMask
		);
	}
	else
	{
		state->SetProcessPermissionMask(
			state->GetProcessPermissionMask() & ~MLRState::MatTwoSidedMask
		);
	}

	// Back face culling
	if(proxy->GetBackface(&onOff))
	{
		state->SetProcessDeltaMask(
			state->GetProcessDeltaMask() | MLRState::BackFaceMask
		);

		if(onOff)
		{
			state->SetBackFaceOn();
		}
		else
		{
			state->SetBackFaceOff();
		}
	}

	permission = proxy->GetBackfaceChildPermission();

	if(permission==true)
	{
		state->SetProcessPermissionMask(
			state->GetProcessPermissionMask() | MLRState::BackFaceMask
		);
	}
	else
	{
		state->SetProcessPermissionMask(
			state->GetProcessPermissionMask() & ~MLRState::BackFaceMask
		);
	}

	int priority;
	if(proxy->GetPriority(&priority))
	{
		state->SetProcessDeltaMask(
			state->GetProcessDeltaMask() | MLRState::PriorityMask
		);

		state->SetPriority(priority);

		// If texture is keyed
		// Need to set priority to DetailPrority
		if (bKeyed)
			state->SetPriority(MLRState::DetailPrority);
	}

	permission = proxy->GetPriorityChildPermission();

	if(permission==true)
	{
		state->SetProcessPermissionMask(
			state->GetProcessPermissionMask() | MLRState::PriorityMask
		);
	}
	else
	{
		state->SetProcessPermissionMask(
			state->GetProcessPermissionMask() & ~MLRState::PriorityMask
		);
	}

	int lightingMode;

	if(proxy->GetLighting(&lightingMode))
	{
		state->SetProcessDeltaMask(
			state->GetProcessDeltaMask() | MLRState::LightingMask
		);

		int mlr_mode = 0;
		if (lightingMode&StateProxy::LightingLightMapMode)
			mlr_mode |= MLRState::LightMapLightingMode;
		if (lightingMode&StateProxy::LightingVertexMode)
			mlr_mode |= MLRState::VertexLightingMode;
		if (lightingMode&StateProxy::LightingLookupMode)
			mlr_mode |= MLRState::LookupLightingMode;
		if (lightingMode&StateProxy::LightingFaceMode)
			mlr_mode |= MLRState::FaceLightingMode;
		state->SetLightingMode(mlr_mode);
	}

	permission = proxy->GetLightingChildPermission();

	if(permission==true)
	{
		state->SetProcessPermissionMask(
			state->GetProcessPermissionMask() | MLRState::LightingMask
		);
	}
	else
	{
		state->SetProcessPermissionMask(
			state->GetProcessPermissionMask() & ~MLRState::LightingMask
		);
	}

	//
	//----------------------
	// Deal with the texture
	//----------------------
	//
	if (texture)
	{
		Check_Object(texture);
		MLRTexturePoolProxy *textures =
			Cast_Object(MLRTexturePoolProxy*, GetTextureLibrary());
		Check_Object(textures);
		MLRTextureProxy *our_texture =
			Cast_Object(
				MLRTextureProxy*,
				textures->UseMatchingTextureProxy(texture)
			);
		MLRTexture *mlr_texture = our_texture->GetMLRTexture();
		Check_Object(mlr_texture);

		state->SetTextureHandle(mlr_texture->GetTextureHandle());
		state->SetRenderDeltaMask(
			state->GetRenderDeltaMask() | MLRState::TextureMask
		);
		
		our_texture->DetachReference();
		texture->DetachReference();
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MLRStatePoolProxy::CloseLibrary()
{
	Check_Object(this);

	//
	//----------------------------
	// Release the texture manager
	//----------------------------
	//
	textureLibrary = NULL;

	//
	//-----------------------------
	// Now delete our state proxies
	//-----------------------------
	//
	HashIteratorOf<MLRStateProxy*, MLRState> states(&proxiedStates);
	MLRStateProxy *state;
	while ((state = states.ReadAndNext()) != NULL)
	{
		Check_Object(state);
		Verify(state->GetReferenceCount() == 1);
		state->DetachReference();
	}
	Verify(GetReferenceCount() == 1);
}

