// ************************************************************
// Helpers for Ajax Creation/
// ************************************************************
function AjaxTools()
{
	this.CreateXmlHttpRequest = ajaxTools_CreateXmlHttpRequest;
	this.CreateXmlDocument = ajaxTools_CreateXmlDocument;
	this.CreateXmlDocumentFromUrl = ajaxTools_CreateXmlDocumentFromUrl;
	this.CreateXmlDocumentFromContent = ajaxTools_CreateXmlDocumentFromContent;
	this.ApplyTransform = ajaxTools_ApplyTransform;
	this.GetNodeValue2 = ajaxTools_GetNodeValue2;
	this.SetNodeValue2 = ajaxTools_SetNodeValue2;
	this.SelectNodes2 = ajaxTools_SelectNodes2;
	this.SelectSingleNode2 = ajaxTools_SelectSingleNode2;

	// Required for mozilla
	this.NsResolver = ajaxTools_NsResolver;

	// Backwards-compatibility methods
	this.GetNodeValue = ajaxTools_GetNodeValue;
	this.SetNodeValue = ajaxTools_SetNodeValue;
	this.GetFirstNode = ajaxTools_GetFirstNode;
	this.SelectNodes = ajaxTools_SelectNodes;
	this.SelectSingleNode = ajaxTools_SelectSingleNode;

	this.isMozilla = (typeof document.implementation != 'undefined') && 
	                (typeof document.implementation.createDocument != 'undefined');

	// Checks if a context node was specified,
	// if not used the document itself as a context node
	function GetContextNode(doc, node)
	{
		if(node) return(node);
		return(doc);
	}

	// Creation of HTTP Request 
	function ajaxTools_CreateXmlHttpRequest() 
	{
		if(this.isMozilla)
		{
			return(new XMLHttpRequest());
		}
		else
		{
			return(new ActiveXObject("Msxml2.XMLHTTP"));
		}
	}
	
	// Creation of XML Document
	function ajaxTools_CreateXmlDocument()
	{
		if(this.isMozilla)
		{
			return(document.implementation.createDocument("", "doc", null));	
		}
		else
		{
			return(new ActiveXObject("Msxml2.DomDocument"));	
		}	
	}
	
	// Creation of XML Document from a specified URL
	function ajaxTools_CreateXmlDocumentFromUrl(url)
	{
		var xmlDoc = this.CreateXmlDocument();
		xmlDoc.async = false;
		xmlDoc.load(url);
		return(xmlDoc);
	}
	
	// Creation of XML Document from a specified URL
	function ajaxTools_CreateXmlDocumentFromContent(content)
	{
		var xmlDoc = this.CreateXmlDocument();
		
		if(this.isMozilla)
		{
			var parser = new DOMParser();
			var xmlDoc = parser.parseFromString(content, 'application/xml');
			return(xmlDoc);
		}
		else
		{
			var xmlDoc = new ActiveXObject("Msxml2.DomDocument");
			xmlDoc.loadXML(content);
			return(xmlDoc);
		}
	}
	
	// Apply a XSLT transformation to a page and retrieves the processed text context
	function ajaxTools_ApplyTransform(doc, transform)
	{
		if(this.isMozilla)
		{
			var processor = new XSLTProcessor();
			processor.importStylesheet(transform);
			
			var transformedDoc = processor.transformToDocument(doc);
			
			var serializer = new XMLSerializer();
			return(serializer.serializeToString(transformedDoc));
		}
		else
		{
			return(doc.transformNode(transform));	
		}
	}	
	
	// Required for the mozilla "evaluate" method	
	function ajaxTools_NsResolver(prefix) 
	{
		if(prefix == 'xsl') 
		{
			return 'http://www.w3.org/1999/XSL/Transform';
		}
		return null;
	}
	
	// Gets the value of the xml node
	function ajaxTools_GetNodeValue2(doc, path, node)
	{
		var node = this.SelectSingleNode2(doc,path,node);
		if(node)
		{
			if(node.nodeValue)
			{
				return(node.nodeValue);
			}		
		}
		return('');
	}

	// Sets the value of a xml node
	function ajaxTools_SetNodeValue2(doc, path, value, node)
	{
		this.SelectSingleNode2(doc,path,node).nodeValue = value;
	}
	
	// Retrieves a single of xml node
	function ajaxTools_SelectSingleNode2(doc, path, node)
	{
		if(this.isMozilla)
		{
			return(doc.evaluate(path, GetContextNode(doc,node), this.NsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue);
		}
		else
		{
			return(GetContextNode(doc,node).selectSingleNode(path));
		}
	}
	
	// Retrieves a collection fo xml nodes
	function ajaxTools_SelectNodes2(doc, path, node)
	{
		var ret = new Array();
		if(this.isMozilla)
		{
			var nodeList = doc.evaluate(path, GetContextNode(doc,node), this.NsResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
			for(var i=0; i < nodeList.snapshotLength; i++)
			{ 
				ret[i] = nodeList.snapshotItem(i);
			}
			return(ret);
		}
		else
		{
			var obj = GetContextNode(doc,node).selectNodes(path);
			for(var i=0;i<obj.length;i++)
			{
				ret[i] = obj(i);
			}
			return(ret);
		}
	}

	// ************************************************************
	// Backwards-compatibility methods
	// ************************************************************	

	// Gets the value of the xml node
	function ajaxTools_GetNodeValue(node)
	{
		if(node)
		{
			if(node.firstChild)
			{
				return(node.firstChild.nodeValue);
			}
		}
		return('');
	}
	
	// Sets the value of the xml node
	function ajaxTools_SetNodeValue(node, value)
	{
		if(node)
		{
			if(node.firstChild)
			{
				node.firstChild.nodeValue = value;
			}
		}
	}
	
	// Gets the first node from a xml
	function ajaxTools_GetFirstNode(node, path)
	{
		var nodeList = node.getElementsByTagName(path);
		
		if(nodeList.length > 0)
		{
			return(nodeList[0]);
		}
		
		return(null);
	}

	// Gets a list of nodes with the required tag name (only searches direcly below the current node)
	function ajaxTools_SelectNodes(node, tagname)
	{
		var ret = new Array();
		if(node!=null)
		{
			if(node.childNodes!=null)
			{
				for(var i=0;i<node.childNodes.length;i++)
				{
					if(node.childNodes[i].tagName==tagname) ret[ret.length] = node.childNodes[i];
				}
			}
		}
		return(ret);
	}

	// Gets the first node with the required tag name (only searches direcly below the current node)
	function ajaxTools_SelectSingleNode(node, tagname)
	{
		if(node!=null)
		{
			if(node.childNodes!=null)
			{
				for(var i=0;i<node.childNodes.length;i++)
				{
					if(node.childNodes[i].tagName==tagname) return(node.childNodes[i]);
				}
			}
		}
		return(null);
	}
}