//
// XMLHttp Library
//
// Serkan Girgin
// (c) 2006
//

function XMLHttp()
{
	var m_xmlhttp, m_url, m_async = true, m_action, m_self = this;
	
	if (window.XMLHttpRequest) m_xmlhttp = new XMLHttpRequest();
	else if (window.ActiveXObject) m_xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	else m_xmlhttp = null;
	
	function handleStateChange()
	{
		if (m_xmlhttp.readyState == 4)
		{
			if (m_xmlhttp.status == 200)
			{
				if (m_action == "POST") m_self.onSend(m_self); else m_self.onReceive(m_self);
			} 
			else m_self.onError(m_self);
		}
	}
	
	this.getXMLHTTP = function() { return(m_xmlhttp); }
	this.getResponseXML = function() { return(m_xmlhttp.responseXML); }
	this.getResponseText = function() { return(m_xmlhttp.responseText); }
	
	this.setURL = function(url) { m_url = url; }
	this.setAsync = function(async) { m_async = async; }

	this.setOnError = function(handler) { this.onError = handler; }
	this.setOnSend = function(handler) { this.onSend = handler; }
	this.setOnReceive = function(handler) { this.onReceive = handler; } 
	
	this.onError = function(xmlhttp) {}
	this.onSend = function(xmlhttp) {}
	this.onReceive = function(xmlhttp) {}
	
	this.abort = function() 
	{ 
		if (m_xmlhttp) m_xmlhttp.abort(); 
	}
	
	this.send = function(content,url)
	{
		if (!url) url = m_url;
		if (!url || !m_xmlhttp) return(false);
		m_action = "POST";
		m_xmlhttp.onreadystatechange = handleStateChange;
		m_xmlhttp.open(m_action,url,m_async);
		m_xmlhttp.send(content);
		return(true);
	}
	
	this.receive = function(url)
	{
		if (!url) url = m_url;
		if (!url || !m_xmlhttp) return(false);
		m_action = "GET";
		m_xmlhttp.onreadystatechange = handleStateChange;
		m_xmlhttp.open(m_action,url,m_async);
		//m_xmlhttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");		
		m_xmlhttp.send(null);
		return(true);
	}
	
	function hasChildElement(element)
	{
		var childs = element.childNodes;
		if (childs) for (var i = 0; i < childs.length; i++) if (childs.item(i).nodeType == 1) return(true);
		return(false);
	}
	
	this.parse = function(xmldoc)
	{
		if (!xmldoc) xmldoc = m_xmlhttp.responseXML;
		if (!xmldoc) return(null);
		if (!xmldoc.documentElement) return(null);

		var result = {}, element, object, existing, i, j;
		var stack = new Array({node:xmldoc.documentElement,obj:result});
		
		while (element = stack.pop()) {
			for (i = 0; i < element.node.childNodes.length; i++) {
				var child = element.node.childNodes.item(i);
				/* Check if node is an element */
				if (child.nodeType == 1) {  
					if (hasChildElement(child)) stack.push({node:child, obj:object = {}});
					else for (j = 0, object = new String(""); j < child.childNodes.length; j++) object += child.childNodes.item(j).nodeValue;
					/* Add attributes as properties */
					for (j = 0; j < child.attributes.length; j++) object[child.attributes[j].name] = child.attributes[j].value;
					/* Check for existing property, if exists convert property into array */
					existing = element.obj[child.nodeName];
					if (!existing) element.obj[child.nodeName] = object; 
					else if (existing instanceof Array) element.obj[child.nodeName].push(object);
					else {element.obj[child.nodeName] = new Array(); element.obj[child.nodeName].push(existing,object); }
				}
				else {
					/* Skip if node type is different from element (e.g. comment, text, etc.)*/
				}
			}
		}
		return(result);
	}
}
