#include "ProxyHeaders.hpp"

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	ChildProxy::CleanHierarchy(CleanHierarchyProcess *process)
{
	Check_Object(this);
	Check_Object(process);

	process->CleanHierarchyCallback(this);
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	PolygonMeshProxy::CleanHierarchy(CleanHierarchyProcess *process)
{
	Check_Object(this);
	Check_Object(process);

	//
	//------------------------------------------------------------
	// Make sure that the process says its OK to check the texture
	//------------------------------------------------------------
	//
	process->CleanHierarchyCallback(this);
	if (!process->continueProcess)
		return true;

	//
	//-----------------------------------------------------------------------
	// Calculate our best fit bounding sphere ignoring any that already exist
	//-----------------------------------------------------------------------
	//
	OBB obb;
	if (GetOBB(&obb))
	{
		STOP(("Not implemented"));
	}
	else
	{
		Sphere bounds;
		PolygonMeshProxy::GetBoundingSphere(&bounds);
		SetBoundingSphere(bounds);
	}
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	GroupProxy::CleanHierarchy(CleanHierarchyProcess *process)
{
	Check_Object(this);
	Check_Object(process);

	//
	//------------------------------------------------------------
	// Make sure that the process says its OK to check the texture
	//------------------------------------------------------------
	//
	process->CleanHierarchyCallback(this);
	if (!process->continueProcess)
		return true;

	//
	//---------------------------------------------------------
	// First, allow each child hierarchy to remove redundancies
	//---------------------------------------------------------
	//
	unsigned child_count = GetChildCount();
	ChildProxy *child = UseFirstChildProxy();
	for (unsigned i=0; i<child_count; ++i)
	{
		Check_Object(child);
		ChildProxy *next = child->UseNextSiblingProxy();
		if (child->CleanHierarchy(process))
			child->DetachReference();
		child = next;
		if (!process->continueProcess)
		{
			if (child)
			{
				Check_Object(child);
				child->DetachReference();
			}
			return true;
		}
	}
	if (child)
		child->DetachReference();

	//
	//-----------------------------------------------------------------------
	// Now, check to see if we are a redundant hierarchy.  If we have a name,
	// or if we have two or more children, we are not redundant.  If we are,
	// we need to push our transform down into our child, and then attach our
	// child to our parent
	//-----------------------------------------------------------------------
	//
	child_count = GetChildCount();
	MString name;
	if (!GetName(&name) && child_count <= 1)
	{
		LinearMatrix4D matrix;
		GetLocalToParent(&matrix);
		child = UseFirstChildProxy();
		Verify(child_count < 2);
		if (child)
		{
			Check_Object(child);
			child->TransformLocalToParent(matrix);
			child->TransferAndAppendToParentGroup(GetParentGroupProxy());
			child->DetachReference();
		}
		Destroy();
		return false;
	}

	//
	//-----------------------------------------------------------------------
	// Calculate our best fit bounding sphere ignoring any that already exist
	//-----------------------------------------------------------------------
	//
	OBB obb;
	if (GetOBB(&obb))
	{
		STOP(("Not implemented"));
	}
	else
	{
		Sphere bounds;
		GroupProxy::GetBoundingSphere(&bounds);
		SetBoundingSphere(bounds);
	}
	return true;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
	SceneProxy::CleanHierarchy(CleanHierarchyProcess *process)
{
	Check_Object(this);
	Check_Object(process);

	//
	//------------------------------------------------------------
	// Make sure that the process says its OK to check the texture
	//------------------------------------------------------------
	//
	process->CleanHierarchyCallback(this);
	if (!process->continueProcess)
		return true;

	//
	//---------------------
	// Handle a scene proxy
	//---------------------
	//
	unsigned child_count = GetChildCount();
	ChildProxy *child = UseFirstChildProxy();
	for (unsigned i=0; i<child_count; ++i)
	{
		Check_Object(child);
		ChildProxy *next = child->UseNextSiblingProxy();
		if (child->CleanHierarchy(process))
			child->DetachReference();
		child = next;
		if (!process->continueProcess)
		{
			if (child)
			{
				Check_Object(child);
				child->DetachReference();
			}
			return true;
		}
	}
	if (child)
		child->DetachReference();
	return true;
}

