///////////////////////////////////////////////////////////////////////////////
//
// File   : Tools_Chunk_PFXOverrides.h
// Author : Andy Southgate
// Date   : 05-Jan-2009
//
// Copyright (C) 2009 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header...
#include "ChunkSystem/Tools_Chunk_PFXOverrides.h"

// Asura independent header-files...
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "ChunkSystem/Asura_SaveBlock.h"
#include "SpecialFX/PFX/Asura_PFX_System.h"

#if defined(ASURA_TOOLS)
// Tools header-files...
#include "Particles/Tools_PFX_Overrides.h"
#endif	// defined(ASURA_TOOLS)



////////////////////////////////////////////////////////////////////////////////
// Constant declarations...
////////////////////////////////////////////////////////////////////////////////

static const u_int	g_uChunkVersion	= 1;


////////////////////////////////////////////////////////////////////////////////
// Static variable declarations...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Private functions...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Protected functions...
////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////
// Public functions...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Chunk_PFXOverrides::Process
// Author       : Andy Southgate
// Date         : 05-Jan-2009
////////////////////////////////////////////////////////////////////////////////

template <typename T> static void LoadOverridesFromStream(int Version, Asura_ResourceSetWithOverride<T>& xResourceSet, Asura_Chunk_Stream &xStream)
{
	u_int	uNumOverrideMaps;

	// Read each override map in-turn...
	xStream >> uNumOverrideMaps;

	for(u_int u = 0; u < uNumOverrideMaps; u++)
	{
		u_int								uNumOverrides;
		Asura_String						xOverrideMapName;
		Asura_Hash_ID						uOverrideMapHash;
		Asura_ResourceSetOverrideMap<T> *pxOverrideMap;

		// Read the name of this override-map...
		xStream >> xOverrideMapName;
		uOverrideMapHash	= xOverrideMapName.GetHash();

		// Ensure we have such an override-map...
		pxOverrideMap		= xResourceSet.GetOverrideMapByHash(uOverrideMapHash);

		if(pxOverrideMap == NULL)
		{
			pxOverrideMap	= xResourceSet.AllocateOverrideMap(uOverrideMapHash);
			pxOverrideMap->SetName(xOverrideMapName.GetString());
		}

		// Read each override in-turn...
		xStream >> uNumOverrides;

		for(u_int v = 0; v < uNumOverrides; v++)
		{

			Asura_String	xOverrideName;

			Asura_String	xItemName;
			// Read the name of this override...
			xStream >> xItemName;
			xStream >> xOverrideName;

			// Ensure we have such an override...
			pxOverrideMap->CreateOverride(xItemName, xOverrideName);
		}
	}

}

bool Tools_Chunk_PFXOverrides::Process(const Asura_Handle iFileHandle) const
{
	if(Version > g_uChunkVersion)
	{
		Asura_Assert(false, "Unexpected chunk version found - aborting chunk-read.");
		return(false);
	}
	else
	{
		Asura_Chunk_File_Stream	xStream(iFileHandle);

		LoadOverridesFromStream(Version, Asura_PFX_System::GetSourceTempResourceSet(), xStream);
		LoadOverridesFromStream(Version, Asura_PFX_System::GetParticleTempResourceSet(), xStream);


		return(true);
	}
}



/// End of function 'Tools_Chunk_PFXOverrides::Process'. ///


template <typename T> static void SaveOverridesToStream(Asura_ResourceSetWithOverride<T>& xResourceSet, Asura_Chunk_Stream &xStream)
{
	u_int	uNumOverrideMaps = xResourceSet.GetNumOverrideMaps();

	// Read each override map in-turn...
	xStream << uNumOverrideMaps;

	for(Asura_ResourceSetWithOverride_ConstOverrideMapIterator<T> xIter(xResourceSet); !xIter.Done(); xIter.Next())
	{
		const Asura_ResourceSetOverrideMap<T> *pxOverrideMap = xIter.GetCurrent();
		u_int								uNumOverrides = pxOverrideMap->GetNumEntries();

		// Read the name of this override-map...
		xStream << Asura_String(pxOverrideMap->GetName());

		// Read each override in-turn...
		xStream << uNumOverrides;

		
		for(Asura_ResourceSetOverrideMap_ConstIterator<T> xIter(*pxOverrideMap); !xIter.Done(); xIter.Next())
		{
			xStream << Asura_String(xIter.GetCurrent()->GetOldName());
			xStream << Asura_String(xIter.GetCurrent()->GetNewName());
		}
	}

}


////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Chunk_PFXOverrides::Create
// Author       : Andy Southgate
// Date         : 12-Jan-2009
////////////////////////////////////////////////////////////////////////////////
void Tools_Chunk_PFXOverrides::Create(Asura_Chunk_Stream& xStream)
{
	// Begin writing...
	xStream.WriteChunk_Start(TOOLS_CHUNK_PFX_OVERRIDES, g_uChunkVersion, 0);

	SaveOverridesToStream(Asura_PFX_System::GetSourceTempResourceSet(), xStream);
	SaveOverridesToStream(Asura_PFX_System::GetParticleTempResourceSet(), xStream);

	xStream.WriteChunk_End();
}
/// End of function 'Tools_Chunk_PFXOverrides::Create'. ///



////////////////////////////////////////////////////////////////////////////////
// Function     : Tools_Chunk_PFXOverrides::Save
// Author       : Andy Southgate
// Date         : 12-Jan-2009
////////////////////////////////////////////////////////////////////////////////
bool Tools_Chunk_PFXOverrides::Save(const char* szFilename)
{
	Asura_SaveBlock					xSaveBlock;
	Asura_Chunk_SaveBlock_Stream	xStream(&xSaveBlock);

	// Fill-in the save-block...
	Create(xStream);

	// Terminate the Asura-file...
	xStream.WriteAsuraTerminator();

	// ...before saving the file to disc...
	return(xSaveBlock.SaveFile(szFilename, false));
}

/// End of function 'Tools_Chunk_PFXOverrides::Save'. ///

/// End of file. ///
