/**
*
* \file Asura_BillboardPlant_TemplateStore.cpp
*
* Created by Andrew Weinkove - 05/12/2002
*
* Copyright (C) 2002 Rebellion, All Rights Reserved.
*
**/

#include "Core/Asura.h"
#include "SpecialFX/Asura_BillboardPlant_TemplateStore.h"

#include "ChunkSystem/Asura_Chunk_BillboardPlant_Template.h"
#include "Core/Asura_Material_System.h"
#include "Core/Asura_TextureManagement.h"
#include "Debugging/Asura_Assert.h"

#ifdef ASURA_USE_BILLBOARD_PLANTS

#ifdef ASURA_TOOLS
unsigned Asura_BillboardPlant_TemplateStore::s_uNextUniqueID = 0;
#endif

int Asura_BillboardPlant_TemplateStore::s_iNumberOfTemplates;
Asura_BillboardPlant_Template *Asura_BillboardPlant_TemplateStore::s_pxTemplates;

Asura_BillboardPlant_Template::~Asura_BillboardPlant_Template()
{
	if (m_szTemplateName)
		delete[] m_szTemplateName;
	if (m_szTextureName)
		delete[] m_szTextureName;
}


void Asura_BillboardPlant_TemplateStore::Initialise()
{
	s_iNumberOfTemplates = 0;
	s_pxTemplates = NULL;
#ifdef ASURA_TOOLS
	s_uNextUniqueID = 0;
#endif
	bool bSuccess = LoadAsuraFile("Misc\\PlntTmps.asr");
	Asura_Assert(bSuccess, "Couldn't find plant templates file - (Misc\\PlntTmps.asr)");
}

void Asura_BillboardPlant_TemplateStore::Shutdown()
{
	s_iNumberOfTemplates = 0;
	delete[] s_pxTemplates;
	s_pxTemplates = NULL;
}

void Asura_BillboardPlant_TemplateStore::Reset()
{
	// (AW - 28.02.2005) - Fix fragmentation by not doing anything on reset.
	//Shutdown();
	//Initialise();
}

void Asura_BillboardPlant_TemplateStore::AllocateTemplates(int iNumberOfTemplates)
{
	Asura_Assert(!s_pxTemplates, "");
	s_iNumberOfTemplates = iNumberOfTemplates;
	s_pxTemplates = new Asura_BillboardPlant_Template[s_iNumberOfTemplates];
}

int Asura_BillboardPlant_TemplateStore::GetIndexFromUniqueID(unsigned uID)
{
	for (int i=0;i<s_iNumberOfTemplates;i++)
	{
		if (s_pxTemplates[i].m_uUniqueID == uID)
			return i;
	}
	return -1;
}


Asura_BillboardPlant_Template* Asura_BillboardPlant_TemplateStore::GetTemplate(int iIndex)
{
	Asura_Assert(iIndex < s_iNumberOfTemplates, "Sanity check");
	Asura_Assert(iIndex >= 0, "Sanity check");
	if (iIndex < s_iNumberOfTemplates &&
		iIndex >= 0)
	{
		return &s_pxTemplates[iIndex];
	}
	return NULL;
}

void Asura_BillboardPlant_TemplateStore::SetTextureID(int iIndex)
{
	bool bWasNew = false;
	s_pxTemplates[iIndex].m_iTextureIndex = Asura_Texture_Management::AddTexture(s_pxTemplates[iIndex].m_szTextureName, &bWasNew);
	Asura_Assert(!bWasNew, "");
	int iTextureIndex = s_pxTemplates[iIndex].m_iTextureIndex;
	if (Asura_Material_System::GetMaterialIDForTexture(iTextureIndex, false) == ASURA_MATERIAL_NONE)
	{
		// Mark it as transparent too.
		int iMaterialID = Asura_Material_System::CreateMaterial();
		if(iMaterialID != ASURA_MATERIAL_NONE)
		{
			Asura_Material* pxMaterial = Asura_Material_System::GetMaterial(iMaterialID);
			Asura_Assert(pxMaterial,"");
			pxMaterial->m_iTextureID[0] = iTextureIndex;
			pxMaterial->m_uMaterialFlags = AsuraMaterialFlag_Transparent;
		}
	}
}


#ifdef ASURA_TOOLS
void Asura_BillboardPlant_TemplateStore::LoadTextures()
{
	bool bLoadedNewTexture = false;
	for (int i=0;i<s_iNumberOfTemplates;i++)
	{
		bool bWasNew = false;
		int iTextureIndex = Asura_Texture_Management::AddTexture(s_pxTemplates[i].m_szTextureName, &bWasNew);
		s_pxTemplates[i].m_iTextureIndex = iTextureIndex;
		if (bWasNew)
			bLoadedNewTexture = true;
	}
	if (bLoadedNewTexture)
		Asura_Texture_Management::LoadTextures();
}


void Asura_BillboardPlant_TemplateStore::Save()
{
	Asura_Chunk_BillboardPlant_Template::Create();
}


Asura_BillboardPlant_Template* Asura_BillboardPlant_TemplateStore::CreateNewTemplate(const Asura_String &xName)
{
	Asura_BillboardPlant_Template *pxBuffer = NULL;
	if (s_iNumberOfTemplates)
	{
		pxBuffer = new Asura_BillboardPlant_Template[s_iNumberOfTemplates];
		for (int i=0;i<s_iNumberOfTemplates;i++)
		{
			pxBuffer[i] = s_pxTemplates[i];
		}
		delete[] s_pxTemplates;
	}
	s_iNumberOfTemplates++;
	s_pxTemplates = new Asura_BillboardPlant_Template[s_iNumberOfTemplates];
	s_pxTemplates[0].m_szTemplateName = new char[xName.GetLength() + 1];
	strcpy(s_pxTemplates[0].m_szTemplateName, xName.GetString());
	s_pxTemplates[0].m_szTextureName = NULL;	// Only valid in tools.
	s_pxTemplates[0].m_iTextureIndex = ASURA_TEXTURE_NONE;
	s_pxTemplates[0].m_fTopLeftU = 0.0f;
	s_pxTemplates[0].m_fTopLeftV = 0.0f;
	s_pxTemplates[0].m_fBottomRightU = 1.0f;
	s_pxTemplates[0].m_fBottomRightV = 1.0f;
	s_pxTemplates[0].m_fHeight = 1.0f;
	s_pxTemplates[0].m_fWidth = 1.0f;
	s_pxTemplates[0].m_fMaxDistortion = 0.5f;
	s_pxTemplates[0].m_fStiffness = 1.0f;
	s_pxTemplates[0].m_uUniqueID = s_uNextUniqueID++;
	s_pxTemplates[0].m_uFlags = 0;
	for (int i=1;i<s_iNumberOfTemplates;i++)
	{
		s_pxTemplates[i] = pxBuffer[i-1];
	}
	delete[] pxBuffer;
	return s_pxTemplates;
}

void Asura_BillboardPlant_TemplateStore::DeleteTemplate(Asura_BillboardPlant_Template* pxTemplate)
{
	if (!s_iNumberOfTemplates)
		return;
	Asura_BillboardPlant_Template *pxBuffer = new Asura_BillboardPlant_Template[s_iNumberOfTemplates];
	int iIndex = -1;
	for (int i=0;i<s_iNumberOfTemplates;i++)
	{
		if (&s_pxTemplates[i] == pxTemplate)
			iIndex = i;
		pxBuffer[i] = s_pxTemplates[i];
	}
	if (iIndex == -1)
	{
		Asura_Assert(false, "Couldn't find plant template to delete");
		delete[] pxBuffer;
		return;
	}
	delete[] s_pxTemplates;
	s_iNumberOfTemplates--;
	if (s_iNumberOfTemplates)
	{
		s_pxTemplates = new Asura_BillboardPlant_Template[s_iNumberOfTemplates];
		for (int i=0;i<s_iNumberOfTemplates;i++)
		{
			if (iIndex > i)
				s_pxTemplates[i] = pxBuffer[i];
			else
				s_pxTemplates[i] = pxBuffer[i+1];
		}
	}
	else
		s_pxTemplates = NULL;
	delete[] pxBuffer;
}

int Asura_BillboardPlant_TemplateStore::GetNumberOfTemplates()
{
	return s_iNumberOfTemplates;
}

void Asura_BillboardPlant_TemplateStore::RegisterUniqueID(unsigned uID)
{
	if (uID >= s_uNextUniqueID)
		s_uNextUniqueID = uID + 1;
}

#endif // ASURA_TOOLS

#endif //ASURA_USE_BILLBOARD_PLANTS
