var UPSXmlObject = new Object();

var XmlNodeType = {
	NODE_ELEMENT : 1,
	NODE_ATTRIBUTE : 2,
	NODE_TEXT : 3,
	NODE_CDATA_SECTION : 4,
	NODE_PROCESSING_INSTRUCTION : 7,
	NODE_DOCUMENT : 9
};

UPSXmlObject.XmlDocument = function(){
	this.xmlDocument = null;
};

UPSXmlObject.XmlDocument.prototype = {
	getDocument:function(){
		return this.xmlDocument;
	},
	
	setDocument:function(val){
		this.xmlDocument = val;
	},
	
	getDocumentElement:function(){
		return this.xmlDocument.documentElement;
	},
	
	createElementNode:function(nodeName, nodeValue){
		var xmlNode = this.xmlDocument.createElement(nodeName);
		xmlNode.text = nodeValue;
		return xmlNode;
	},
	
	createAjaxRequestNode:function(strAction)
	{
		var obRequestElement = this.createElementNode("ajaxRequest", "");
		this.addAttributeToNode(obRequestElement, "action", strAction);
		return obRequestElement;
	},
	
	addAttributeToNode:function(parentNode, attrName, attrValue){
		parentNode.setAttribute(attrName, attrValue);
	},
	
	addDocumentElement:function(child){
	    return this.xmlDocument.appendChild(child);
	},
	
	addElementToRoot:function(child){
		return this.xmlDocument.documentElement.appendChild(child);
	},
	
	addElementToParent:function(parentNode, childNode){
		return parentNode.appendChild(childNode);
	},
	
	getAttributeValue:function(elementNode, strAttribName){
		var attrib = elementNode.attributes.getNamedItem(strAttribName);
		if (null != attrib)
		{
			return attrib.value;
		}
		return null;
	},
	
	getElementFromParent:function(obParentNode, strNodeName){
		if (null != obParentNode)
		{
			var nodes = obParentNode.getElementsByTagName(strNodeName);
			if (null != nodes)
			{
				return nodes[0];
			}
		}
		return null;
	},
	
	getChildNodes:function(oParentNode, strQuery)
	{
		var oChildNodes = null;
		if(null != oParentNode)
		{
			oChildNodes = oParentNode.selectNodes(strQuery);
		}
		return oChildNodes;
	},
	
	loadXmlString:function(val){
		this.xmlDocument.loadXML(val);
	},
	
	toString:function(){
		return (this.xmlDocument.xml)?this.xmlDocument.xml:(new XMLSerializer).serializeToString(this.xmlDocument);
	}
};

var UPSXmlEngine = new Object();

UPSXmlEngine.prototype = {
	createXmlDocument:function(ns,rootElement)
	{
		var doc = null;
		var xmlDoc = new UPSXmlObject.XmlDocument();
		xmlDoc.xmlEngine = this;
		if (document.implementation &&
			document.implementation.createDocument)
		{
			doc = document.implementation.createDocument(ns,rootElement,null);
			// TODO: Add some features to add event listeners for various
			//		 loading stages of document.
			xmlDoc.setDocument(doc);
			return xmlDoc;
		}
		
		if (window.ActiveXObject)
		{
			doc = new ActiveXObject('MSXML2.DomDocument');
			if(null == doc)
			{
				doc = new ActiveXObject('Microsoft.DomDocument');
			}
			if (null == doc)
			{
				doc = new ActiveXObject('MSXML.DomDocument');
			}
			if (null == doc)
			{
				doc = new ActiveXObject('MSXML.DOMDocument30');
			}
			if (null == doc)
			{
				doc = new ActiveXObject('MSXML.DOMDocument40');
			}
			
			xmlDoc.setDocument(doc);
		}
		
		
		return xmlDoc;
	},
	
	loadDocumentFile:function(strFile){
	},
	
	loadDocumentString:function(strDocument){
	}
};
// mozXPath [http://km0ti0n.blunted.co.uk/mozxpath/] km0ti0n@gmail.com
// Code licensed under Creative Commons Attribution-ShareAlike License 
// http://creativecommons.org/licenses/by-sa/2.5/

if( document.implementation.hasFeature("XPath", "3.0") )
{
	XMLDocument.prototype.selectNodes = function(cXPathString, xNode)
	{
		if( !xNode ) { xNode = this; } 

		var oNSResolver = this.createNSResolver(this.documentElement)
		var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
		var aResult = [];
		for( var i = 0; i < aItems.snapshotLength; i++)
		{
			aResult[i] =  aItems.snapshotItem(i);
		}
		
		return aResult;
	}
	XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode)
	{
		if( !xNode ) { xNode = this; } 

		var xItems = this.selectNodes(cXPathString, xNode);
		if( xItems.length > 0 )
		{
			return xItems[0];
		}
		else
		{
			return null;
		}
	}

	Element.prototype.selectNodes = function(cXPathString)
	{
		if(this.ownerDocument.selectNodes)
		{
			return this.ownerDocument.selectNodes(cXPathString, this);
		}
		else{throw "For XML Elements Only";}
	}

	Element.prototype.selectSingleNode = function(cXPathString)
	{	
		if(this.ownerDocument.selectSingleNode)
		{
			return this.ownerDocument.selectSingleNode(cXPathString, this);
		}
		else{throw "For XML Elements Only";}
	}

}


