/*
 * jidutil.h
 * Copyright (C) 2006  Remko Troncon, Justin Karneges
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU 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_jid.h"
#include "jidutil.h"
#include "psioptions.h"

using namespace XMPP;

QString JIDUtil::defaultDomain()
{
	return PsiOptions::instance()->getOption("options.account.domain").toString();
}

void JIDUtil::setDefaultDomain(QString domain)
{
	PsiOptions::instance()->setOption("options.account.domain", domain);
}

QString JIDUtil::encode(const QString &jid)
{
	QString jid2;

	for(int n = 0; n < jid.length(); ++n) {
		if(jid.at(n) == '@') {
			jid2.append("_at_");
		}
		else if(jid.at(n) == '.') {
			jid2.append('.');
		}
		else if(!jid.at(n).isLetterOrNumber()) {
			// hex encode
			QString hex;
			hex.sprintf("%%%02X", jid.at(n).toLatin1());
			jid2.append(hex);
		}
		else {
			jid2.append(jid.at(n));
		}
	}

	return jid2;
}

QString JIDUtil::decode(const QString &jid)
{
	QString jid2;
	int n;

	for(n = 0; n < (int)jid.length(); ++n) {
		if(jid.at(n) == '%' && (jid.length() - n - 1) >= 2) {
			QString str = jid.mid(n+1,2);
			bool ok;
			char c = str.toInt(&ok, 16);
			if(!ok)
				continue;

			QChar a(c);
			jid2.append(a);
			n += 2;
		}
		else {
			jid2.append(jid.at(n));
		}
	}

	// search for the _at_ backwards, just in case
	for(n = jid2.length()-5; n >= 1; --n) {
		if(jid2.at(n) == '_') {
			if(jid2.mid(n, 4) == "_at_") {
				jid2.replace(n, 4, "@");
				break;
			}
			n -= 2;
		}
	}

	return jid2;
}

QString JIDUtil::nickOrJid(const QString &nick, const QString &jid)
{
	if(nick.isEmpty())
		return jid;
	else
		return nick;
}

QString JIDUtil::accountToString(const Jid& j, bool withResource)
{
	QString s = j.node();
	if (!defaultDomain().isEmpty()) {
		return (withResource && !j.resource().isEmpty() ? j.node() + "/" + j.resource() : j.node());
	}
	else {
		return (withResource ? j.full() : j.bare());
	}
}

Jid JIDUtil::accountFromString(const QString& s)
{
	if (!defaultDomain().isEmpty()) {
		return Jid(s, defaultDomain(), "");
	}
	else {
		return Jid(s);
	}
}

QString JIDUtil::toString(const Jid& j, bool withResource)
{
	return (withResource ? j.full() : j.bare());
}

Jid JIDUtil::fromString(const QString& s)
{
	return Jid(s);
}

QString JIDUtil::encode822(const QString &s)
{
	QString out;
	for(int n = 0; n < (int)s.length(); ++n) {
		if(s[n] == '\\' || s[n] == '<' || s[n] == '>') {
			QString hex;
			hex.sprintf("\\x%02X", (unsigned char )s[n].toLatin1());
			out.append(hex);
		}
		else
			out += s[n];
	}
	return out;
}

QString JIDUtil::decode822(const QString &s)
{
	QString out;
	for(int n = 0; n < (int)s.length(); ++n) {
		if(s[n] == '\\' && n + 3 < (int)s.length()) {
			int x = n + 1;
			n += 3;
			if(s[x] != 'x')
				continue;
			ushort val = 0;
			val += QString(s[x+1]).toInt(NULL,16);
			val += QString(s[x+2]).toInt(NULL,16);
			QChar c(val);
			out += c;
		}
		else
			out += s[n];
	}
	return out;
}

