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


		#include "motion/motion.h"
		#include "log/log.h"

		using namespace GS::Core;
		using GS::NML::Tag;


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

	use_quaternion = false;

	// Parse root tags.
	NMLTagForeach(pt, tag)
	{
				if	(pt->name == "Id")
			name = pt->GetString();
		else	if	(pt->name == "UseQuaternion")
			use_quaternion = pt->GetBool();
		else	if	(pt->name == "QChannel")
			quaternion.FromMetaTag(*pt);

		else	if	(pt->name == "Channel")
		{
			MotionChannel *chn = AddChannel(MotionChannel::Undf);
			chn->FromMetaTag(*pt);
		}
		else	if	(pt->name == "DataKnot")
		{
			Tag *count_tag = pt->GetTag("Count");

			ArrayListDeleteAllPtr(SDataPoint *, data_point)

			if	(count_tag && count_tag->GetInteger() > 0)
			{					
				uint n = (uint)count_tag->GetInteger();
				while (n--)
					if	(!data_point.Add(new SDataPoint))
						return false;

				n = 0;
				NMLTagForeach(st, *pt)
				{
					if	(st->name == "Knot")
					{
						if	(n == data_point.GetCount())
						{
							__LOG_E__ << "Too many knot in <DataKnot>, " << data_point.GetCount() << " expected.\n";
							break;
						}

						if	(const char *p = st->GetString())
						{
							data_point[n]->t = Time::fromSec(String::atof(p));

							p = String::strfindchar(p, ':');
							data_point[n]->data = Variant(p + 1);

							n++;
						}
						else
							__LOG_W__ << "Invalid knot tag while parsing curve.\n";
					}
				}
			}
		}
		else	__LOG_W__ << "Unknown tag '" << pt->name << "' in <Motion>.\n";
	}
	return true;
}
Tag			*Motion::AsMetaTag()
{
	Tag *root = new Tag("Motion");
	if	(!root)
		__ERR__(__LOG_E__ << "Could not create root tag to serialize.\n", NULL)

	root->AddChild("Id", name.c_str());

	// Dump quaternion channel.
	root->AddChild("UseQuaternion", use_quaternion);
	root->AddChild(quaternion.AsMetaTag());

	// Dump all channels.
	ListForeachPtr(MotionChannel *, channel, channel_list)
		root->AddChild(channel->AsMetaTag());
	
	// Dump the data array	
	if	(data_point.GetCount())
		if	(Tag *data_knot_tag = root->AddChild("DataKnot"))
		{
			data_knot_tag->AddChild("Count", (int)data_point.GetCount());
		
			ArrayListForeachPtr(SDataPoint *, data, data_point)
				data_knot_tag->AddChild("Knot",String::Format("%f:%s", data->t.toSec(), data->data.s_value.c_str()).c_str());
		}

	return root;
}
//------------------------------------------------------------------------------
