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


		#include "physic/physic_item_desc.h"
		#include "metafile/nml.h"
		#include "log/log.h"

		using namespace GS::S3D;
		using namespace GS::NML;


//------------------------------------------------------------------------------
float				PhysicItemDesc::GetMass() const
{
	float mass = 0;
	ListForeachPtr(PhysicShape *, shape, shape_list)
		mass += shape->mass;
	return mass;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
bool				PhysicItemDesc::FromMetaTag(Tag &tag)
{
	if	((tag.name != "TauItem") && (tag.name != "GColItem") && (tag.name != "PhysicItem"))
		__ERR__(__LOG_E__ << "Could not parse physic item, incorrect root tag (" << tag.name << ").\n", false)

	shape_list.Clear();
	vehicle.wheel_list.Clear();
	physic_flags.Set(PhysicFlag_None);

	self_mask = 1;
	collision_mask = 1;

	// Parse root tags.
	NMLTagForeach(pt, tag)
	{
				if	(pt->name == "SelfMask")
				self_mask = pt->GetInteger();
		else	if	(pt->name == "Mask")
				collision_mask = pt->GetInteger();

		else	if	(pt->name == "Mode")
		{
			String mode(pt->GetString());

					if	(mode == "None")		physic_mode = Mode_None;
			else	if	(mode == "Static")		physic_mode = Mode_Static;
			else	if	(mode == "Dynamic")		physic_mode = Mode_Dynamic;
			else	if	(mode == "Kinematic")	physic_mode = Mode_Kinematic;
			else	if	(mode == "Character")	physic_mode = Mode_Character;
			else	if	(mode == "Vehicle")		physic_mode = Mode_Vehicle;
		}
		else	if	(pt->name == "Shapes")
		{
			NMLTagForeach(st, *pt)
				if	(PhysicShape *shape = new PhysicShape)
				{
					shape->FromMetaTag(*st);
					shape_list.Add(shape);
				}
		}
		else	if	(pt->name == "Wheels")
		{
			NMLTagForeach(wt, *pt)
				if	(PhysicWheel *wheel = new PhysicWheel)
				{
					wheel->FromMetaTag(*wt);
					vehicle.wheel_list.Add(wheel);
				}
		}
		else	if	(pt->name == "Flag")
		{}

		else	if	(pt->name == "CharacterRadius")
			character.radius = pt->GetReal();
		else	if	(pt->name == "CharacterHeight")
			character.height = pt->GetReal();
		else	if	(pt->name == "CharacterMaxStep")
			character.max_step = pt->GetReal();

		else	if	(pt->name == "LinearDamping_v2")
			linear_damping = pt->GetReal();
		else	if	(pt->name == "AngularDamping_v2")
			angular_damping = pt->GetReal();
#if		1
		else	if	(pt->name == "LinearDamping")
			linear_damping = pt->GetReal();
		else	if	(pt->name == "AngularDamping")
			angular_damping = pt->GetReal();
		else	if	(pt->name == "Active")
				;
#endif

		else	__LOG_W__ << "Unknown tag '" << pt->name << "' in <PhysicItem>.\n";
	}
	return true;
}
Tag			*PhysicItemDesc::AsMetaTag() const
{
	Tag *root = new Tag("PhysicItem");
	if	(!root)
		__ERR__(__LOG_E__ << "Could not create collision item root tag to serialize.\n", NULL)

	root->AddChild("SelfMask", (int)self_mask);
	root->AddChild("Mask", (int)collision_mask);
	root->AddChild("LinearDamping_v2", linear_damping);
	root->AddChild("AngularDamping_v2", angular_damping);
	root->AddChild("CharacterRadius", character.radius);
	root->AddChild("CharacterHeight", character.height);
	root->AddChild("CharacterMaxStep", character.max_step);

	switch (physic_mode)
	{
		default:
		case Mode_None:			root->AddChild("Mode", "None");			break;

		case Mode_Static:		root->AddChild("Mode", "Static");		break;
		case Mode_Dynamic:		root->AddChild("Mode", "Dynamic");		break;
		case Mode_Kinematic:	root->AddChild("Mode", "Kinematic");	break;

		case Mode_Character:	root->AddChild("Mode", "Character");	break;
		case Mode_Vehicle:		root->AddChild("Mode", "Vehicle");		break;
	}

	// Dump shapes.
	if	(shape_list.GetCount())
		if	(Tag *st = root->AddChild("Shapes"))
			ListForeachPtr(PhysicShape *, shape, shape_list)
				st->AddChild(shape->AsMetaTag());

	// Dump wheels.
	if	(vehicle.wheel_list.GetCount())
		if	(Tag *wt = root->AddChild("Wheels"))
			ListForeachPtr(PhysicWheel *, wheel, vehicle.wheel_list)
				wt->AddChild(wheel->AsMetaTag());

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