/**
 * @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 "XSLTransTree.hpp"

// STDC++
#include <cassert>

// C libraries
#include <ui-utilcpp/Text.hpp>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>

// Local
#include "Util.hpp"

namespace UI {
namespace GXML {

XSLTransTree::Params & XSLTransTree::Params::add(std::string const & name, std::string const & value)
{
	CStrArray::add(name);
	CStrArray::add(value);
	return *this;
}

XSLTransTree::XSLTransTree(XSLTree const & style, Tree const & tree, Params const & params)
	:xslTree_(&style)
{
	xmlDoc * const doc(xsltApplyStylesheet(style.getStylesheet(), tree.get(), params.get()));
	if (!doc)
	{
		UI_THROW_CODE(Apply_, "Error applying stylesheet");
	}
	set(doc);
}

XSLTransTree::XSLTransTree(XSLTree const & style, XMLTree const * const tree, Params const & params)
	:xslTree_(&style)
{
	assert(tree);
	xmlDoc * const doc(xsltApplyStylesheet(style.getStylesheet(), tree->getDocPtr(), params.get()));
	if (!doc)
	{
		UI_THROW_CODE(Apply_, "Error applying stylesheet");
	}
	set(doc);
}

std::string XSLTransTree::getOutputEncoding() const
{
	return xslTree_->getOutputEncoding();
}

XSLTransTree::Dump::Dump(XSLTransTree const & xslTransTree)
	:xslTransTree_(&xslTransTree)
	,buf_(0)
	,size_(0)
{
	// Note: (1.1.8) xsltSaveResultToString does NOT return the amount of bytes on success as described in the docs.
	int res(xsltSaveResultToString(&buf_, &size_, xslTransTree_->get(), xslTransTree_->getStylesheet()));

	if (res < 0)
	{
		UI_THROW_CODE(Mem_, "Error dumping xsl translation result");
	}
}

XSLTransTree::Dump::~Dump()
{
	if (buf_)
	{
		xmlFree(buf_);
	}
}

char const * XSLTransTree::Dump::getC() const
{
	return buf_ ? (char *) buf_ : UI::Util::EmptyString_.c_str();
}

std::string XSLTransTree::Dump::get() const
{
	return getC();
}

int XSLTransTree::Dump::getSize() const
{
	return size_;
}

std::string XSLTransTree::Dump::getEncoding() const
{
	return xslTransTree_->getOutputEncoding();
}

xsltStylesheet * XSLTransTree::getStylesheet() const
{
	return xslTree_->getStylesheet();
}

}}
