///////////////////////////////////////////////////////////////////////////////
//
// File: Tools_ContainerRegistry.cpp
//
// Created by Martin G.Harris (23/5/2008)
// 
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"
#include "Entity/Container/Tools_ContainerRegistry.h"

#ifdef ASURA_USE_CONTAINER_SYSTEM

// Asura
#include "Debugging/Asura_Assert.h"
#include "Entity/Container/Asura_ContainerRegistry.h"

///////////////////////////////////////////////////////////////////////////////
// Tools_ContainerRegistry
///////////////////////////////////////////////////////////////////////////////

//////////////
// AddEntry //
//////////////
void Tools_ContainerRegistry::AddEntry(u_int uClassification, PFN_TOOLS_CREATE pfnFunction, const char* szClassName, bool bCanAttach)
{
	Asura_Assert(szClassName, "Null class name");
	if (!szClassName) return;

	const int iIndex = Asura_ContainerRegistry::MapClassificationToIndex(uClassification);
	if (iIndex < 0)
	{
		Asura_Assertf(0, ("Failed to add container class '%s' to registry.", szClassName));
		return;
	}

	Asura_Assert(iIndex>=0 && iIndex<iCONTAINER_TYPES_MAX_NUMBER, "Invalid index.");

	if (m_axRegistry[iIndex].m_szClassName || m_axRegistry[iIndex].m_pfnToolsCreateFn)
	{
		Asura_Assertf(0, ("Tried to add container class '%s' to registry twice.", szClassName));
		return;
	}

	m_axRegistry[iIndex].m_uClassification	= uClassification;
	m_axRegistry[iIndex].m_pfnToolsCreateFn	= pfnFunction;
	m_axRegistry[iIndex].m_szClassName		= szClassName;
	m_axRegistry[iIndex].m_bCanAttach		= bCanAttach;
	
	++m_uNumEntries;
}

///////////////////////////
// GetContainerClassName //
///////////////////////////
const char* Tools_ContainerRegistry::GetContainerClassName(u_int uClassification)
{
	const int iIndex = Asura_ContainerRegistry::MapClassificationToIndex(uClassification);
	if (iIndex >= 0 && iIndex < iCONTAINER_TYPES_MAX_NUMBER)
	{
		return GetInstance().m_axRegistry[iIndex].m_szClassName;
	}

	return "*Unknown*";
}

//////////////////////
// CanUseAttachment //
//////////////////////
// Can the specified container classification use an attachment?
bool Tools_ContainerRegistry::CanUseAttachment(u_int uClassification)
{
	const int iIndex = Asura_ContainerRegistry::MapClassificationToIndex(uClassification);
	if (iIndex >= 0 && iIndex < iCONTAINER_TYPES_MAX_NUMBER)
	{
		return GetInstance().m_axRegistry[iIndex].m_bCanAttach;
	}

	return true;
}

//////////////////////
// CreateToolsClass //
//////////////////////
Tools_Container* Tools_ContainerRegistry::CreateToolsClass(u_int uClassification)
{
	Tools_Container* pxContainer = 0;

	const int iIndex = Asura_ContainerRegistry::MapClassificationToIndex(uClassification);
	if (iIndex >= 0 && iIndex < iCONTAINER_TYPES_MAX_NUMBER)
	{
		PFN_TOOLS_CREATE pfnFunction = GetInstance().m_axRegistry[iIndex].m_pfnToolsCreateFn;
		if (pfnFunction)
		{
			pxContainer = pfnFunction();
			if (pxContainer)
			{
				pxContainer->m_uClassification = uClassification;
			}
		}
	}

	Asura_Assertf(pxContainer, ("Failed to create Tools_Container (classification = %u).", uClassification));
	return pxContainer;
}

////////////////////
// AddToolsEntity //
////////////////////
void Tools_ContainerRegistry::AddToolsEntity(PFN_TOOLS_ENTITY_CREATE pfnFunction, bool bProjectOverride)
{
	// Don't let the Asura version overwrite the project version.
	if (m_pfnToolsEntityCreateFn && !bProjectOverride) return;

	m_pfnToolsEntityCreateFn = pfnFunction;
}

///////////////////////
// CreateToolsEntity //
///////////////////////
Tools_Entity_Container* Tools_ContainerRegistry::CreateToolsEntity(Asura_Entity* pxEntity)
{
	PFN_TOOLS_ENTITY_CREATE pfnFunction = GetInstance().m_pfnToolsEntityCreateFn;
	if (pfnFunction)
	{
		return pfnFunction(pxEntity);
	}
	return 0;
}

#endif //#ifdef ASURA_USE_CONTAINER_SYSTEM

