
//namespace
var xml = new Object();

xml.useActiveX = typeof ActiveXObject != 'undefined';
xml.useDom = document.implementation &&  document.implementation.createDocument;
xml.DOM_VER = null;

// class
xml.DOMDocument = function()
{
}

xml.DOM_VERS = [/*'MSXML2.DOMDocument.5.0', 'MSXML2.DOMDocument.4.0',*/ 'MSXML2.DOMDocument.3.0', 'MSXML2.DOMDocument', 'Microsoft.XmlDom'];

xml.DOMDocument.create = function(xml_text)
{
	if(xml.useDom)
		if (xml_text)
			return (new DOMParser()).parseFromString(xml_text, 'text/xml');
		else
			return document.implementation.createDocument('', '', null);
	else if(xml.useActiveX)
	{
		if(!xml.DOM_VER)
		{
			for(var i=0; i < xml.DOM_VERS.length; i++)
			{
				try
				{
					new ActiveXObject(xml.DOM_VERS[i]);
					xml.DOM_VER = xml.DOM_VERS[i];
					break;
				}
				catch(oError)
				{}
			}
		}
		
		if(xml.DOM_VER)
		{
			var res = new ActiveXObject(xml.DOM_VER);
			if (xml_text) res.loadXML(xml_text);
			return res;
		}
		else
			throw new Error("Could not create XML DOM document.");
	}
	else
		throw new Error("Your browser doesn't support an XML DOM document.");
}

// adapts ff XMLDocument to ms dom
if (typeof XMLDocument != 'undefined')
{
	XMLDocument.prototype.__defineGetter__('xml', function()
	{
		var serializer = new XMLSerializer();
		return serializer.serializeToString(this, 'text/xml');
	});
	
	XMLDocument.prototype.loadXML = function(s)
	{
		var parser = new DOMParser();
		var dom = parser.parseFromString(s, 'text/xml');

		while(this.firstChild) this.removeChild(this.firstChild);
		for(var i = 0; i < dom.childNodes.length; i++)
			this.appendChild(this.importNode(dom.childNodes[i], true));
			
        return this.documentElement != null;
	}

	XMLDocument.prototype.selectNodes = function(xpath, node)
	{
		if (typeof XPathEvaluator != 'undefined')
		{
			if (!node) node = this;
			var evaluator = new XPathEvaluator();
			var xpathRes = evaluator.evaluate(xpath, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
			var res = new Array();

			for(var i = 0; i < xpathRes.snapshotLength; i++)
				res[i] = xpathRes.snapshotItem(i);
			
			return res;
		}
		else
			throw new Error('No XPath engine found.');
	}

	XMLDocument.prototype.selectSingleNode = function(xpath, node)
	{
		if (typeof XPathEvaluator != 'undefined')
		{
			if (!node) node = this;
			var evaluator = new XPathEvaluator();
			var xpathRes = evaluator.evaluate(xpath, node, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null)
			return xpathRes ? xpathRes.singleNodeValue : null
		}
		else
			throw new Error("No XPath engine found.");
	}

	XMLDocument.prototype.transformNode = function(xslDOM)
	{
		if(typeof XSLTProcessor != 'undefined')
		{
			var processor = new XSLTProcessor();
			processor.importStylesheet(xslDOM);
			var resDOM = processor.transformToDocument(this);
			var res = resDOM.xml;

			if(res.indexOf('<transformiix:result') > -1)
				res = res.substring(res.indexOf('>') + 1, res.lastIndexOf('<'));
			return res;
		}
		else
			throw new Error("No XSLT engine found.");
	}

    Node.prototype.__defineGetter__('xml',
		function()
		{
			var serializer = new XMLSerializer();
			return serializer.serializeToString(this, 'text/xml');
		});
    
    Node.prototype.__defineGetter__('text',
		function()
		{
			var res = '';
			for(var i = 0; i < this.childNodes.length; i++)
				if (this.childNodes[i].hasChildNodes())
					res += this.childNodes[i].text;
				else
					res += this.childNodes[i].nodeValue;
			return res;
		});		
		
    Node.prototype.__defineSetter__('text',
		function(val)
		{
		    while(this.firstChild) this.removeChild(this.firstChild);
		    this.appendChild(this.ownerDocument.createTextNode(val));	
		});				
		
	Node.prototype.selectNodes = function(xpath)
	{
		return this.ownerDocument.selectNodes(xpath, this);
	}

	Node.prototype.selectSingleNode = function(xpath)
	{
		return this.ownerDocument.selectSingleNode(xpath, this);
	}
	
	Node.prototype.transformNode = XMLDocument.prototype.transformNode;
}
