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


		#include "script/script_unit.h"
		#include "metafile/nml.h"
		#include "log/log.h"

		using namespace GS::Script;
		using namespace GS::NML;


//------------------------------------------------------------------------------
bool				Unit::FromMetaTag(Tag &tag)
{
	if	(tag.name != "ScriptUnit")
		__ERR__(__LOG_E__ << "Could not parse script unit, incorrect root tag (" << tag.name << ").\n", false)

	script_class.Clear();
	script_file.Clear();

	// Parse root tags.
	NMLTagForeach(pt, tag)
	{
				if	(pt->name == "ScriptPath")
			script_file = pt->GetString();

		else	if	(pt->name == "Script")	// legacy path (convert to explicit @core)
		{
			script_file = pt->GetString();
			if	(script_file.StartsWith("builtin/"))
				script_file = String("@core/") + script_file;
		}
		else	if	(pt->name == "Class")
				script_class = pt->GetString();

		// Parse instance parameters.
		else	if	(pt->name == "ParmList")
		{
			NMLTagForeach(c, *pt)
			{
				Tag *id = c->GetTag("Id"), *vl = c->GetTag("Value");

				if	(id && vl)
				{
					GS::Variant *parm = NULL;

					switch (vl->GetType())
					{
						case GS::Variant::VariantBool:
							parm = new GS::Variant(id->GetString(), vl->GetBool());
							break;
						case GS::Variant::VariantInteger:
							parm = new GS::Variant(id->GetString(), vl->GetInteger());
							break;
						case GS::Variant::VariantFloat:
							parm = new GS::Variant(id->GetString(), vl->GetReal());
							break;
						case GS::Variant::VariantString:
							parm = new GS::Variant(id->GetString(), vl->GetString());
							break;

						default:
							__LOG_W__ << "parameter '" << id->GetString() << "' type is invalid.\n";
							break;
					}
					if	(parm)
						parm_list.Add(parm);
				}
				else	__LOG_W__ << "Incomplete script parameter declaration ignored.\n";
			}
		}
		else	__LOG_W__ << "Unknown tag '" << pt->name << "' in <ScriptUnit>.\n";
	}
	return true;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
Tag					*Unit::AsMetaTag() const
{
	Tag *root = new Tag("ScriptUnit");
	if	(!root)
		__ERR__(__LOG_E__ << "Could not serialize script unit. Failed to create root tag.\n", NULL)

	// Store script.
	if	(!script_file.IsEmpty())
		root->AddChild("ScriptPath", script_file.c_str());
	if	(!script_class.IsEmpty())
		root->AddChild("Class", script_class.c_str());

	// Store instance parameters.
	if	(parm_list.GetCount())
	{
		if	(Tag *parmlist = root->AddChild("ParmList"))
		{
			ListForeachPtr(GS::Variant *, v, parm_list)
			{
				if	(Tag *parm = parmlist->AddChild("Parm"))
				{
					parm->AddChild("Id", v->id);

					switch (v->GetType())
					{
						case GS::Variant::VariantBool:
							parm->AddChild("Value", v->b_value);
							break;
						case GS::Variant::VariantInteger:
							parm->AddChild("Value", v->i_value);
							break;
						case GS::Variant::VariantFloat:
							parm->AddChild("Value", v->f_value);
							break;
						case GS::Variant::VariantString:
							parm->AddChild("Value", v->s_value);
							break;
					}
				}
				else	__LOG_W__ << "Failed to serialize instance parameter '" << v->id << "'.\n";
			}
		}
		else	__LOG_W__ << "Failed to serialize instance parameter list.\n";
	}

	if	(!root->GetChildCount())
		_safe_delete(root);
	return root;
}
//------------------------------------------------------------------------------
