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


		#include "metafile/nml.h"
		#include "filesystem/io_handle.h"
		#include "alloc/ialloc.h"
		#include "log/log.h"

		using namespace GS::NML;


//------------------------------------------------------------------------------
Tag			*Tag::GetParent(Tag *root) const
{
	ListForeachPtr(Tag *, child, root->GetTags())
		if	(child == this)
			return root;

	Tag *parent = NULL;
	ListForeachPtr(Tag *, child, root->GetTags())
		if	((parent = GetParent(child)) != NULL)
			break;

	return parent;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
Tag			*Tag::AddChild(Tag *t)
{
	if	(!t)
		return NULL;
	if	(value.type != Variant::VariantNone)
		__ERR__(__LOG_E__ << "Cannot add child to tag '" << name << "' as it is neither a pure tag or a node.\n", NULL)
	if	(!tags.Add(t))
		return NULL;
	return t;
}
Tag			*Tag::AddChild(const char *name)
{	return AddChild(new Tag(name));	}
Tag			*Tag::AddChild(const char *name, bool v)
{	return AddChild(new Tag(name, v));	}
Tag			*Tag::AddChild(const char *name, int v)
{	return AddChild(new Tag(name, v));	}
Tag			*Tag::AddChild(const char *name, uint v)
{	return AddChild(new Tag(name, v));	}
Tag			*Tag::AddChild(const char *name, float v)
{	return AddChild(new Tag(name, v));	}
Tag			*Tag::AddChild(const char *name, const char *s)
{	return AddChild(new Tag(name, s));	}
Tag			*Tag::AddChild(const char *name, void *buffer, size_t size)
{	return AddChild(new Tag(name, buffer, size));	}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
bool		Tag::Clone(const Tag &src, bool recursive)
{
	Free();

	value = src.GetValue();

	if	(recursive)
		ListForeachPtr(Tag *, ct, src.GetTags())
			AddChild(ct->Clone(true));

	return true;
}
Tag			*Tag::Clone(bool recursive) const
{
	Tag *clone = new Tag(name);
	if	(!clone)
		return NULL;

	// Copy tag content.
	clone->GetValue() = value;

	// Clone children.
	if	(recursive)
		ListForeachPtr(Tag *, ct, tags)
			clone->AddChild(ct->Clone(true));

	return clone;
}
uint		Tag::DeleteChildren(const char *filter)
{
	uint count = 0;

	if	(filter)
	{
		String _filter(filter);

		ListForeachPtr(Tag *, t, tags)
			if	(t->name == _filter)
			{
				tags.Remove(t);
				_safe_delete(t);
				count++;
			}
	}
	else
		ListDeleteAllPtr(Tag *, tags)

	return count;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void		Tag::Free()
{
	value.Free();
	DeleteChildren();
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
Tag::~Tag()
{	Free();	}
//------------------------------------------------------------------------------
