// HAJAX
// a simple and dirty little Ajax Processor
// handles multiple, simultanious Ajax requests
//
// NO WARRANTY
// This code is provided "as is" without warranty of any kind, either
// expressed or implied, including, but not limited to, the implied warranties
// of merchantability and fitness for a particular purpose. You expressly
// acknowledge and agree that use of this code is at your own risk.

// global settings
// allow multiple requests
// hajax_allowMultiple
// This setting will turn on/off the ability to allow mutilpe requests to be processed globally
// this means, if you turn it on then all ajax calls can be run simultaneously
// 		if you turn it off then if a request is currently being processed then all subsequent requests will be blocked
//		until the curren request has been completed
var hajax_allowMultiple = true;
// hajax may also be set on a call by call basis to allow/disallow mutiple simultaneous requests
//		see parameter blockMultiple
// for a discussion of allowing/disallowing multiple simultaneous requests on a funtion by function basis
// in your own functions see the discussion at the end of this document

// if you would like the default alert shown that a request has been blocked
// set the following variable to true
var hajax_showMultipleBlockedMessage = true;

// do not edit these, flag that hajax used to see if a process is currently running or temporarily blocked
var hajax_running = false;
var hajax_temp_blockMultiple = false;


function hajax(url, call_function, parameters, pass, method, blockMultiple) {
	
	// **********************************************************************************************************
	// url = url of the script file on the server
	// can be absolute or reletive from page or doc root
	// can include http://domain
	// absolute urls are best if this will be called from several different levels of a site 
	//
	// call_function is a variable that contains the javascript function that will process whatever is returned from url
	// more info on creating call_function below
	//
	// parameters (optional) are any variable/value pairs that need to be sent to the server
	// example 'x=2&amp;y=3'
	//
	// method = GET or POST (optional default = POST)
	// POST must be used for long argument lists (GET URL's are limited to 256 characters
	// POST may fail, depending on the server, if no parameters are sent
	//
	// pass (optional)
	// anything in pass will be passed to call_function without alteration
	// values in pass would be anything that the called function might need as 
	// parameters other than the server response
	// since it is unaltered, anything that can be passed in a javascript varaible can be passed to the called function
	// including other functions or arrays
	//
	// blockMultiple (optional)
	// This parameter, if set to true will temporarily turn off multiple simultaneous requests
	// This will block the current call from running if there is already a process in progress as well as
	// Prevent any further calls until the current call is completed
	// 			If you call hajax with blockMultiple set to true then if there is no process running the call will be allowed
	//			and subsequect calls will be blocked
	//			If there is already a process running then the current call will blocked as well
	//			for more flexibility in allowing/disallowing multiple simultaneous requests
	//			see the discussion at the end of this document
	//
	// of the above parameters only url and call_function are required. The other three are optional
	// (exception: added a default call_function/response handler - see below 
	//		so now the only required parameter is the URL as long as non-empty element with the id "hajax_default"
	//		is available in the document
	// **********************************************************************************************************
	
	// **********************************************************************************************************
	// returns (sends to call_function) paremeters in the following order
	// 	server_response, pass, httpConnection, httpStatus, statusText, readError
	// 		server_response = the data returned by the called url
	// 		httpConnection = true or false, indicates if an http connection was succesfully created
	// 		httpStatus = the last http status returned by the server. Could indicate errors
	// 		statusText = text of the above http status number
	// 		readError = any errors in reading the response
	// it is completely up to the user and call_function to decide what is done with any of the above values
	// error capturing and handling is completely up to the user to deal with
	// **********************************************************************************************************
	
	// **********************************************************************************************************
	// creating a function to be called when a response is recieved from the server
	// at its simplest, create function as follows
	//
	// var alert_this = function (what) { alert(what); }
	// the parameter "what" will contain whatever was returned by the server
	//
	// more complicated
	// var myfunction = function(server_response, pass, httpConnection, httpStatus, statusText, readError) {
	// 		all instructions for function here
	// }
	//
	// the above function "myfunction" will recieve all paremeters returned by hajax
	// see the discussion about returned values above	
	// **********************************************************************************************************
	
	// **********************************************************************************************************
	// calling hajax
	// simplest form
	// hajax('http://mysite.com/ajax.php', myfunction);
	// the url that is being called and the function that will process the response (see discusion of creating functions above)
	// no parameters are sent to the server, method will default to "GET", and nothing will be passed from the call to the called function
	//
	// more complicated
	// hajax('http://mysite.com/ajax.asp', myfunction, 'x=2&y=5', 'POST', extra_values);
	// url = 'http://mysite.com/ajax.asp'
	// function to process the response = myfunction (see discussion of creating functions above)
	// query string = 'x=2&y=5', values to send to url
	// 'POST' = method to use (can be POST or GET)
	// extra_values = anythig that will be passed, unaltered, to the called function
	// any value not needed may be set to null, for instance if you wish to send no query string and use the 
	// default method of GET but you need to pass values to the called function then call hajax like this
	// hajax('http://mysite.com/ajax.asp', myfunction, '', '', extra_values);
	// **********************************************************************************************************
	
	// **********************************************************************************************************
	// default response handler
	// the default response handler will check for errors and if none exist will simply
	// dump the entire server response into the innerHTML of the element whose id is passed to Hajax
	// no extra formating of the server response is performed
	//
	// example:
	// hajax('http://mysite.com/ajax.asp', hajax_default, 'x=2&y=5', 'POST', 'test_div');
	// call myfunction in the script http://mysite.com/ajax.asp using the POST method and parameters of 'x=2&y=5'
	// dump server response into the element that has the id "test_div"
	//
	// hajax default does not even need to be explicitly called
	// example:
	// hajax('http://mysite.com/ajax.asp', '', 'x=2&y=5', 'POST', 'test_div');
	// is the same as the above example
	// if you do not specify a destination element id the default elment with an id of "hajax_default" will be used
	// example
	// hajax('http://mysite.com/ajax.asp', '', 'x=2&y=5', 'POST');
	// 
	// putting this all together, if you want to call the default handler and us an elment with the id of "hajax_default"
	// and use all other default settings you simply nee to use:
	// hajax('http://mysite.com/ajax.asp');
	//
	// **********************************************************************************************************
	
	// set defaults if not passed to function will recieve all parameters passed by hajax
	// see discussion of returned values above
	// it is up to the user to decide what to do with these values.
	if (blockMultiple) {
		hajax_temp_blockMultiple = true;
	}
	
	// see if multiple requests are allowed and if hajax is running
	if ((hajax_allowMultiple && !hajax_temp_blockMultiple) || !hajax_running) {
		hajax_running = true;
		if (!method || method == '') {
			method = 'POST';
		}
		if(parameters == '') method = 'GET'; //if no parameters are passed, then use get method to avoid chances of failing the ajax request
		method = method.toUpperCase();
		if (!parameters) {
				var dt = new Date();
			parameters = 'dummy='+ dt.getTime();
		}
		if (!pass) {
			pass = false;
		}
		if (!call_function || call_function == '') {
			// call_function = 'hajax_default';
			call_function = false;
		}
		//if (call_function == 'hajax_default') {
		if (!call_function) {
			if (!pass) {
				pass = 'hajax_default';
			}
		}
		
		var httpConnection = false;
		var readError = false;
		var httpStatus = false;
		var statusText = false;
		var server_response = false;
		var xmlHttp = hajax_createXmlHttpRequestObject();
		
		
		hajax_process();
	} else {
		// multiple simultaneous requests blocked
		if (hajax_showMultipleBlockedMessage) {
			alert('There is already an Ajax Process Running.\nPlease Wait.');
		}
	}
	
	// **********************************************************************************************************
	// Functions to create connection, send request and recieve response
	// **********************************************************************************************************
	
	function hajax_createXmlHttpRequestObject() {
		// create new XMLHttpRequest Object
		xmlHttp == false;
		// will store the reference to the XMLHttpRequest object
		// this should work for all browsers except IE6 and older
		try {
			// try to create XMLHttpRequest object
			xmlHttp = new XMLHttpRequest();
		}
		catch(e) {
			// failed to create XMLHttpRequest object
			// assume IE6 or older
			var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0",
																			"MSXML2.XMLHTTP.5.0",
																			"MSXML2.XMLHTTP.4.0",
																			"MSXML2.XMLHTTP.3.0",
																			"MSXML2.XMLHTTP",
																			"Microsoft.XMLHTTP");
			// try every prog id until one works
			for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++) {
				try { 
					// try to create XMLHttpRequest object
					xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
				} 
				catch (e) {}
				// failed to create object
				// do nothing and try the next
			}
		}
		
		// return the object
		// returns false if we were unable to create any object
		return xmlHttp;
	}
	
	function hajax_process() {
		// make request to server
		if (xmlHttp) {
			httpConnection = true;
			if (method == 'GET') {
				if (parameters != '') {
					url = url + '?' + parameters;
				}
				post_args = null;
			} else {
				post_args = parameters;
			}
			try {
				xmlHttp.open(method, url, true);
				xmlHttp.onreadystatechange = hajax_handleRequestStateChange;
				if (method == 'POST') {
					//Send the proper header information along with the request
					xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
					xmlHttp.setRequestHeader("Content-length", post_args.length);
					xmlHttp.setRequestHeader("Connection", "close");
				}
				xmlHttp.send(post_args);
			}
			catch (e) {
				// unable error openenng connection
				statusText = 'Ajax Error sending request';
				if(call_function)
				{	
					
					call_function(server_response, pass, httpConnection, httpStatus, statusText, readError);
				}
			
				hajax_temp_blockMultiple = false;
				hajax_running = false;
			}
		} else {
			// could not connect, call response handler
			if(call_function)
			{
				
				call_function(server_response, pass, httpConnection, httpStatus, statusText, readError);
			}
			hajax_temp_blockMultiple = false;
			hajax_running = false;
		}
	}
	
	function hajax_handleRequestStateChange()  {
		// wait for request to be complete and then process returned data
		readError = '';
		if (xmlHttp.readyState == 4) {
			// when readyState is 4 (done), we also read the server response
			// continue only if HTTP status is "OK"
			
			if (xmlHttp.status == 200)  {
				httpStatus = 200;
				statusText = xmlHttp.statusText;
				try {
					// read the message from the server
					server_response = xmlHttp.responseText;
				}
				catch(e) {
					// display error message
					alert("Error reading the response: " + e.toString());
					readError = e.toString();
				}
			} else {
				// display status message
				//alert("There was a problem retrieving the data:\n" + xmlHttp.statusText);
				
				//if(xmlHttp.statusText)
					//statusText = xmlHttp.statusText;
				//else
					//statusText = 'status text failed';
				//if(xmlHttp.status)
					//httpStatus = xmlHttp.status;
				//else
					//httpStatus = 'http status failed';
			}
			// call the function to deal with the server response
			// pass status and errors to server response processor
			// it is up to that function to deal with any errors
			if(call_function)
			{
				call_function(server_response, pass, httpConnection, httpStatus, statusText, readError);
			}
			hajax_temp_blockMultiple = false;
			hajax_running = false;
		}
	}
}

//alert('alert once for testing');
function WriteFile(filename,str)
{
	var newDiv = document.createElement('DIV');
	document.getElementById('debuggingdiv').appendChild(newDiv);
	newDiv.style.display = 'block';
	newDiv.style.backgroundColor = '#FFFFFF';
	
	var divid = divids++;
	divid = 'tetingdivdivdiv'+divid;
	newDiv.id = divid;
	str = '<a href="javascript: fnRemoveChildDiv('+newDiv.id+');">'+str+'</a>';
	newDiv.innerHTML = str;
}
function fnRemoveChildDiv(divid)
{
	if(typeof document.getElementById('pageProfiling') != 'undefined' && document.getElementById('pageProfiling') != null)
		document.getElementById('pageProfiling').style.display = 'none';
	if(typeof document.getElementById('pageProfiling_js') != 'undefined' && document.getElementById('pageProfiling_js') != null)
		document.getElementById('pageProfiling_js').style.display = 'none';
	document.getElementById('debuggingdiv').removeChild(divid);
}