#include "MAXProxyHeaders.hpp"
#include <ElementRenderer\StateChange.hpp>

//
//############################################################################
//############################    MAXState    ##############################
//############################################################################
//

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

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

	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			MAXStateClassID,
			"MAXState",
			StateProxy::DefaultData
		);
	Register_Object(DefaultData);
}

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

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

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MAXState::MAXState(
	MAXStateLibrary *library,
	INode *mesh,
	Mtl *material,
	BitmapTex *texture,
	int indice
):
	StateProxy(DefaultData, library),
	meshState(mesh),
	materialState(material),
	textureState(texture),
	mapIndice(indice)
{
	Check_Pointer(this);
	Check_Object(this);
	bAlphaMode = false;
	bFlatShaded = false;
	matID = 0;
	mipmapHint=0;
}

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

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetName(MString *name)
{
	Check_Object(this);
	Check_Object(name);
	name->AllocateLength(0);
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetName(const char* name)
{
	Check_Object(this);
	Check_Pointer(name);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetSpecularColor(RGBColor *color)
{
	return false;
	// Not implemented in MLRSTate
	Check_Object(this);
	Check_Pointer(color);
	if (materialState)
	{
		Check_Pointer(materialState);
		Color matcolor = materialState->GetSpecular();
		color->red = matcolor.r;
		color->green = matcolor.g;
		color->blue = matcolor.b;
		return true;
	}
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetSpecularColor(const RGBColor &color)
{
	Check_Object(this);
	Check_Object(&color);
	
	Check_Pointer(materialState);
	Color matcolor;
	matcolor.r = color.red;
	matcolor.g = color.green;
	matcolor.b = color.blue;
	// TODO:  What about animated textures?
	materialState->SetSpecular(matcolor,0);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Scalar
	MAXState::GetSpecularShininess()
{
	Check_Object(this);
	if (materialState)
	{
		Check_Pointer(materialState);
		return materialState->GetShininess();
	}
	return 0.0;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetSpecularShininess(Scalar shininess)
{
	Check_Object(this);
	Check_Pointer(materialState);
	materialState->SetShininess(shininess,0);
	STOP(("SetSpecularShininess not implemented"));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetSpecular(bool *bval)
{
	Check_Object(this);
	if (materialState)
	{
		Check_Pointer(materialState);
		if (materialState->SubTexmapOn(ID_SP))
		{
			*bval = true;
			return true;
		}
	}
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetSpecular(bool)
{
	Check_Object(this);
	// Needs to set the texmap flag to on
	//STOP(("SetSpecular not implemented"));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetSpecularChildPermission()
{
	Check_Object(this);
	return true;
}

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


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// this routine was done the hard way because it is a quick hack to include
// multi - texture.  It will be rewritten when the God's above decide how
// multi - texture will be implemented and used - BDB
//
bool
	MAXState::GetAlpha(Proxies::StateProxy::AlphaMode *alpha_mode)
{
	Check_Object(this);
	if (NULL == materialState)
		return false;

	if (0==mipmapHint)
	{
		mipmapHint=1;
		char *name = materialState->GetName();
		
		MAXStateLibrary *max_states = GetStateLibrary();
		Check_Object(max_states);
		MAXScene *scene = max_states->GetSceneProxy();

		Page *page = scene->FindHint(name);
		if (page)
		{
			const char *entry;
			if (page->GetEntry("MipMap",&entry))
			{
				if (strnicmp(entry,"None",4)==0)
				{
					mipmapHint++;
				}
			}
		}
	}

	if (mipmapHint)
	{
		if (mipmapHint>1)
		{
			*alpha_mode = Proxies::StateProxy::AlphaMode::OneZeroMode;
			return true;
		}
	}

	Check_Pointer(materialState);
	if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
	{
		if ((Cast_Pointer(StdMat*, materialState)->GetTransparencyType() == TRANSP_ADDITIVE))
		{
			*alpha_mode = Proxies::StateProxy::AlphaMode::OneOneMode;
			if (bAlphaMode || materialState->SubTexmapOn(ID_OP))
				*alpha_mode = Proxies::StateProxy::AlphaMode::AlphaOneMode;
			return true;
		}

	}
	else if (materialState->ClassID() == Class_ID(MULTI_CLASS_ID,0))
	{
		int number_sub_materials = materialState->NumSubMtls();
		for (int w=0;w<number_sub_materials;w++)
		{
			Mtl* sub = materialState->GetSubMtl(w);
			if ((Cast_Pointer(StdMat*, sub)->GetTransparencyType() == TRANSP_ADDITIVE))
			{
				*alpha_mode = Proxies::StateProxy::AlphaMode::OneOneMode;
				if (bAlphaMode || materialState->SubTexmapOn(ID_OP))
					*alpha_mode = Proxies::StateProxy::AlphaMode::AlphaOneMode;
				return true;
			}
		}
	}
	if (bAlphaMode || materialState->SubTexmapOn(ID_OP))
	{
		*alpha_mode = Proxies::StateProxy::AlphaMode::AlphaInvAlphaMode;
		return true;
	}
	*alpha_mode = Proxies::StateProxy::AlphaMode::OneZeroMode;
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetAlpha(Proxies::StateProxy::AlphaMode alpha)
{
	Check_Object(this);
	Check_Pointer(materialState);
	switch (alpha)
	{
	case Proxies::StateProxy::AlphaMode::OneOneMode:
		{
			// Set the material to additive
			if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
			{
				if ((Cast_Pointer(StdMat*, materialState)->GetTransparencyType() == TRANSP_ADDITIVE))
				{
					int x=1;
				}
				Cast_Pointer(StdMat*, materialState)->SetTransparencyType(TRANSP_ADDITIVE);
			}
			else if (materialState->ClassID() == Class_ID(MULTI_CLASS_ID,0))
			{
				int number_sub_materials = materialState->NumSubMtls();
				for (int w=0;w<number_sub_materials;w++)
				{
					Mtl* sub = materialState->GetSubMtl(w);
					Cast_Pointer(StdMat*, sub)->SetTransparencyType(TRANSP_ADDITIVE);
				}
			}
			break;
		}
	case Proxies::StateProxy::AlphaMode::OneZeroMode:
		{
			//Check_Pointer(textureState);
			// Set to texture to AlphaNone
			//textureState->SetAlphaSource(ALPHA_NONE);
			break;
		}
	case Proxies::StateProxy::AlphaMode::AlphaInvAlphaMode:
	case Proxies::StateProxy::AlphaMode::KeyedAlphaMode:
		{
			bAlphaMode = true;

			//Check_Pointer(materialState);
			Texmap *tex = materialState->GetSubTexmap(ID_DI);

			if (tex && tex->ClassID() == Class_ID(BMTEX_CLASS_ID,0))
			{
				BitmapTex *bmtex = (BitmapTex*)tex;
				bmtex->SetAlphaAsMono(true);
				bmtex->SetAlphaSource(ALPHA_NONE);
			}
			materialState->SetSubTexmap(ID_OP,tex);
		/*	materialState->EnableMap(ID_OP, TRUE);
			materialState->SetTexmapAmt(ID_OP, 1.f, 0);*/
			break;
		}
	default:
		STOP(("SetAlpha, mode not supported"));
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetAlphaChildPermission()
{
	Check_Object(this);
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetAlphaChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetFilter(FilterMode *filter_mode)
{
	Check_Object(this);
	if (materialState)
	{
		Check_Pointer(materialState);
		// TODO: What about multi-texture???
		Texmap *texmap = materialState->GetSubTexmap(ID_DI);
		if (texmap)
		{
			Check_Pointer(texmap);
			if (texmap->ClassID() == Class_ID(BMTEX_CLASS_ID,0))
			{
				switch ( ((BitmapTex*)texmap)->GetFilterType())
				{
				case FILTER_PYR:
					{
						*filter_mode = Proxies::StateProxy::FilterMode::TriLinearFilterMode;
						break;
					}
				case FILTER_SAT:
					{
						*filter_mode = Proxies::StateProxy::FilterMode::BiLinearFilterMode;
						break;
					}
				case FILTER_NADA:
					{
						*filter_mode = Proxies::StateProxy::FilterMode::NoFilterMode;
						break;
					}
				default:
					{
						STOP(("Invalid Filter Type"));
					}
				}

				// Should let always let decide filter type
				return false;
			}
		}
	}
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetFilter(FilterMode mode)
{
	Check_Object(this);
	Check_Pointer(materialState);
		// TODO: What about multi-texture???
	Texmap *texmap = materialState->GetSubTexmap(ID_DI);
	if (texmap)
	{
		Check_Pointer(texmap);
		if (texmap->ClassID() == Class_ID(BMTEX_CLASS_ID,0))
		{
			int filter = 0;
			switch ( mode)
			{
			case Proxies::StateProxy::FilterMode::TriLinearFilterMode:
				{
					filter = FILTER_PYR;
					break;
				}
			case Proxies::StateProxy::FilterMode::BiLinearFilterMode:
				{
					filter = FILTER_SAT;
					break;
				}
			case Proxies::StateProxy::FilterMode::NoFilterMode:
				{
					filter = FILTER_NADA;
					break;
				}
			default:
				{
					STOP(("Invalid Filter Type"));
				}
			}
			((BitmapTex*)texmap)->SetFilterType(filter);
		}
		else
		{
			STOP(("SetFilter: Diffuse Material map must have a bitmap texture"));
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetFilterChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetFilterChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetFog(FogMode *fog_on)
{
	Check_Object(this);
  //
  // Art is using self-illumination to prevent lighting, and this automatically turns on fog
  // they want to have the option of turning it off explicitely so we are checking for this first
  //
  // While I'm here I will enable all the values
  //
	if (meshState)
	{
		Check_Pointer(meshState);
		char *name = meshState->GetName();
		TSTR value;
		TSTR key="FOGMODESETTING";
		if (meshState->GetUserPropString(key,value))
		{
			bool bValid = false;
			if ('0' == value[0])
			{
				*fog_on = DisableFogMode;
				bValid = true;
			}
			if ('1' == value[0])
			{
				*fog_on = GeneralFogMode;
				bValid = true;
			}
			if ('2' == value[0])
			{
				*fog_on = LightFogMode;
				bValid = true;
			}
			if ('3' == value[0])
			{
				*fog_on = CustomFogMode;
				bValid = true;
			}
			if (bValid)
				return true;
		}
	}
	if (materialState)
	{
    float fval = materialState->GetSelfIllum(0);
    if (fval > 0.0f)
    {
   		*fog_on = LightFogMode;
       return true;
    }
		  // Check that Self-Illumination is checked

  //			float fval = 0.0f;
  //	if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
  //	{
  //		fval = Cast_Pointer(StdMat*, materialState)->GetTexmapAmt(ID_SI,0);
  //	}
  //
  //  if (/*materialState->SubTexmapOn(ID_SI) || */fval > 0.0f)
  //
  //		//if (materialState->SubTexmapOn(ID_SI))
  //		{
  //			*fog_on = LightFogMode;
  //			return true;
  //		}
  }
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetFog(FogMode mode)
{
/*	STOP(("Not Implemented"));
	Check_Object(this);
	Check_Pointer(materialState);
	if (LightFogMode == mode)
	{
		if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
		{
			if ((Cast_Pointer(StdMat*, materialState)->GetTransparencyType() == TRANSP_ADDITIVE))
				{
					int x=1;
				}
			Cast_Pointer(StdMat*, materialState)->SetTransparencyType(TRANSP_ADDITIVE);
		}
		else if (materialState->ClassID() == Class_ID(MULTI_CLASS_ID,0))
		{
			int number_sub_materials = materialState->NumSubMtls();
			for (int w=0;w<number_sub_materials;w++)
			{
				Mtl* sub = materialState->GetSubMtl(w);
		
				Cast_Pointer(StdMat*, sub)->SetTransparencyType(TRANSP_ADDITIVE);
			}
		}
	}*/
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetFogChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetFogChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetDither(bool *dither_on)
{
	return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetDither(bool)
{
	Check_Object(this);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetDitherChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetDitherChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetTextureCorrection(bool *correction_on)
{
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetTextureCorrection(bool)
{
	Check_Object(this);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetTextureCorrectionChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetTextureCorrectionChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetTextureWrap(TextureWrapMode* mode)
{
	Check_Object(this);
	if (materialState)
	{
		Check_Pointer(materialState);
		Texmap *texmap = materialState->GetSubTexmap(ID_DI);
		if (texmap)
		{
			Check_Pointer(texmap);
			UVGen *gen = texmap->GetTheUVGen();
			if (gen)
			{
				Check_Pointer(gen);
				int tiling = gen->GetTextureTiling();
				if ((tiling & U_WRAP) && (tiling & V_WRAP))
				{
					*mode = TextureWrap;
					return true;
				}
				else
				{
					*mode = TextureClamp;
					return true;
				}
			}
		}
	}
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetTextureWrap(TextureWrapMode)
{
	Check_Object(this);
	// TODO: does import need this?
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetTextureWrapChildPermission()
{
	Check_Object(this);
	return true;
}

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetWireFrame(WireFrameMode *wireframe_mode)
{
	Check_Object(this);
	if (NULL == materialState)
		return false;
	Check_Pointer(materialState);
	ULONG mat_requirements = materialState->Requirements(-1);

	if (mat_requirements & MTLREQ_WIRE)
	{
		*wireframe_mode = Proxies::StateProxy::WireFrameMode::WireFrameOnlyMode;
	}
	else
	{
		*wireframe_mode = Proxies::StateProxy::WireFrameMode::WireFrameOffMode;
	}
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetWireFrame(WireFrameMode mode)
{
	Check_Object(this);
	Check_Pointer(materialState);
	//if (LightFogMode == mode)
	{
		if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
		{
			Cast_Pointer(StdMat*, materialState)->SetWire(Proxies::StateProxy::WireFrameMode::WireFrameOnlyMode == mode?true:false);
		}
		else if (materialState->ClassID() == Class_ID(MULTI_CLASS_ID,0))
		{
			int number_sub_materials = materialState->NumSubMtls();
			for (int w=0;w<number_sub_materials;w++)
			{
				Mtl* sub = materialState->GetSubMtl(w);
		
				Cast_Pointer(StdMat*, sub)->SetWire(Proxies::StateProxy::WireFrameMode::WireFrameOnlyMode == mode?true:false);
			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetWireFrameChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetWireFrameChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetZBufferCompare(bool *z_compare)
{
	Check_Object(this);
	if (meshState)
	{
		Check_Pointer(meshState);
		char *name = meshState->GetName();
		TSTR value;
		TSTR key="ZBUFFERCOMPARE";
		if (meshState->GetUserPropString(key,value))
		{
			bool bValid = false;
			if ('1' == value[0])
			{
				*z_compare = true;
				bValid = true;
			}
			if ('0' == value[0])
			{
				*z_compare = false;
				bValid = true;
			}
			if (bValid)
				return true;
		}
	}

	*z_compare = true;
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetZBufferCompare(bool)
{
	Check_Object(this);
	//STOP(("SetZBufferCompare Not implemented"));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetZBufferCompareChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetZBufferCompareChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetZBufferWrite(bool *z_write)
{
	Check_Object(this);
	if (meshState)
	{
		Check_Pointer(meshState);
		char *name = meshState->GetName();
		TSTR value;
		TSTR key="ZBUFFERWRITE";
		if (meshState->GetUserPropString(key,value))
		{
			bool bValid = false;
			if ('1' == value[0])
			{
				*z_write = true;
				bValid = true;
			}
			if ('0' == value[0])
			{
				*z_write = false;
				bValid = true;
			}
			if (bValid)
				return true;
		}
	}
	if (NULL == materialState)
		return false;
	if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
	{
		if ((Cast_Pointer(StdMat*, materialState)->GetTransparencyType() == TRANSP_ADDITIVE))
		{
			*z_write = false;
			return true;
		}

	}
	else if (materialState->ClassID() == Class_ID(MULTI_CLASS_ID,0))
	{
		int number_sub_materials = materialState->NumSubMtls();
		for (int w=0;w<number_sub_materials;w++)
		{
			Mtl* sub = materialState->GetSubMtl(w);
			if ((Cast_Pointer(StdMat*, sub)->GetTransparencyType() == TRANSP_ADDITIVE))
			{
				*z_write = false;
				return true;
			}
		}
	}

	*z_write = true;
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetZBufferWrite(bool)
{
	Check_Object(this);
	//STOP(("SetZBufferWrite Not implemented"));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetZBufferWriteChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetZBufferWriteChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetFlatColoring(bool *flat)
{
	Check_Object(this);
	*flat = bFlatShaded;
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetFlatColoring(bool flat)
{
	bFlatShaded = flat;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetFlatColoringChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetFlatColoringChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetMatTwoSided(bool *onOff)
{
	Check_Object(this);
	if (NULL == materialState)
		return false;
	Check_Pointer(materialState);
	ULONG mat_requirements = materialState->Requirements(-1);

	*onOff = (mat_requirements & MTLREQ_2SIDE)?true:false;
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetMatTwoSided(bool onOff)
{
	Check_Object(this);
	if (onOff)
	{
		Check_Pointer(materialState);
		if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
		{
			Cast_Pointer(StdMat*, materialState)->SetTwoSided(true);
		}
		else if (materialState->ClassID() == Class_ID(MULTI_CLASS_ID,0))
		{
			int number_sub_materials = materialState->NumSubMtls();
			for (int w=0;w<number_sub_materials;w++)
			{
				Mtl* sub = materialState->GetSubMtl(w);
				Cast_Pointer(StdMat*, sub)->SetTwoSided(true);
			}
		}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetMatTwoSidedChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetMatTwoSidedChildPermission(bool override)
{
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetBackface(bool *onOff)
{
	Check_Object(this);
	if (NULL == meshState)
		return false;
	Check_Pointer(meshState);

	*onOff = meshState->GetBackCull()?true:false;
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetBackface(bool onOff)
{
	Check_Object(this);
	if (NULL == meshState)
		return;
	Check_Pointer(meshState);

	meshState->BackCull(onOff);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetBackfaceChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetBackfaceChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetPriority(int *priority)
{
	Check_Object(this);
	if (NULL == materialState)
		return false;
	Check_Pointer(materialState);

	if (meshState)
	{
		Check_Pointer(meshState);
		char *name = meshState->GetName();
		TSTR value;
		TSTR key="PRIORITY";
		if (meshState->GetUserPropString(key,value))
		{
			bool bValid = false;
			if (0==stricmp(value,"CagePriority"))
			{
				*priority =	Proxies::StateProxy::CagePriority;
				bValid = true;
			}
			else if (0==stricmp(value,"CageDashPriority"))
			{
				*priority =	Proxies::StateProxy::CageEffectsPriority;
				bValid = true;
			}
			else if (0==stricmp(value,"CageEffectsPriority"))
			{
				*priority =	Proxies::StateProxy::FlarePriority;
				bValid = true;
			}
			else if (0==stricmp(value,"HUDPriority0"))
			{
				*priority =	Proxies::StateProxy::HUDPriority0;
				bValid = true;
			}
			else if (0==stricmp(value,"HUDPriority1"))
			{
				*priority =	Proxies::StateProxy::HUDPriority1;
				bValid = true;
			}
			else if (0==stricmp(value,"HUDPriority2"))
			{
				*priority =	Proxies::StateProxy::HUDPriority2;
				bValid = true;
			}
			else if (0==stricmp(value,"HUDPriority3"))
			{
				*priority =	Proxies::StateProxy::HUDPriority3;
				bValid = true;
			}

			if (bValid)
				return true;
		}
	}

	if (0==mipmapHint)
	{
		mipmapHint=1;
		char *name = materialState->GetName();
		
		MAXStateLibrary *max_states = GetStateLibrary();
		Check_Object(max_states);
		MAXScene *scene = max_states->GetSceneProxy();

		Page *page = scene->FindHint(name);
		if (page)
		{
			const char *entry;
			if (page->GetEntry("MipMap",&entry))
			{
				if (strnicmp(entry,"None",4)==0)
				{
					mipmapHint++;
				}
			}
		}
	}
	if (mipmapHint)
	{
		if (mipmapHint>1)
		{
			*priority =	Proxies::StateProxy::DetailPrority;
			return true;
		}
	}

	if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
	{
		if ((Cast_Pointer(StdMat*, materialState)->GetTransparencyType() == TRANSP_ADDITIVE))
			{
				*priority =	Proxies::StateProxy::AlphaPriority;
				return true;
			}

	}
	else if (materialState->ClassID() == Class_ID(MULTI_CLASS_ID,0))
	{
		int number_sub_materials = materialState->NumSubMtls();
		for (int w=0;w<number_sub_materials;w++)
		{
			Mtl* sub = materialState->GetSubMtl(w);
			if ((Cast_Pointer(StdMat*, sub)->GetTransparencyType() == TRANSP_ADDITIVE))
				{
					*priority =	Proxies::StateProxy::AlphaPriority;
					return true;
				}
		}
	}
	
	if (bAlphaMode || materialState->SubTexmapOn(ID_OP))
	{
		*priority = Proxies::StateProxy::AlphaPriority;
	}
	else
	{
		*priority = Proxies::StateProxy::DefaultPriority;
	}
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetPriority(int priority)
{
	//STOP(("Not Implemented"));
	Check_Object(this);
	switch (priority)
	{
	case Proxies::StateProxy::AlphaPriority:
		{
			bAlphaMode = true;
			break;
		}
	}
/*	if (Proxies::StateProxy::AlphaPriority == priority)
	{
		// Either set the alphasource to ALPHA_FILE or set the transparency to TRANSP_ADDITIVE
// Set the material to additive
		if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
		{
			if ((Cast_Pointer(StdMat*, materialState)->GetTransparencyType() == TRANSP_ADDITIVE))
				{
					int x=1;
				}
			Cast_Pointer(StdMat*, materialState)->SetTransparencyType(TRANSP_ADDITIVE);
		}
		else if (materialState->ClassID() == Class_ID(MULTI_CLASS_ID,0))
		{
			int number_sub_materials = materialState->NumSubMtls();
			for (int w=0;w<number_sub_materials;w++)
			{
				Mtl* sub = materialState->GetSubMtl(w);
				Cast_Pointer(StdMat*, sub)->SetTransparencyType(TRANSP_ADDITIVE);
			}
		}
	}*/
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetPriorityChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetPriorityChildPermission(bool override)
{
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetLighting(int *lighting_mode)
{
	Check_Object(this);
	if (NULL == materialState)
		return false;
	Check_Pointer(materialState);

//	float fval = 0.0f;
//	if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
//	{
//		fval = Cast_Pointer(StdMat*, materialState)->GetTexmapAmt(ID_SI,0);
//	}

//  if (materialState->SubTexmapOn(ID_SI) && (fval > 0.0f))
//  {
//     *lighting_mode = Proxies::StateProxy::LightingMode::LightingOffMode;
//     return true;
//  }
  float fval = materialState->GetSelfIllum(0);
  if (fval > 0.0f)
  {
     *lighting_mode = Proxies::StateProxy::LightingMode::LightingOffMode;
     return true;
  }
  
  
//	*lighting_mode = (materialState->SubTexmapOn(ID_SI))?Proxies::StateProxy::LightingMode::LightingFaceMode
//		:Proxies::StateProxy::LightingMode::LightingOffMode;
//	return true;
  return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetLighting(int lighting_mode)
{
	Check_Object(this);
/*	if (Proxies::StateProxy::LightingMode::LightingOffMode == lighting_mode)
	{
	// Set the material to additive
		if (materialState->ClassID() == Class_ID(DMTL_CLASS_ID,0))
		{
			if ((Cast_Pointer(StdMat*, materialState)->GetTransparencyType() == TRANSP_ADDITIVE))
				{
					int x=1;
				}
			Cast_Pointer(StdMat*, materialState)->SetTransparencyType(TRANSP_ADDITIVE);
		}
		else if (materialState->ClassID() == Class_ID(MULTI_CLASS_ID,0))
		{
			int number_sub_materials = materialState->NumSubMtls();
			for (int w=0;w<number_sub_materials;w++)
			{
				Mtl* sub = materialState->GetSubMtl(w);
				Cast_Pointer(StdMat*, sub)->SetTransparencyType(TRANSP_ADDITIVE);
			}
		}
	}*/
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetLightingChildPermission()
{
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXState::SetLightingChildPermission(bool override)
{
}

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

	//
	//--------------------------
	// Return the state proxy
	//--------------------------
	//
	Proxies::StateLibrary *states = GetStateLibrary();
	Check_Object(states);

	MAXStateLibrary *max_states = GetStateLibrary();
	Check_Object(max_states);
	MAXScene *scene = max_states->GetSceneProxy();

	MAXTextureLibrary *library =
		Cast_Object(MAXTextureLibrary*, states->GetTextureLibrary());
	
	int textureIndex = scene->bmpList.GetBitmapID(textureState);
	if (textureIndex == -1)
		return NULL;

	MAXTexture *proxy = MAXTexture::MakeProxy(library, scene, textureIndex);
	Register_Object(proxy);
	//return library->UseTextureProxy(textureIndex);
	//return library->UseTextureProxy(textureState);
	Proxies::TextureProxy *proxyret = (NULL == materialState)?NULL:library->UseMatchingTextureProxy(proxy);
	Unregister_Object(proxy);
	proxy->Destroy();
	return proxyret;
}

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

	//
	//----------------------------------------
	// Have the texture library make our proxy
	//----------------------------------------
	//
	Proxies::StateLibrary *state_library = GetStateLibrary();
	Proxies::TextureLibrary *texture_library = state_library->GetTextureLibrary();
	Proxies::TextureProxy *proxy = texture_library->UseMatchingTextureProxy(texture);
	return proxy;
}

#if 0	// was input to fix a bug in the lower level proxies that has since been
		// solved "we think"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::IsEqualTo(Proxies::StateProxy *state)
{
	Check_Object(this);
	Check_Object(state);
	if (StateProxy::IsEqualTo(state))
	{
		bool us   = GetAlphaSetting();
		MAXState *max_state = Cast_Object(MAXState *, state);
		bool them = max_state->GetAlphaSetting();
		if (them == us)
		return true;
	}
	return false;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXState::GetAlphaSetting()
{
	if (textureState)
	{
		Check_Pointer(textureState);
		int alpha_source = textureState->GetAlphaSource();
		if (alpha_source == ALPHA_NONE)
			return false;
		else //if (alpha_source == ALPHA_FILE) 
			return true;
	}
	return false;
}
#endif

//
//############################################################################
//############################    MAXStateLibrary    #########################
//############################################################################
//

MAXStateLibrary::ClassData*
	MAXStateLibrary::DefaultData = NULL;

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

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

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MAXStateLibrary::MAXStateLibrary(MAXScene *scene):
	StateLibrary(DefaultData, scene)
{
	Check_Pointer(this);
	multiMtl = NULL;
	//
	//---------------------------------------------------
	// Get the number of textures present in the database
	//---------------------------------------------------
	//
	textureLibrary = MAXTextureLibrary::MakeProxy(this);
	Register_Object(textureLibrary);
	Check_Object(this);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MAXStateLibrary::~MAXStateLibrary()
{
	//TODO: clean up multiMtl
	Check_Object(this);
	Cast_Object(MAXTextureLibrary*, textureLibrary)->CloseLibrary();
	textureLibrary->DetachReference();
	Unregister_Object(textureLibrary);
	textureLibrary = NULL;
}

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

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

	//
	//------------------------------------
	// See if this state needs to be added
	//------------------------------------
	//
	if (!texture)
		texture = state->UseTextureProxy();
	else
	{
		texture->AttachReference();
		Check_Object(texture);
	}

	if (!texture)
	{
		// Breakpoint here.  Exporting didn't detect that there is no texture
		int x=1;
	}
	MAXProxies::MAXState *our_state = NULL;
	ChainIteratorOf< Proxies::StateProxy* > iterator(&activeStateProxies);
	Proxies::StateProxy *iterator_state;
	int index = 0;
	while (iterator_state = iterator.ReadAndNext())
	{
		our_state = Cast_Object(MAXState *,iterator_state);
		//iterator.Next();
		if (state->IsEqualTo(our_state))
			break;
		our_state = NULL;
		index++;
	}
	index = index >> 1;
	//index++;
	if (!our_state)
	{

		MAXProxies::MAXScene *scene = GetSceneProxy();
		// Create the material and texture
		StdMat *mat = NewDefaultStdMat();
		scene->mtlList.AddMtl(mat);
		// Add this material to the multimaterial object (connected to the node)
		int numMat = multiMtl->NumSubMtls();
		multiMtl->SetNumSubMtls(numMat+1);
		multiMtl->SetSubMtl(numMat,mat);
		scene->GetInterface()->GetMaterialLibrary().Add(mat);

		static int addtex = 0;
		BitmapTex *tex = NULL;
		if (texture && addtex)
		{
			// Get Ready for FPU error here
			
			tex = NewDefaultBitmapTex();
			
			Stuff::MString name;
			if (texture->GetName(&name))
			{
				tex->SetMapName(name+".tga");
			}
			else
				STOP(("UseMatchingStateProxy - could not get texture name"));
			if (tex->SupportTexDisplay() == TRUE)
			{
				tex->SetMtlFlag(MTL_TEX_DISPLAY_ENABLED, TRUE);
				tex->ActivateTexDisplay(TRUE);
			}
			scene->bmpList.AddBitmap(tex);
			mat->SetSubTexmap(ID_DI,tex);
		}
		mat->EnableMap(ID_DI, TRUE);
		mat->SetTexmapAmt(ID_DI, 1.f, 0);
		if (tex && tex->SupportTexDisplay() == TRUE)
			mat->SetMtlFlag(MTL_TEX_DISPLAY_ENABLED, TRUE);

		our_state = MAXProxies::MAXState::MakeProxy(this, NULL,mat,tex,0);

		// TODO: Use the matching texture proxy to add the texture to the bmp list
		MAXCopyProcess process;
		our_state->Copy(&process,state);
	
		Register_Object(our_state);
		AttachStateProxy(our_state);
	}
	else
		our_state->matID = index;
	our_state->AttachReference();
	// Set the Material ID - only really used for import
/*	if (texture)
		texture->DetachReference();*/

	return our_state;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXStateLibrary::CloseLibrary()
{
	Check_Object(this);
	Verify(GetReferenceCount() == 1);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MAXState*
	MAXStateLibrary::UseStateProxy(
		Mtl *material,
		BitmapTex *texture,
		INode *mesh,
		int indice
	)
{
	Check_Object(this);
	//
	//--------------------------------------------
	// Look up the material and make a state proxy
	//--------------------------------------------
	//
	MAXState *proxy =
		MAXState::MakeProxy(this, mesh, material, texture, indice);
	Register_Object(proxy);
	return proxy;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MultiMtl *MAXStateLibrary::GetMultiMtl()
{
	if (!multiMtl)
	{
		multiMtl = NewDefaultMultiMtl();
		multiMtl->SetName("Mesh Materials");
		multiMtl->SetNumSubMtls(0);
		MAXProxies::MAXScene *scene = GetSceneProxy();
		scene->GetInterface()->GetMaterialLibrary().Add(multiMtl);
	}
	return multiMtl;
}

void
	MAXStateLibrary::CalculateMaxState(
		MAXState *state,
		Proxies::StateProxy *proxy,
		Proxies::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();
	}

	//
	//---------------------
	// Deal with the states
	//---------------------
	//

	bool permission, onOff;
	Proxies::StateProxy::AlphaMode alphaMode;

	if(proxy->GetAlpha(&alphaMode))
	{
		state->SetAlpha(alphaMode);
	}

	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
		);
	}

	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);
	}

	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();
	}*/
}
