XMLUtils.prototype._array;
XMLUtils.prototype._request;

function XMLUtils()
{
	//if(navigator.userAgent.toLowerCase().indexOf("safari") != -1 && navigator.userAgent.toLowerCase().indexOf("chrome") == -1 && navigator.userAgent.toLowerCase().indexOf("version/4") == -1)
		//alert("Safari webbrowser older than version 4.0 not supported! Use IE, Opera, Chrome or Firefox");
		
	this._array = new Array();
	
	if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
		this._request = new XMLHttpRequest();
	else
		this._request = new ActiveXObject("MSXML2.XMLHTTP.3.0");
}

XMLUtils.prototype._download = function(href, post, returnXML)
{
	if(this._request != null)
	{
		//if(post != null)
		//{
			this._request.open("POST", href, false);
			this._request.send(post);
		//}
		//else
		//{
		//	this._request.open("GET", href, false);
		//	this._request.send(null);
		//}

		if(returnXML)
		{
			if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1)
				return this._request.responseXML;
			else if(navigator.userAgent.toLowerCase().indexOf("opera") != -1)
				return this._request.responseXML;
			else if(navigator.userAgent.toLowerCase().indexOf("chrome") != -1)
				return this._request.responseXML;
			else
			{
				var xml = this._request.responseXML;
				xml.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
   				xml.setProperty("SelectionLanguage", "XPath");
   				
   				return xml;
   			}
		}
		else
			return this._request.responseText;
	}
	else
		return null;
}

XMLUtils.prototype._files = function(href, data, xmlData)
{
	this.href = href;
	this.data = data;
	this.xmlData = xmlData;
}

XMLUtils.prototype.download = function(href, post, returnXML)
{
	for(var i = 0; i < this._array.length; i++)
	{
		if(this._array[i].href == href)
			return this._array[i].data;
	}
	
	var data = this._download(href, post, returnXML);
	
	if(data != null)
		this._array.push(new this._files(href, data));
	
	return data;
}

XMLUtils.prototype.toString = function(xml)
{
	if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
	{
		var ser = new XMLSerializer();
		return ser.serializeToString(xml);
	}
	else
		return xml.xml;
}

XMLUtils.prototype.transform = function(xml_file, xsl_file)
{
	if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
	{
		var text = this.toString(this.transformXML(xml_file, xsl_file));
		
		if(text.indexOf("<transformiix") == 0)
		{
			text = text.substr(text.indexOf(">") + 1);
			text = text.substr(0, text.lastIndexOf("</transformiix"));
		}
		
		return text;
	}
	else
	{
		var text = xml_file.transformNode(xsl_file);
		
		if(text.indexOf("<?xml") == 0)
			text = text.substr(text.indexOf(">") + 1);
		
		return text;
	}
}

XMLUtils.prototype.transformXML = function(xml_file, xsl_file)
{
	if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
	{
		var proc = new XSLTProcessor();
		proc.importStylesheet(xsl_file);
		
		return proc.transformToDocument(xml_file);
	}
	else
	{
		var result = new ActiveXObject("Msxml2.DOMDocument.3.0");
		xml_file.transformNodeToObject(xsl_file, result);
		
		return result;
	}
}

XMLUtils.prototype.getText = function(node)
{
	if(node == null)
		return "";
	
	var list = node.childNodes;
	
	if(list == null)
		return "";

	var child = null;
	
	for(var i = 0; i < list.length; i++)
	{
		child = list.item(i);
		
		if(child.nodeType == 3) // TextNode
		{
			if(child.nodeValue == "null")
				return "";
			else
				return child.nodeValue;
		}
	}
	
	return "";
}

XMLUtils.prototype.setText = function(node, text)
{
	var list = node.childNodes;
	var child = null;
	var text_node = null;
	
	for(var i = 0; i < list.length; i++)
	{
		child = list.item(i);
		if(child.nodeType == 3) // TextNode
			text_node = child;
	}
	
	if(text_node == null)
	{
		var text_node = node.ownerDocument.createTextNode(text);
		node.appendChild(text_node);
	}
	else
		text_node.nodeValue = text;
}

XMLUtils.prototype.createXMLDocument = function(xmlString)
{
	if(xmlString == null || xmlString == "")
		xmlString = "<?xml version='1.0' encoding='UTF-8' ?><root></root>";
		
	if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
	{
		var parser = new DOMParser();
		return parser.parseFromString(xmlString, "text/xml");
	}
	else
	{
		var doc = new ActiveXObject("Msxml2.DOMDocument.3.0");
		doc.async = "false";
		doc.loadXML(xmlString);
		doc.setProperty("SelectionNamespaces", "xmlns:xsl='http://www.w3.org/1999/XSL/Transform'");
   		doc.setProperty("SelectionLanguage", "XPath");
   				
		return doc;
	}
	
	return null;
}

XMLUtils.prototype.appendCDATASection = function(parent_node, data)
{
	var new_node = parent_node.ownerDocument.createCDATASection(data);
	return parent_node.appendChild(new_node);
}

XMLUtils.prototype.appendNode = function(parent_node, name)
{
	var new_node = parent_node.ownerDocument.createElement(name);
	return parent_node.appendChild(new_node);
}

XMLUtils.prototype.appendElement = function(parent_node, name, text)
{
	var new_node = parent_node.ownerDocument.createElement(name);
	this.setText(new_node, text);
	return parent_node.appendChild(new_node);
}

XMLUtils.prototype.insertNodeBefore = function(sibling_node, name)
{
	var new_node = sibling_node.ownerDocument.createElement(name);
	return sibling_node.parentNode.insertBefore(new_node, sibling_node);
}

XMLUtils.prototype.insertElementBefore = function(sibling_node, name, text)
{
	var new_node = sibling_node.ownerDocument.createElement(name);
	this.setText(new_node, text);
	return sibling_node.parentNode.insertBefore(new_node, sibling_node);
}

XMLUtils.prototype.cloneNode = function(node_to, node_from)
{
	return node_to.appendChild(node_from.cloneNode(true));
}

function NSResolver(prefix)
{
	if(prefix == 'html')
		return "http://www.w3.org/1999/xhtml";
	else if(prefix == 'mathml')
		return "http://www.w3.org/1998/Math/MathML";
	else if(prefix == 'xsl')
		return "http://www.w3.org/1999/XSL/Transform";
	else
		return null;
}

XPATH.prototype._list;
XPATH.prototype._it;

function XPATH()
{
}

XPATH.prototype.evaluate = function(node, xpath)
{
	this._list = null;
	
	if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
	{
		var doc = node;
		
		if(doc.nodeType != 9)
			doc = node.ownerDocument;
		
		this._list = doc.evaluate(xpath, node, NSResolver, 4, null);
	}
	else
		this._list = node.selectNodes(xpath);
}

XPATH.prototype.next = function()
{
	if(this._list == null)
		return null;
	
	var retVal = null;
	
	try
	{
		if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
			retVal = this._list.iterateNext();
		else
			retVal = this._list.nextNode();
	}
	catch(e){}
	
	return retVal;
}

XPATH.prototype.evaluateSnapshot = function(node, xpath, ordered)
{
	this._it = -1;
	this._list = null;
	
	if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
	{
		var doc = node;
		var type = 6;
		
		if(ordered)
			type = 7;
		
		if(doc.nodeType != 9)
			doc = node.ownerDocument;
		
		this._list = doc.evaluate(xpath, node, NSResolver, type, null);
	}
	else
		this._list = node.selectNodes(xpath);
}
			
XPATH.prototype.nextSnapshot = function()
{
	if(this._list == null)
		return null;
	
	var length = 0;
	
	if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
		length = this._list.snapshotLength;
	else
		length = this._list.length;
		
	if(++this._it < length)
	{
		if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
			return this._list.snapshotItem(this._it);
		else
			return this._list[this._it];
	}
	
	return null;
}

XPATH.prototype.getFirstNode = function(node, xpath_string)
{
	var temp = this._list;
	this.evaluate(node, xpath_string);	
	var result = this.next();
	
	this._list = temp;
	return result;
}

XPATH.prototype.getCount = function(node, xpath)
{
	var count = 0;
	
	if(navigator.userAgent.toLowerCase().indexOf("gecko") != -1 || navigator.userAgent.toLowerCase().indexOf("opera") != -1)
	{
		var doc = node;
		
		if(doc.nodeType != 9)
			doc = node.ownerDocument;
		
		count = doc.evaluate("count(" + xpath + ")", node, NSResolver, XPathResult.ANY_TYPE, null).numberValue;
	}
	else
		count = node.selectNodes(xpath).length;

	return count;
}
