/*
 * xmlcommon.cpp - helper functions for dealing with XML
 * Copyright (C) 2001, 2002  Justin Karneges
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include "xmpp_xmlcommon.h"

#include <tqstring.h>
#include <tqdom.h>
#include <tqdatetime.h>
#include <tqsize.h>
#include <tqrect.h>
#include <tqstringlist.h>
#include <tqcolor.h>

#include "im.h"

bool stamp2TS(const TQString &ts, TQDateTime *d)
{
	if(ts.length() != 17)
		return false;

	int year  = ts.mid(0,4).toInt();
	int month = ts.mid(4,2).toInt();
	int day   = ts.mid(6,2).toInt();

	int hour  = ts.mid(9,2).toInt();
	int min   = ts.mid(12,2).toInt();
	int sec   = ts.mid(15,2).toInt();

	TQDate xd;
	xd.setYMD(year, month, day);
	if(!xd.isValid())
		return false;

	TQTime xt;
	xt.setHMS(hour, min, sec);
	if(!xt.isValid())
		return false;

	d->setDate(xd);
	d->setTime(xt);

	return true;
}

TQString TS2stamp(const TQDateTime &d)
{
	TQString str;

	str.sprintf("%04d%02d%02dT%02d:%02d:%02d",
		d.date().year(),
		d.date().month(),
		d.date().day(),
		d.time().hour(),
		d.time().minute(),
		d.time().second());

	return str;
}

TQDomElement textTag(TQDomDocument *doc, const TQString &name, const TQString &content)
{
	TQDomElement tag = doc->createElement(name);
	TQDomText text = doc->createTextNode(content);
	tag.appendChild(text);

	return tag;
}

TQString tagContent(const TQDomElement &e)
{
	// look for some tag content
	for(TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
		TQDomText i = n.toText();
		if(i.isNull())
			continue;
		return i.data();
	}

	return "";
}

TQDomElement findSubTag(const TQDomElement &e, const TQString &name, bool *found)
{
	if(found)
		*found = false;

	for(TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
		TQDomElement i = n.toElement();
		if(i.isNull())
			continue;
		if(i.tagName() == name) {
			if(found)
				*found = true;
			return i;
		}
	}

	TQDomElement tmp;
	return tmp;
}

TQDomElement createIQ(TQDomDocument *doc, const TQString &type, const TQString &to, const TQString &id)
{
	TQDomElement iq = doc->createElement("iq");
	if(!type.isEmpty())
		iq.setAttribute("type", type);
	if(!to.isEmpty())
		iq.setAttribute("to", to);
	if(!id.isEmpty())
		iq.setAttribute("id", id);

	return iq;
}

TQDomElement queryTag(const TQDomElement &e)
{
	bool found;
	TQDomElement q = findSubTag(e, "query", &found);
	return q;
}

TQString queryNS(const TQDomElement &e)
{
	bool found;
	TQDomElement q = findSubTag(e, "query", &found);
	if(found)
		return q.attribute("xmlns");

	return "";
}

void getErrorFromElement(const TQDomElement &e, int *code, TQString *str)
{
	bool found;
	TQDomElement tag = findSubTag(e, "error", &found);
	if(!found)
		return;

	if(code)
		*code = tag.attribute("code").toInt();
	if(str)
		*str = tagContent(tag);
}

//----------------------------------------------------------------------------
// XMLHelper
//----------------------------------------------------------------------------

namespace XMLHelper {

TQDomElement emptyTag(TQDomDocument *doc, const TQString &name)
{
	TQDomElement tag = doc->createElement(name);

	return tag;
}

bool hasSubTag(const TQDomElement &e, const TQString &name)
{
	bool found;
	findSubTag(e, name, &found);
	return found;
}

TQString subTagText(const TQDomElement &e, const TQString &name)
{
	bool found;
	TQDomElement i = findSubTag(e, name, &found);
	if ( found )
		return i.text();
	return TQString();
}

TQDomElement textTag(TQDomDocument &doc, const TQString &name, const TQString &content)
{
	TQDomElement tag = doc.createElement(name);
	TQDomText text = doc.createTextNode(content);
	tag.appendChild(text);

	return tag;
}

TQDomElement textTag(TQDomDocument &doc, const TQString &name, int content)
{
	TQDomElement tag = doc.createElement(name);
	TQDomText text = doc.createTextNode(TQString::number(content));
	tag.appendChild(text);

	return tag;
}

TQDomElement textTag(TQDomDocument &doc, const TQString &name, bool content)
{
	TQDomElement tag = doc.createElement(name);
	TQDomText text = doc.createTextNode(content ? "true" : "false");
	tag.appendChild(text);

	return tag;
}

TQDomElement textTag(TQDomDocument &doc, const TQString &name, TQSize &s)
{
	TQString str;
	str.sprintf("%d,%d", s.width(), s.height());

	TQDomElement tag = doc.createElement(name);
	TQDomText text = doc.createTextNode(str);
	tag.appendChild(text);

	return tag;
}

TQDomElement textTag(TQDomDocument &doc, const TQString &name, TQRect &r)
{
	TQString str;
	str.sprintf("%d,%d,%d,%d", r.x(), r.y(), r.width(), r.height());

	TQDomElement tag = doc.createElement(name);
	TQDomText text = doc.createTextNode(str);
	tag.appendChild(text);

	return tag;
}

TQDomElement stringListToXml(TQDomDocument &doc, const TQString &name, const TQStringList &l)
{
	TQDomElement tag = doc.createElement(name);
	for(TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it)
		tag.appendChild(textTag(doc, "item", *it));

	return tag;
}

/*TQString tagContent(const TQDomElement &e)
{
	// look for some tag content
	for(TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
		TQDomText i = n.toText();
		if(i.isNull())
			continue;
		return i.data();
	}

	return "";
}*/

/*TQDomElement findSubTag(const TQDomElement &e, const TQString &name, bool *found)
{
	if(found)
		*found = false;

	for(TQDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
		TQDomElement i = n.toElement();
		if(i.isNull())
			continue;
		if(i.tagName() == name) {
			if(found)
				*found = true;
			return i;
		}
	}

	TQDomElement tmp;
	return tmp;
}*/

void readEntry(const TQDomElement &e, const TQString &name, TQString *v)
{
	bool found = false;
	TQDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	*v = tagContent(tag);
}

void readNumEntry(const TQDomElement &e, const TQString &name, int *v)
{
	bool found = false;
	TQDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	*v = tagContent(tag).toInt();
}

void readBoolEntry(const TQDomElement &e, const TQString &name, bool *v)
{
	bool found = false;
	TQDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	*v = (tagContent(tag) == "true");
}

void readSizeEntry(const TQDomElement &e, const TQString &name, TQSize *v)
{
	bool found = false;
	TQDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	TQStringList list = TQStringList::split(',', tagContent(tag));
	if(list.count() != 2)
		return;
	TQSize s;
	s.setWidth(list[0].toInt());
	s.setHeight(list[1].toInt());
	*v = s;
}

void readRectEntry(const TQDomElement &e, const TQString &name, TQRect *v)
{
	bool found = false;
	TQDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	TQStringList list = TQStringList::split(',', tagContent(tag));
	if(list.count() != 4)
		return;
	TQRect r;
	r.setX(list[0].toInt());
	r.setY(list[1].toInt());
	r.setWidth(list[2].toInt());
	r.setHeight(list[3].toInt());
	*v = r;
}

void readColorEntry(const TQDomElement &e, const TQString &name, TQColor *v)
{
	bool found = false;
	TQDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	TQColor c;
	c.setNamedColor(tagContent(tag));
	if(c.isValid())
		*v = c;
}

void xmlToStringList(const TQDomElement &e, const TQString &name, TQStringList *v)
{
	bool found = false;
	TQDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	TQStringList list;
	for(TQDomNode n = tag.firstChild(); !n.isNull(); n = n.nextSibling()) {
		TQDomElement i = n.toElement();
		if(i.isNull())
			continue;
		if(i.tagName() == "item")
			list += tagContent(i);
	}
	*v = list;
}

void setBoolAttribute(TQDomElement e, const TQString &name, bool b)
{
	e.setAttribute(name, b ? "true" : "false");
}

void readBoolAttribute(TQDomElement e, const TQString &name, bool *v)
{
	if(e.hasAttribute(name)) {
		TQString s = e.attribute(name);
		*v = (s == "true");
	}
}

}

