/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/

#include "saxiohelper.h"
#include "saxio.h"
#include "scfonts.h"
#include "fpointarray.h"
#include "scclocale.h"

const Xml_string SaxIO::saxxDefaultElem;

Xml_string mkXMLName(const QString& any)
{
	QString result;
	for (int i=0; i < any.length(); ++i)
	{
		unsigned int ch = any[i].unicode();
		if (ch == ':' || ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')
			|| (0xC0 <= ch && ch <= 0xD6) || (0xD8 <= ch && ch <= 0xF6)
			|| (0xF8 <= ch && ch <= 0x2FF) || (0x370 <= ch && ch <= 0x37D)
			|| (0x37F <= ch && ch <= 0x1FFF) || (0x200C <= ch && ch <= 0x200D)
			|| (0x2070 <= ch && ch <= 0x218F) || (0x2C00 <= ch && ch <= 0x2FEF)
			|| (0x3001 <= ch && ch <= 0xD7FF) || (0xF900 <= ch && ch <= 0xFDCF)
			|| (0xFDF0 <= ch && ch <= 0xFFFD) || ch > 0xFFFF
			|| (i > 0 && (ch == '-' || ch == '.' || ('0' <= ch && ch <= '9') || ch == 0xB7
						  || (0x300 <= ch && ch <= 0x36F) || (0x203F <= ch && ch <= 0x2040) )))
		{
			result += QChar(ch);
		}
		else
		{
			result += '_';
			result += "0123456789ABCDEF"[(ch >> 12) & 15];
			result += "0123456789ABCDEF"[(ch >>  8) & 15];
			result += "0123456789ABCDEF"[(ch >>  4) & 15];
			result += "0123456789ABCDEF"[(ch      ) & 15];
		}
	}
	return result;
}

/*
 NameStartChar ::= ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] 
 | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
 NameChar	   ::=   	NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
*/


// FIXME: this is too Qt dependent
Xml_string toXMLString(unsigned int val)
{
	return QString::number(val);
}

char32_t parseChar32(const Xml_string& str)
{
	return static_cast<char32_t>(str.toUInt());
}

unsigned int parseUInt(const Xml_string& str)
{
	return str.toUInt();
}

Xml_string toXMLString(int val)
{
	return QString::number(val);
}


int parseInt(const Xml_string& str)
{
	return str.toInt();
}


Xml_string toXMLString(unsigned long val)
{
	return QString::number(val);
}

unsigned long parseULong(const Xml_string& str)
{
	return str.toULong();
}

Xml_string toXMLString(long val)
{
	return QString::number(val);
}


long parseLong(const Xml_string& str)
{
	return str.toLong();
}


Xml_string toXMLString(double val)
{
	return QString::number(val, 'g', 10);
}

Xml_string toXMLString(float val)
{
	return QString::number(val);
}

double parseDouble(const Xml_string& str)
{
	return ScCLocale::toDoubleC(str);
}

float parseFloat(const Xml_string& str)
{
	return ScCLocale::toFloatC(str);
}


Xml_string toXMLString(bool val)
{
	return val ? "yes" : "no";
}


bool parseBool(const Xml_string& str)
{
	return str == "yes";
}


Xml_string toXMLString(const Xml_string& val)
{
	return val;
}


Xml_string toXMLString(const QList<double>& doublelist)
{
	QString result;
	for (double dax : doublelist)
		result += toXMLString(dax) + " ";
	return result;
}

Xml_string toXMLString(const QList<float>& floatlist)
{
	QString result;
	for (float dax : floatlist)
		result += toXMLString(dax) + " ";
	return result;
}

QList<double> parseDoubleList(const Xml_string& str)
{
	const QStringList strlist = str.split(' ', Qt::SkipEmptyParts);
	QList<double> result;
	for (const QString& qStr : strlist)
		result.append(parseDouble(qStr));
	return result;
}


QVector<double> parseDoubleVector(const Xml_string& str)
{
	const QStringList strlist = str.split(' ', Qt::SkipEmptyParts);
	QVector<double> result;
	for (const QString& qStr : strlist)
		result.append(parseDouble(qStr));
	return result;
}


Xml_string toXMLString(const QList<int>& intlist)
{
	QString result;
	for (int dax : intlist)
		result += toXMLString(dax) + " ";
	return result;
}


QList<int> parseIntList(const Xml_string& str)
{
	const QStringList strlist = str.split(' ', Qt::SkipEmptyParts);
	QList<int> result;
	for (const QString& qStr : strlist)
		result.append(parseInt(qStr));
	return result;
}


QVector<int> parseIntVector(const Xml_string& str)
{
	const QStringList strlist = str.split(' ', Qt::SkipEmptyParts);
	QVector<int> result;
	for (const QString& qStr : strlist)
		result.append(parseInt(qStr));
	return result;
}


QStack<int> parseIntStack(const Xml_string& str)
{
	const QStringList strlist = str.split(' ', Qt::SkipEmptyParts);
	QStack<int> result;
	for (const QString& qStr : strlist)
		result.append(parseInt(qStr));
	return result;
}


Xml_string toXMLString(const QStringList& list)
{
	QString result;
	for (const QString& str : list)
		result += str + " ";
	return result;
}


QStringList parseStringList(const Xml_string&  str)
{
	return str.split(' ', Qt::SkipEmptyParts);
}


// FIXME: the following should not be in desaxe:
Xml_string toXMLString(const ScFace& val)
{
	return val.scName();
}


Xml_string toXMLString(const FPointArray& path)
{
	return path.svgPath();
}
