/**
 * @file
 * @version @$Id$
 * @author
 * ui-gxmlcpp: C++ wrapper for Gnome libxml2/libxsl.
 * Copyright (C) Schlund+Partner AG 2002-2004.
 * Licensed under the GNU Lesser General Public License (LGPL). See
 * @ref License, or the file COPYING in distribution.
 */

// Local configuration
#include "config.h"

// Implementation
#include "XPathObject.hpp"

// STDC++
#include <string>
#include <cassert>

// C libraries
#include <ui-utilcpp/Text.hpp>

// Local
#include "Util.hpp"

namespace UI {
namespace GXML {

// XPathObject holder class
xmlXPathObjectPtr XPathObject::create(xmlXPathContextPtr const context, std::string const & xpath)
{
	xmlXPathObjectPtr obj(xmlXPathEval((xmlChar*)xpath.c_str(), context));
	if (obj == 0)
	{
		UI_THROW_CODE(EvalError_, "Error evaluating xpath: " + xpath);
	}
	return obj;
}

XPathObject::XPathObject(xmlXPathContextPtr const context, std::string const & xpath)
	:xpath_(xpath)
{
	set(create(context, xpath_));
}

XPathObject::XPathObject(XPathContext const & context, std::string const & xpath)
	:xpath_(xpath)
{
	set(create(context.get(), xpath_));
}

XPathObject::~XPathObject()
{
	xmlXPathFreeObject(get());
}

XPathObject::Type XPathObject::getType() const
{
	return get()->type;
}

std::string XPathObject::getString() const
{
	if (get()->stringval == 0 || get()->type != XPATH_STRING)
	{
		UI_THROW_CODE(NotAString_, "No string from xpath: " + xpath_);
	}
	else
	{
		return (char *)get()->stringval;
	}
}

double XPathObject::getNumber() const
{
	if (get()->type != XPATH_NUMBER)
	{
		UI_THROW_CODE(NotAFloat_, "No float from xpath: " + xpath_);
	}
	else
	{
		return get()->floatval;
	}
}

bool XPathObject::getBoolean() const
{
	if (get()->type != XPATH_BOOLEAN)
	{
		UI_THROW_CODE(NotABool_, "No bool from xpath: " + xpath_);
	}
	return (get()->boolval == 1);
}

}}
