/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


		#include "core/embedded_resource_extractor.h"
		#include "metafile/nml.h"
		#include "filesystem/filesystem.h"
		#include "filesystem/io_memory.h"
		#include "platform.h"
		#include "log/log.h"

		using namespace GS;
		using namespace GS::Core;


//------------------------------------------------------------------------------
static bool	FormatExtractionPath(String &out, const char *context, const char *suffix, bool to_ram)
{
	__LOG_V__ << "Formatting extraction path for a resource embedded in '" << context << "'.\n";
	if	(!context)
		__ERR__(__LOG_W__ << "Cannot extract embedded resource, context is empty.\n", false)

	String extract_out = String(context).CutFileExtension();

	if	(to_ram)
	{
		extract_out = Platform::Get().io->StripRootPath(extract_out);

		if	(extract_out.IsAbsolutePath())
			__ERR__(__LOG_W__ << "Extraction context represents an absolute path, cannot extract to ramdisk.\n", false)
		else
		{
			if	(!extract_out.StartsWith("@embedded"))
				extract_out = String("@embedded/") + extract_out;
		}
	}

	out = extract_out + suffix;
	return true;
}
static bool	SaveExtractedResource(const char *out, NML::Tag &t)
{
	if	(Platform::Get().io->Exists(out))
		return true;		// Do not export resource more than once.

	__LOG_H__ << "Saving extracted resource to '" << out << "'.\n";

	NML::File file;
	file.AddRoot(&t);

	bool r = NML::Parser::Save(out, file);
	file.UnlinkRoot(&t);	// Unlink root tag so that the meta file destructor does not free it.

	return r;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
bool		EmbeddedResourceExtractor::ExtractEmbeddedMaterial(String &out, NML::Tag &t, const char *context, int slot)
{	return FormatExtractionPath(out, context, String::Format("-material-%d.nmm", slot), extract_to_ram) && SaveExtractedResource(out, t);	}
bool		EmbeddedResourceExtractor::ExtractEmbeddedShaderTree(String &out, NML::Tag &t, const char *context)
{	return FormatExtractionPath(out, context, "-shader-tree.nsa", extract_to_ram) && SaveExtractedResource(out, t);		}
//------------------------------------------------------------------------------

EmbeddedResourceExtractor::EmbeddedResourceExtractor(bool extract_to_ramdisk)
{
	if	((extract_to_ram = extract_to_ramdisk) == true)
		Platform::Get().io->Mount(new IO::Memory, "@embedded/");
}
