//Functions
//HasAgent() - Detects if browser can use ActiveXObject("Microsoft.XMLHTTP")
//loadXMLDoc(url) - Pass it a url and it sends.  Also calls processReqChange to process the returned request.
//processReqChange() - Checks the status of the request. Called from LoadXMLDoc
//processRequest(response) - Creates a name value array of the XML returned response and calls handleResponse(ResponseArray)

// XMLHttpRequest2 borrowed from http://weblogs.asp.net/mschwarz/archive/2005/08/24/423495.aspx.

var AJAX_Object = new AJAX_Engine()
var AJAX_RequestValues = new Array() // named array of values - arr["name1"] = value1, arr["name2"] = value2, ...
var AJAX_RequestContent = null // HTML content returned from an AJAX request

function AJAX_Engine()  { // object for HTTPRequest object and other properties

	var engine = new Object()

	// properties
	engine._div_name = ""
	engine._func = null
	engine._httpRequest = null
	engine._requestHeaders = new Array()
	engine.RequestContent = null
	engine.RequestValues = new Array()

	// methods
	engine.CreateObject = function() {
		if(engine._httpRequest == null) {
			if(window.XMLHttpRequest) {
				engine._httpRequest = new XMLHttpRequest() // branch for native XMLHttpRequest object
			} else if(window.ActiveXObject) {
				try {
					engine._httpRequest = new ActiveXObject("Microsoft.XMLHTTP") // branch for IE/Windows ActiveX version
				}
				catch(e) {
					try {
						engine._httpRequest = new XMLHttpRequest2() // branch for IE/Windows with ActiveX disabled
					}
					catch(e) {
						engine._httpRequest = null
					}
				}
			}
		}
		return (engine._httpRequest != null)
	}
	engine.SendExecute = function(url, func) {
		if(engine.CreateObject()) {
			engine._func = func
			engine._httpRequest.onreadystatechange = engine.OnCompleteExec
			engine._httpRequest.open("POST", url, true)
			engine._httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
			var qs = new AJAX_QueryString()
			for(name in engine._requestHeaders) {
				qs.setInput(name, engine._requestHeaders[name])
			}
			engine._httpRequest.send(qs.getQueryString())
		}
	}
	engine.OnCompleteExec = function() {
		if(engine._httpRequest) {
			if(engine._httpRequest.readyState == 4) { // only if req shows "complete"
				if(engine._httpRequest.status == 200) { // Numeric code returned by server, such as 404 for "Not Found" or 200 for "OK"
					engine.RequestValues = engine.ParseQueryString(engine._httpRequest.responseText)
					engine.RequestContent = engine._httpRequest.responseText
					engine._func() // execute function
					engine._httpRequest = null
				}
			}
		}
	}
	engine.SendSetContent = function(url, div_name) {
		if(engine.CreateObject()) {
			engine._div_name = div_name
			engine._httpRequest.onreadystatechange = engine.OnCompleteSetContent
			engine._httpRequest.open("POST", url, true)
			engine._httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
			var qs = new AJAX_QueryString()
			for(name in engine._requestHeaders) {
				qs.setInput(name, engine._requestHeaders[name])
			}
			engine._httpRequest.send(qs.getQueryString())
		}
	}
	engine.OnCompleteSetContent = function() {
		if(engine._httpRequest) {
			if(engine._httpRequest.readyState == 4) { // only if req shows "complete"
				if(engine._httpRequest.status == 200) { // Numeric code returned by server, such as 404 for "Not Found" or 200 for "OK"
					engine.RequestContent = engine._httpRequest.responseText
					engine.SetContent(engine._div_name, engine.RequestContent)
					engine._httpRequest = null
				}
			}
		}
	}
	engine.SetContent = function(name, content) {
		setElementHTML(name, content)
	}
	engine.SetRequestHeader = function(name, value) {
		if(!engine._requestHeaders[name]) { // doesn't already exist
			if(value && value.length) { // value is not null or empty string
				engine._requestHeaders[name] = URLEncode(value)
			}
		}
	}
	engine.ParseQueryString = function(QueryString) {
		var values = new Array()
		QueryString = QueryString.replace(/&amp;/g, "&")
		if(QueryString && QueryString.length) {
			var pairs = QueryString.split("&")
			for(var i = 0; i < pairs.length; i++) {
				var atoms = pairs[i].split("=")
				if(!atoms[1]) {
					atoms[1] = ""
				}
				values[atoms[0]] = URLDecode(atoms[1])
			}
		}
		return values
	}
	return engine
}

function XMLHttpRequest2() {

	// properties
	this._headers = new Array()
	this._inputs = new Array()
	this.method = "POST"
	this.url = null
	this.async = true
	this.readyState = 0
	this.iframe = null
	this.responseText = null
	this.responseXML = null
	this.id = "_xmlhttp_" + new Date().getTime()
	this.container = document.body

	// methods
	this.open = function(method, url, async) {
		this.method = method
		this.url = url
		this.async = async
		this.readyState = 0
		this.iframe = document.createElement("IFRAME")
		this.iframe.height = 1
		this.iframe.width = 1
		this.iframe.style.visibility = "hidden"
		this.iframe.id = this.id + "_iframe"

		if(document.getElementById(this.id) == null) {
			this.container.appendChild(this.iframe)
		}
	}
	this.setRequestHeader = function(name, value) {
		this._headers[name] = URLEncode(value)
	}
	this.send = function(data) {
		this.iframe._parent = this // iframe._parent allows us to reference the XMLHttpRequest2 object from the iframe object
		this._fix = -1
		this.responseText = null
		this.iframe.onreadystatechange = this._onreadystatechange

		if(this.method == "POST") {
			var html = ""
			var values = ParseQueryString(data)
			html += "<html><body><form method=\"" + this.method + "\" action=\"" + this.url + "\">"
			for(name in this._headers) {
				html += "<textarea name=\"" + name + "\">" + this._headers[name] + "</textarea>"
			}
			for(name in values) {
				html += "<textarea name=\"" + name + "\">" + values[name] + "</textarea>"
			}
			html += "</form>"
			html += "<script type=\"text/javascript\">document.forms[0].submit()</script>"
			html += "</body></html>"
			html = html.replace(/\'/g, "\\'")
			this.iframe.src = "javascript:document.write('" + html + "')"
		}
		else { // this.method == "GET"
			this.iframe.src = this.url
		}
	}
	this.onreadystatechange = function() {}
	this._onreadystatechange = function() {
		var iframe = this // this function is the event handler of the iframe.onreadystatechange, so "this" is actually the XMLHttpRequest2.iframe

		iframe._parent._fix++

		if(iframe._parent._fix < 1) {
			return
		}
		if(iframe._parent._fix == 1) {
			iframe._parent.readyState = 1
		} else if(iframe._parent._fix > 1) {
			switch(iframe.readyState.toString()) {
				case "loading":
					iframe._parent.readyState = 2
					break
				case "interactive":
					iframe._parent.readyState = 3
					break
				case "complete":
					iframe._parent.responseText = window.frames[iframe.id].document.childNodes[0].childNodes[1].innerHTML
					iframe._parent.responseXML= window.frames[iframe.id].document
					iframe._parent.readyState = 4
					iframe._parent.status = 200
					iframe.onreadystatechange = function() {} // stop firing the XMLHttpRequest2.onreadystatechange event.
					iframe.src = "" // clear IFRAME tag. This fixes a problem where the browser status progress bar would run as if something was stuck loading.
					iframe.parentNode.removeChild(iframe) // remove IFRAME from document
					break
			}
			iframe._parent.onreadystatechange()
		}
	}
}

function AJAX_QueryString() { // creates an object for use with creating a url containing a query string
	// properties
	this.url = ""
	this.inputs = new Array()

	// methods
	this.getInput = function(name) {
		return this.inputs[name]
	}
	this.getQueryString = function() {
		var queryString = ""
		// add random entry to avoid browser caching
		this.setInput("ajax_rnd", URLEncode(Date()))
		for(name in this.inputs) {
			if(queryString.length) {
				queryString += "&"
			}
			queryString += name + "=" + this.inputs[name]
		}
		return queryString
	}
	this.getURL = function() {
		var url = this.url
		var queryString = this.getQueryString()
		if(queryString.length) {
			url += "?" + queryString
		}
		return url
	}
	this.setInput = function(name, value) {
		this.inputs[name] = value
	}
}

function AJAXEnabled() {
	if(window.XMLHttpRequest) {
		return true
	}
	if(window.ActiveXObject) {
		try {
			Agent = new ActiveXObject("Microsoft.XMLHTTP")
			return true
		}
		catch(e) {
			return false
		}
	}
}

function AJAX_SendExecute(url, func) {
	if(AJAX_Object.CreateObject()) {
		AJAX_Object.func = func
		AJAX_Object._httpRequest.onreadystatechange = AJAX_OnCompleteExec
		AJAX_Object._httpRequest.open("GET", url, true)
		AJAX_Object._httpRequest.send(null)
	}
}

function AJAX_OnCompleteExec() {
	if(AJAX_Object._httpRequest.readyState == 4) { // only if req shows "complete"
		if(AJAX_Object._httpRequest.status == 200) { // Numeric code returned by server, such as 404 for "Not Found" or 200 for "OK"
			AJAX_RequestValues = ParseQueryString(AJAX_Object._httpRequest.responseText)
			AJAX_RequestContent = AJAX_Object._httpRequest.responseText
			AJAX_Object.func() // execute function
			AJAX_Object._httpRequest = null
		}
	}
}

function AJAX_SendSetContent(url, div_name) {
	if(AJAX_Object.CreateObject()) {
		AJAX_Object._div_name = div_name
		AJAX_Object._httpRequest.onreadystatechange = AJAX_OnCompleteSetContent
		AJAX_Object._httpRequest.open("GET", url, true)
		AJAX_Object._httpRequest.send(null)
	}
}

function AJAX_OnCompleteSetContent() {
	if(AJAX_Object._httpRequest.readyState == 4) { // only if req shows "complete"
		if(AJAX_Object._httpRequest.status == 200) { // Numeric code returned by server, such as 404 for "Not Found" or 200 for "OK"
			var div_name = AJAX_Object._div_name
			AJAX_RequestContent = AJAX_Object._httpRequest.responseText
			AJAX_SetContent(div_name, AJAX_RequestContent)
			AJAX_Object._httpRequest = null
		}
	}
}

function AJAX_SetContent(name, content) {
	setElementHTML(name, content)
}

function ParseQueryString(QueryString) {
	var values = new Array()
	QueryString = QueryString.replace(/&amp;/g, "&")
	if(QueryString && QueryString.length) {
		var pairs = QueryString.split("&")
		for(var i = 0; i < pairs.length; i++) {
			var atoms = pairs[i].split("=")
			if(!atoms[1]) {
				atoms[1] = ""
			}
			values[atoms[0]] = URLDecode(atoms[1])
		}
	}
	return values
}

function URLEncode(plaintext) {
	// The Javascript escape and unescape functions do not correspond
	// with what browsers actually do...
	var SAFECHARS = "0123456789" + // Numeric
					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // Alphabetic
					"abcdefghijklmnopqrstuvwxyz" +
					"-_.!~*'()" // RFC2396 Mark characters
	var HEX = "0123456789ABCDEF"

	var encoded = ""
	for (var i = 0; i < plaintext.length; i++ ) {
		var ch = plaintext.charAt(i)
	    if(ch == " ") {
		    encoded += "+" // x-www-urlencoded, rather than %20
		} else if(SAFECHARS.indexOf(ch) != -1) {
		    encoded += ch
		} else {
		    var charCode = ch.charCodeAt(0)
			if(charCode > 255) {
			    // Unicode Character cannot be encoded using standard URL encoding.
			    // (URL encoding only supports 8-bit characters.)
				// A space (+) will be substituted.
				encoded += "+"
			} else {
				encoded += "%"
				encoded += HEX.charAt((charCode >> 4) & 0xF)
				encoded += HEX.charAt(charCode & 0xF)
			}
		}
	} // for
	return encoded
}

function URLDecode(encoded) {
   // Replace + with ' '
   // Replace %xx with equivalent character
   // Put [ERROR] in output if %xx is invalid.
   var HEXCHARS = "0123456789ABCDEFabcdef"
   var plaintext = ""
   var i = 0
   while (i < encoded.length) {
       var ch = encoded.charAt(i)
	   if(ch == "+") {
	       plaintext += " "
		   i++
	   } else if(ch == "%") {
			if(i < (encoded.length - 2)
					&& HEXCHARS.indexOf(encoded.charAt(i+1)) != -1
					&& HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
				plaintext += unescape( encoded.substr(i,3) )
				i += 3
			} else {
				// Bad escape combination
				plaintext += ""
				i++
			}
		} else {
		   plaintext += ch
		   i++
		}
	} // while
   return plaintext
}

function setElementHTML(name, content)
{
	if(document.getElementById) {
		var div = document.getElementById(name)
		div.innerHTML = content
	} else if(document.all) {
		var div = document.all(name)
		div.innerHTML = content
	} else if(document.layers) {
		var div = document.layers[name]
		div.document.open()
		div.document.write(content)
		div.close()
	}
}


