/*****************
 * XMLFunctions
 */
 

// used to find the Automation server name
function getDomDocumentPrefix() {
	if (getDomDocumentPrefix.prefix)
		return getDomDocumentPrefix.prefix;
	
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for (var i = 0; i < prefixes.length; i++) {
		try {
			// try to create the objects
			o = new ActiveXObject(prefixes[i] + ".DomDocument");
			return getDomDocumentPrefix.prefix = prefixes[i];
		}
		catch (ex) {};
	}
	
	throw new Error("Could not find an installed XML parser");
}

function getXmlHttpPrefix() {
	if (getXmlHttpPrefix.prefix)
		return getXmlHttpPrefix.prefix;
	
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for (var i = 0; i < prefixes.length; i++) {
		try {
			// try to create the objects
			o = new ActiveXObject(prefixes[i] + ".XmlHttp");
			return getXmlHttpPrefix.prefix = prefixes[i];
		}
		catch (ex) {};
	}
	
	throw new Error("Could not find an installed XML parser");
}

//////////////////////////
// Start the Real stuff //
//////////////////////////


// XmlHttp factory
function XmlHttp() {}

XmlHttp.create = function () {
	try {
		if (window.XMLHttpRequest) {
			var req = new XMLHttpRequest();
			
			// some versions of Moz do not support the readyState property
			// and the onreadystate event so we patch it!
			if (req.readyState == null) {
				req.readyState = 1;
				req.addEventListener("load", function () {
					req.readyState = 4;
					if (typeof req.onreadystatechange == "function")
						req.onreadystatechange();
				}, false);
			}
			
			return req;
		}
		if (window.ActiveXObject) {
			return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");
		}
	}
	catch (ex) {}
	// fell through
	throw new Error("Your browser does not support XmlHttp objects");
};

// XmlDocument factory
function XmlDocument() {}

XmlDocument.create = function () {
	try {
		// DOM2
		if (document.implementation && document.implementation.createDocument) {
			var doc = document.implementation.createDocument("", "", null);
			
			// some versions of Moz do not support the readyState property
			// and the onreadystate event so we patch it!
			if (doc.readyState == null) {
				doc.readyState = 1;
				doc.addEventListener("load", function () {
					doc.readyState = 4;
					if (typeof doc.onreadystatechange == "function")
						doc.onreadystatechange();
				}, false);
			}
			
			return doc;
		}
		if (window.ActiveXObject)
			return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");
	}
	catch (ex) {}
	throw new Error("Your browser does not support XmlDocument objects");
};

// Create the loadXML method and xml getter for Mozilla
if (window.DOMParser &&
	window.XMLSerializer &&
	window.Node && Node.prototype && Node.prototype.__defineGetter__) {

	// XMLDocument did not extend the Document interface in some versions
	// of Mozilla. Extend both!
	//XMLDocument.prototype.loadXML = 
	Document.prototype.loadXML = function (s) {
		
		// parse the string to a new doc	
		var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
		
		// remove all initial children
		while (this.hasChildNodes())
			this.removeChild(this.lastChild);
			
		// insert and import nodes
		for (var i = 0; i < doc2.childNodes.length; i++) {
			this.appendChild(this.importNode(doc2.childNodes[i], true));
		}
	};
	Document.prototype.__defineGetter__("xml", function () {
		return (new XMLSerializer()).serializeToString(this);
	});
}

function getXmlResponse(sUri, bAsync)
{
	var done = function ()
	{
		try
		{
			var str = xmlHttp.responseText;
			return str;
		}
		catch (exc)
		{
			alert('An error occured, no good response');
		}
	};
	
	var xmlHttp = XmlHttp.create();
	xmlHttp.open("GET", sUri, bAsync);
	if (bAsync)
	{
		xmlHttp.onreadystatechange = function ()
		{
			if (xmlHttp.readyState == 4 || xmlHttp.readyState == "complete")
			{
				done();
				return xmlHttp.responseText;
			}			
		}
	}
	xmlHttp.send(null);
	if (!bAsync)
	{
		return done();
	}
}

 function createArray(str, lengte, counter)
 {
	counter++;

	 // initializing the array (object)
	var serArr = new Object();

	 // i will hold the position of where we are in the string
	var i = 0;
	 // number will keep track of how many elements we've parsed. It can never exceed the variable lengte
	var number = 0;

	while (number < lengte)
	{
		/*****
		 * Getting the key/index of the current element
		 ***/
		 // first we're gonna determine the length of the key.
		 // this is represented by a number in the string.
		 // offset is gonna contain the first position of that number and j will hold the last position after the while loop
		var loop_i = 0;			// loop_i is gonna keep track of how many characters we advance this element
		var offset = i+2;
		var j = offset;
		var continu = true;
		while (continu)
		{
			 // currentChar is the current character we're evaluating
			currentChar = str.charAt(j);
			 // if the currentChar is not a number, we break. else, we just increase j so we can evaluate the next
			if (currentChar != parseInt(currentChar))
			{
				break;
			}
			else
				j++;
		}
		loop_i = loop_i + 2 + (j- offset);		// 2 is for i: or s:
		 // j will now hold the position of the last digit of the number

		 // we're dealing with a key/string that is represented as a String
		 // we now can determine the length and then extract the name of the key/index
		if (str.charAt(i) == 's')
		{
			loop_i = loop_i + 1;		// the : that precedes the string "value"
			 // the numerical representation of the length (for example with 'index' this would be 5
			var keyLength = str.substring(offset, j);
			 // thisKey is now gonna get the name of the key/index (in our example : index)
			var thisKey = str.substr((j+2), parseInt(keyLength));
			 // we log the intervals for debugging purposes
			var keyIntervals = (j+2)+','+keyLength;

			 // after having determined the key/index we're gonna determine the corresponding value
			 // instead of i we're gonna use the variable nextI.
			 // here we give it the right position
			var nextI = j+2+parseInt(keyLength)+2;

			loop_i = loop_i + 2 + thisKey.length;		// 2 is for the double quotes around the string
		}
		 // we're dealing with a key/string that is represented as an Integer
		 // this means that the number we just extracted is also the name of the key/index
		else if (str.charAt(i) == 'i')
		{
			var keyLength = str.substring(offset, j);
			var thisKey = keyLength;
			var keyIntervals = offset+','+j;

			var nextI = i + 1 + keyLength.length + 2;
		}
		else
		{
			alert('!!!str.charAt(i) is geen i maar ook geen s!!! ('+str.charAt(i)+')');
		}
		loop_i = loop_i + 1;		// the ; that ends the key

		/*****
		 * Getting the value of the current element
		 ***/
		var offset = nextI+2;
		var j = offset;
		var continu = true;
		while (continu)
		{
			var currentChar = str.charAt(j);
			if (currentChar != parseInt(currentChar))
			{
				break;
			}
			else
				j++;
		}
		loop_i = loop_i + 2 + (j- offset);		// 2 is for a: or s:
		loop_i = loop_i + 1;				// 1 for the : after that

		var valLength = str.substring(offset, j);

		 // we're dealing with an array
		if (str.charAt(nextI) == 'a')
		{
			var stringFromArray = str.substr(nextI);
			var tempFirstAndLast = getFirstAndLast(stringFromArray);
			var newArrayString = stringFromArray.substring(tempFirstAndLast[0], tempFirstAndLast[1]);
			var thisValue = createArray(newArrayString, valLength, counter);

			var valIntervals = tempFirstAndLast[0]+','+tempFirstAndLast[1];

			loop_i = loop_i + 2 + newArrayString.length;		// 2 is for the {}
		}
		 // it's a normal string
		else
		{
			var thisValue = str.substr((j+2), parseInt(valLength));
			var valIntervals = (j+2)+','+valLength;

			loop_i = loop_i + thisValue.length + 2 + 1;		// 2 is the double quotes again and 1 the ending ;
		}
		i = i + loop_i;
		number++;
		serArr[thisKey] = thisValue;
	}
	return serArr;
 }
 function getFirstAndLast(str)
 {
	var lengte = str.length;
	var first = str.search(/{/);
	var i = first;
	var whenZero = 1;
	while (++i < lengte && whenZero > 0)
	{
		if (str.charAt(i) == '}')
		{
			whenZero--;
		}
		else if (str.charAt(i) == '{')
		{
			whenZero++;
		}
		if (whenZero == 0)
		{
			var last = i;
		}
	}
	var arr = [];
	arr[0] = first+1;
	arr[1] = last;
	return arr;
 }
 function showObj(arr, indent)
 {
	var output = '';
	for (var i in arr)
	{
		output = output + '<div style="padding-left: '+indent+'px;">'+i;
		if (typeof arr[i] == 'string')
		{
			output = output + ' => '+arr[i]+'</div>';
		}
		else
		{
			output = output + ' => Array()</div>';
			output = output + showObj(arr[i], (indent + 15))
		}
	}
	return output;
 }
 
 function getArraySize(str)
 {
	j = 2;
	var continu = true;
	while (continu)
	{
		 // currentChar is the current character we're evaluating
		currentChar = str.charAt(j);
		 // if the currentChar is not a number, we break. else, we just increase j so we can evaluate the next
		if (currentChar != parseInt(currentChar))
		{
			break;
		}
		else
			j++;
	}
	return str.substring(2, j);
 }
