/********************************************************************************
AJAX CORE FUNCTIONALITY CLASS
Nathan Bryant 2006
http://www.dynamicsystems.co.nz

Copyright 2006 Dynamic Systems

All rights reserved. Republication, redistribution,
replication or use of Dynamic Systems content / scripting
is strictly prohibited without the prior written consent of Dynamic Systems.
********************************************************************************/

var xml = {
	
	//max_url_length: 2083,
	showErrors: true,
	request: null,
	requestActive: null,
	asynch: true,
	queue: [],
	timeout: 30,
	requestTimer: 0,
	maxRetry: 3,
	crntRetry: 0,
	
	/****************************************
	*										*
	*	  OVERWRITES SET PARAMETERS			*
	*										*
	****************************************/
	/*setParameters: function(params)
	{
		// overwrite parameters 
		for (var param_name in params) {
			eval("this." + param_name + " = '" + params[param_name] + "'");
		}
	},*/

	/****************************************
	*										*
	*	  XML DATA REQUEST FUNCTIONS 		*
	*										*
	****************************************/
	execRequest: function(url, func, type, form)
	{		
		xml.request = null;
		xml.requestTimer = 0;

		// MOZILLA / SAFARI
		if (window.XMLHttpRequest) {
			xml.request = new XMLHttpRequest();
		}
		// IE
		else if (window.ActiveXObject) {
			xml.request = new ActiveXObject("Microsoft.XMLHTTP");
		}
		// No XML 
		else {
			alert("XML Object is not available");
			return false;
		}

		if (xml.request) {
			
			/*var d = new Date();
			$("debug").innerHTML = "URL: " + url + " - requested : " + d.toString();*/

			xml.request.onreadystatechange = function() {
				
				try {
					var status = xml.request.status;
				}
				catch (e) {

					/*for (var prop in xml.request) {
						try {
							alert(prop + " = " + eval("xml.request." + prop));
						}
						catch (e) {
							alert(prop);
						}
					}*/

					/*

					xml.endRequest();
					xml.queue.unshift({"url":url,"func":func,"type":type,"form":form});					
					*/
					// Mozilla has issues with the request sometimes, this needs to be here - re-request
					/*if (xml.request == null) {
						 
					}*/
				}

				if (xml.request && xml.request.readyState == 4 && typeof(status) == "number") {

					switch (status) {
						
						case 200 : 			
							if (typeof(func) != "undefined") {
								try {							
									func(xml.request);
								}
								catch (e) {
									eval(func);
								}
							}
							xml.endRequest();
						break;
						
						case 404 : 
							if (xml.showErrors) {
								alert("XML file not found: " + url);
							}
							xml.endRequest();
						break;
						
						case 0 : break;

						default : if (xml.showErrors) { alert("There was a problem sourcing the request\n\nThe error code returned was : " + xml.request.status); }

					}
				}
			}
			xml.request.open(type, url, xml.asynch);
			// make request
			if (type == "GET" || type == "HEAD") {
				if (type == "HEAD" && ! document.all) {
					xml.request.overrideMimeType("text/plain");
				}
				xml.request.send(null);
			}
			else {	
				// parameters have been passed
				if (typeof(form) == "object" && ! form.tagName) {
					var postvars = [];
					for (var prop in form) {
						postvars.push(prop + "=" + form[prop]);
					}
					postvars = postvars.join("&");
				}
				else {
					var postvars = xml.getFormVars(form).join("&");
				}
				//xml.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
				xml.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				xml.request.setRequestHeader("Content-length", postvars.length);
     			xml.request.setRequestHeader("Connection", "close");
				xml.request.send(postvars);
			}			
			xml.requestTimer = setTimeout(
					function() {
						//if (xml.requestActive && xml.maxRetry < xml.crntRetry++) {
							xml.endRequest();
							xml.execRequest(url, func, type, form);
						/*}
						else {
							alert("MAX XML RETRIES HIT");
						}*/
					},
					xml.timeout * 1000
			);
		}
		return true;
	},

	endRequest: function()
	{
		clearTimeout(xml.requestTimer);
		if (xml.request) {
			xml.request.onreadystatechange = function(){};
			xml.request.abort();
		}
		xml.requestActive = false;
		
		/*	show user ajax loading sign */
		if( xml.loader ){
			xml.autoLoaderShutoff();
		}
	},
	
	getFormVars: function(f)
	{
		var ft = typeof(f); 
		if (ft != "undefined") {
			if (ft != "object") {
				if ($(f)) {
					f = $(f);
				}
				else if (document.forms[f]) {
					f = document.forms[f];
				}
			}
					
			if (f.elements) {
				var els = f.elements;
				var vars = [];
				for (var w = 0, l = els.length; w < l; w ++) {
					if (! els[w].disabled) {
						if (els[w].type && (((els[w].type == "radio" || els[w].type == "checkbox") && els[w].checked) || (els[w].type != "radio" && els[w].type != "checkbox"))) {
							vars.push(els[w].name + "=" + encodeURIComponent(els[w].value));
						}
					}
				}
				return vars;
			}
			alert("There is no form available for xml post - " + f);
		}
		return [];		
	},
 
 	/****************************************
	*										*
	*	  XML CALL QUEUING FUNCTIONS 		*
	*										*
	****************************************/
	queue_add: function(url, func, type, formvars)
	{
		/*	show user ajax loading sign */
		if( xml.loader ){
			xml.showLoader()
		}
		
		var x = {
			'url': url,
			'func': func,
			'type': (type == null) ? "GET" : type.toUpperCase(),
			'form': formvars
		};
		xml.queue[xml.queue.length] = x;
		xml.queue_do();
	},

	queue_do: function()
	{
		if (xml.requestActive) {
			setTimeout("xml.queue_do()", 50);
		}
		else if (xml.queue.length != 0) {
			xml.requestActive = true;		
			//alert(xml.queue[0]['url'] + " = " + xml.queue[0]['func']);
			xml.execRequest(xml.queue[0].url, xml.queue[0].func, xml.queue[0].type, xml.queue[0].form);
			xml.queue.shift();
		}
	},

	/************************************
	*									*
	*	 DECODES ENCODED CHARACTERS		*
	*									*
	************************************/
	decode: function(str)
	{
		var find = ["&lt;", "&gt;", "&apos;", "&quot;", "&amp;"];
		var replace = ["<", ">", "'", '"', "&"];
		for (var i = 0, l = find.length; i < l; i ++) {
			var sought = new RegExp(find[i]);
			do {
				str = str.replace(sought, replace[i]);
			} while (str.search(sought) != -1);
		}
		return str;
	}
};

// extend to mimic prototype functionality
var Ajax = {	
	Request:function(url, options)
	{
		if (options == null) {
			options = {};
		}
		var m = (options.method || "GET");
		var callback = (options.onSuccess || options.onComplete || options.callback || null);	
		var form = (options.parameters || (options.form || false));
		if (! form && m != "GET") {
			alert("Please use the form option to pass a form name or the parameter option to specify parameters directly");
			return false
		}
		xml.execRequest(url, callback, m, form);
	}
};