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


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

		using namespace GS;
		using namespace GS::NML;


static bool MetatagNameCompare(const Tag *o, const String &name) { return o->name == name; }

//------------------------------------------------------------------------------
Tag				*Tag::GetTagEx(const List <Tag *> &tg, const char *s, const File *, bool verbose)
{
	if	(!s)
		return NULL;

	const char *path = s;
	const List <Tag *> *list = &tg;

	Tag *tag = NULL;

	while (s[0])
	{
		while (s[0] == ':')
			s++;
		if	(s[0] == ';')
			break;

		const char *t = s;
		while ((t[0] != ';') && (t[0] != ':') && t[0])
			t++;
		if	(!t[0] && verbose)
		{
			if	(t > s)
					__LOG_W__ << "incomplete path '" << path << "' (missing ';').\n";
			else	__LOG_E__ << "unexpected end of path'" << path << "'.\n";
		}

		// No more node to search.
		if	(!list)
		{
			if	(verbose)
				__LOG_W__ << "'" << path << "' is deeper than lowest tree node.\n";
			return NULL;
		}

		String node_name(s, t);
		s = t;
		tag = ListFindEx(*list, MetatagNameCompare, node_name);

		if	(tag == NULL)
		{
			if	(verbose)
				__LOG__ << "!! Error '" << node_name << "' in '" << path << "' not found.\n";
			return NULL;
		}

		switch (tag->GetValue().GetType())
		{
			case Variant::VariantNone:
				list = &tag->tags;
				break;

			default:
				list = NULL;
				break;
		}
	}
	return tag;
}
Tag				*Tag::GetTag(const char *path, const File *root, bool verbose) const
{
	return GetTagEx(tags, path, root, verbose);
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
Tag				*Tag::GetTypedTag(const char *path, Variant::Type type, const File *root, bool verbose) const
{
	Tag *t = Tag::GetTagEx(tags, path, root, verbose);
	if	((!t) || (t->GetValue().GetType() != type))
		return NULL;
	return t;
}
Tag				*File::GetTypedTag(const char *path, Variant::Type type, bool verbose) const
{
	Tag *t = Tag::GetTagEx(tags, path, this, verbose);
	if	((!t) || (t->GetValue().GetType() != type))
		return NULL;
	return t;
}
//------------------------------------------------------------------------------
