#include "ElementProxyHeaders.hpp"
#include <Proxies\StateSort.hpp>
#include <MLR\MLRShape.hpp>

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	ElementPolygonMeshProxy::SplitByState(SplitByStateProcess *process)
{
	Check_Object(this);
	Check_Object(process);

	//
	//--------------------------
	// Make sure we can continue
	//--------------------------
	//
	process->SplitCallback(this, SplitByStateProcess::StatusCheck);
	if (!process->continueProcess)
		return true;

	//
	//-----------------------------------------------------------------------
	// We have to evaluate each polygon within the mesh to see how many have
	// unique texture/material combinations, so set up arrays to hold proxies
	// and matching indices
	//-----------------------------------------------------------------------
	//
	unsigned unique_combinations = GetPrimitiveCount();

	//
	//-------------------------------------------------------------------------
	// If there are no unique entries, than this is a spurious polygon mesh and
	// should be destroyed
	//-------------------------------------------------------------------------
	//
	if (!unique_combinations)
	{
		Destroy();
		return false;
	}

	//
	//---------------------------------------------------------
	// If there is only one unique entry, this mesh is OK as is
	//---------------------------------------------------------
	//
	if (unique_combinations == 1)
		return true;

	//
	//-----------------------------------------------------------------------
	// There were more than one entry, so this mesh must be split up, so find
	// the parent and get the local to parent transform of the base mesh
	//-----------------------------------------------------------------------
	//
	process->SplitCallback(this, SplitByStateProcess::WARNING_MultipleStates);
	GroupProxy *parent = GetParentGroupProxy();
	LinearMatrix4D m;
	GetLocalToParent(&m);

	//
	//------------------------------------------------------------------------
	// For each unique combination, create a new polygon mesh, and give it the
	// same transform as the original polygon mesh
	//------------------------------------------------------------------------
	//
	for (unsigned i=0; i<unique_combinations; ++i)
	{
		PolygonMeshProxy *mesh;
		if (parent)
		{
			Check_Object(parent);
			mesh = parent->AppendNewPolygonMeshProxy();
		}
		else
			mesh = GetSceneProxy()->AppendNewPolygonMeshProxy();
		mesh->SetLocalToParent(m);

		//
		//-------------------------------------------
		// Attach the specific primitive to the shape
		//-------------------------------------------
		//
		ShapeElement *shape = 
			Cast_Object(ElementPolygonMeshProxy*, mesh)->GetProxiedShape();
		MLRShape *mlr_shape = shape->GetMLRShape();
		Check_Object(mlr_shape);
		MLR_I_PMesh *primitive = GetPrimitive(i);
		Check_Object(primitive);
		mlr_shape->Add(primitive);
		mesh->DetachReference();
	}

	//
	//---------------------
	// Clean up the proxies
	//---------------------
	//
	Destroy();
	return false;
}
