#include "MAXProxyHeaders.hpp"

//
//############################################################################
//#############################    MAXPolygon    ##############################
//############################################################################
//

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

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

	Verify(!DefaultData);
	DefaultData =
		new ClassData(
			MAXPolygonClassID,
			"MAXPolygon",
			PolygonProxy::DefaultData
		);
	Register_Object(DefaultData);
}

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

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXPolygon::Destroy()
{
	Check_Object(this);
	Verify(referenceCount == 1);
	Verify(activeIndexProxies.IsEmpty());
	Check_Pointer(proxiedPolygon);
	DetachReference();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MAXPolygon::MAXPolygon(
	MAXPolygonMesh *mesh,
	Face *polygon,
	int index
):
	Proxies::PolygonProxy(DefaultData, mesh),
	proxiedPolygon(polygon),
	faceIndex(index)
{
	Check_Pointer(this);
	Check_Object(mesh);
	Check_Pointer(polygon);
	Check_Object(this);
}

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXPolygon::TestInstance() const
{
	Verify(IsDerivedFrom(DefaultData));
	Check_Pointer(proxiedPolygon);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
unsigned
	MAXPolygon::UseIndexArray(DynamicArrayOf<Proxies::IndexProxy*> *indices)
{
	Check_Object(this);
	Check_Object(indices);
	Check_Pointer(proxiedPolygon);

	MAXPolygonMesh *mesh_proxy = GetPolygonMeshProxy();
	Check_Object(mesh_proxy);

	unsigned vertex_count = 3;
	indices->SetLength(vertex_count);
	MAXVertex *vertex;

	TVFace *tex_face = mesh_proxy->GetTVFace(faceIndex);
	for (unsigned i=0; i<vertex_count; ++i)
	{
		if (mesh_proxy->GetnumTVerts() >0)
		{
			vertex = MAXVertex::MakeProxy(mesh_proxy,
									  proxiedPolygon->v[i],
									  tex_face->t[i],
									  mesh_proxy->GetVertex(proxiedPolygon->v[i]),faceIndex);
		}
		else
		{
			vertex = MAXVertex::MakeProxy(mesh_proxy,
									  proxiedPolygon->v[i],
									  0,
									  mesh_proxy->GetVertex(proxiedPolygon->v[i]),faceIndex);
		}
		Register_Object(vertex);
		(*indices)[i] = MAXIndex::MakeProxy(this, vertex);
		Register_Object((*indices)[i]);
		Verify(vertex->GetReferenceCount() == 2);
		vertex->DetachReference();
	}
	return vertex_count;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXPolygon::AddToCollection(const char *collection)
{
	Check_Object(this);
	Check_Pointer(collection);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXPolygon::RemoveFromCollection(const char *collection)
{
	Check_Object(this);
	Check_Pointer(collection);
	STOP(("Not implemented"));
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	MAXPolygon::GetCollections(Proxies::MStringChain *collection_list)
{
	Check_Object(this);
	Check_Object(collection_list);
//	Abort_Program("Not implemented");
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	MAXPolygon::IsMemberOf(const char *collection)
{
	Check_Object(this);
	Check_Pointer(collection);
	STOP(("Not implemented"));
	return false;
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
unsigned
		MAXPolygon::UseMultiState(Proxies::MultiState *states)
{
	Check_Object(this);
	Check_Pointer(proxiedPolygon);
	//
	//-----------------------
	// Return the state proxy
	//-----------------------
	//
	MAXPolygonMesh *mesh = GetPolygonMeshProxy();
	Check_Object(mesh);

	INode* node = mesh->GetProxiedMesh();  // this node, used below for the state, is keeping the mesh from being
											// a protected member of the MAXPolygonMesh proxy
											// Just be very careful not to access the vertices and faces of this mesh

	Mtl* m = mesh->GetMtl();
	unsigned short index = proxiedPolygon->getMatID();
	int num_sub = 0;
	Mtl* mat = NULL;
	if (m)
	{
		num_sub = m->NumSubMtls();
		if (index < num_sub)
		{
			 mat = m->GetSubMtl(index);
		}
		else
		{
			mat = m;
		}
	}
#if 0
	if (mat==NULL)
	{
		STOP(("THE OBJECT MUST HAVE A MATERIAL !!"));
	}
#endif

	int texture_count = 0;
	int texture_index[NTEXMAPS];
	if (mat)
	{
		for (int i=0;i<NTEXMAPS;i++)
		{
			if (i==ID_OP) continue; // skip over the opacity map cause we use it
			Texmap* texmap = NULL;
			texmap = mat->GetSubTexmap(i);
			if (texmap!=NULL)
			{
				texture_index[texture_count] = i;
				texture_count++;
			}
		}
	}

	BitmapTex*	texture[NTEXMAPS];
	int			map_indice[NTEXMAPS];
	map_indice[0] = ID_DI;
	texture[0] = NULL;
	Texmap *tmap = NULL;
	int texture_found_count = 0;
	if (mat)
	{
		for (int i=0;i<texture_count;i++)
		{
			tmap = mat->GetSubTexmap(texture_index[i]);
			if (tmap)
			{
				if (tmap->ClassID() == Class_ID(BMTEX_CLASS_ID,0))
				{
					texture[texture_found_count] = (BitmapTex*)tmap;
					map_indice[texture_found_count] = i;
					texture_found_count++;
					TCHAR *temp1 = texture[i]->GetMapName();
				}
			}
		}
	}
	MAXScene *scene = mesh->GetSceneProxy();
	Check_Object(scene);
	MAXStateLibrary *library =
		Cast_Object(MAXStateLibrary*, scene->GetStateLibrary());
	//
	// the first part is done incase there is no texture a state still needs to be made
	//
	if (texture_found_count <= 0)
	{
		states->SetLength(1);
		//(*states)[0] = library->UseStateProxy( mat, texture[0], node, map_indice[0]);
		(*states)[0] = library->UseStateProxy( mat, texture[0], node, texture_index[0]);
		(*states)[0]->SetFlatColoring(0 == proxiedPolygon->smGroup);
		return 1;
	}
	else
	{
		states->SetLength(texture_found_count);
		for (int w=0;w<texture_found_count;w++)
		{
			if (texture[w] != NULL)
			{
				//(*states)[w] = library->UseStateProxy( mat, texture[w], node, map_indice[w]);
				(*states)[w] = library->UseStateProxy( mat, texture[w], node, texture_index[w]);
				(*states)[w]->SetFlatColoring(0 == proxiedPolygon->smGroup);
			}
		}
		return texture_found_count;
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
Face*
	MAXPolygon::AllocateRecord()
{
	return NULL;
}
