/*ajax.js: contains functions for instantiation of httpRequest object, ajax requests, and data/collection processing functions to support those requests*/

function createRequestObject() {//function to instantiate the httpRequest object;
    var ro;
	try {
		ro = new XMLHttpRequest();
	} catch (trymicrosoft) {
		try {
			ro = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (othermicrosoft) {
			try {
				ro = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (failed) {
				ro = null;
			}
		}
	}
	return ro;
}

var requester = createRequestObject();//create the request object

function trim(toTrim)//remove whitespace 
{
	return toTrim.replace(/^\s*|\s*$/g,'');
}

function substituteEscapedChars(toSubstitute)//replace escaped commas/semi-colons (those with '&' preceding) with special string
{
	toSubstitute = toSubstitute.replace(/&,/g, '@#@#@#');
	toSubstitute = toSubstitute.replace(/&;/g, '#@#@#@');
	return toSubstitute;
}

function unSubstituteEscapedChars(toUnsubstitute)//replace special string from previous escapes with appropriate character (comma or semi-colon) 
{
	toUnsubstitute = toUnsubstitute.replace(/@#@#@#/g, ',');
	toUnsubstitute = toUnsubstitute.replace(/#@#@#@/g, ';');
	return toUnsubstitute;
}

/*this function can call any other function when passed the name 
(without parentheses) of the function and a list (delimited by '^^')
of the arguments to pass to it*/
function caller(functionName, vars) 
{
	var funcString = functionName+'(';//funcString will be the text of the javascript function call
	if ((typeof(vars)!="undefined") && (vars != ""))// see if vars were passed
	{
		if (vars.search(/(&,)|(&;)/ != -1))//if there are any escaped chars call function to substitute them out
		{
			vars = substituteEscapedChars(vars);
		}
		var funcVars = vars.split(',');// parse the string containing the variables with the normal delimiter 
		var i = 0;
		while (i < funcVars.length)// loop through funcVars array appending vars to funcString
		{
			funcString += '\''+funcVars[i]+'\'';
			if (i != funcVars.length - 1)
			{
				funcString += ', ';// add commas as necessary
			}
			i++;
		}
	}
	funcString += ')';
	if (funcString.search(/#@#@#/ != -1))//replace any substituted escaped chars with the original intended text
	{
		funcString = unSubstituteEscapedChars(funcString);//if there are any escaped chars call function to substitute them out
	}
	//alert ('final string caller is using: '+funcString);
	return eval(funcString);// use eval() to call the function 
}

/* makeRequest: primary ajax request function
Takes 1 or 3 parameters (in standard javascript comma-separated list): 
1 - the page that will respond to Ajax request, 
2 (optional) - the name(s) of the url variables to be passed to that page (semi-colon delimited if multiple). 
	alternatively another function can be called by naming that function and appending '()' to the end of it.
	if a semicolon must be entered as a value it can be escaped by preceding it with an ampersand (&).
3 (optional) - the associated values to be passed through the URL (semi-colon delimited if multiple). 
	alternatively the vars to be passed to a called function can be passed in a ',' (comma) separated list
	if a comma must be entered as a value it can be escaped by preceding it with an ampersand (&).
	****** even if there are not to be any vars passed to a called function, the delimiter(s) (;) must still be in place to mark that spot; 
	the number of url Vars/Functions must match the number of values and vice versa ***** */
function makeRequest(targetResponder, urlVarNames, urlVarValues) 
{
	var urlVarNameArray = urlVarNames.split(';');
	if (urlVarValues.search(/(&,)|(&;)/ != -1))//if there are any escaped chars call function to substitute them out
	{
		urlVarValues = substituteEscapedChars(urlVarValues);
	}
	var urlVarValueArray = urlVarValues.split(';');
	if (urlVarNameArray.length != urlVarValueArray.length)
	{
		alert('makeRequest: the proper number of urlVar names and values was not passed');
	} else 
	{
		var urlVarCount = urlVarNameArray.length;
	}
	var targetUrl = targetResponder+'?x=1';
	if (urlVarCount >= 1)
	{
		var i = 0;
		while (i < urlVarCount)//loop through appending whatever vars were passed to the url 
		{
			var name = urlVarNameArray[i];
			//alert(name);
			var value = urlVarValueArray[i];
			//alert(value);
			var equalsCheck = name.search(/=/);
			if (equalsCheck != -1)
			{
				var nameAndFunctionArray = name.split('=');//break the string at the =
				name = nameAndFunctionArray[0];
				var functionToCall = nameAndFunctionArray[1];
				var functionCheck = functionToCall.search(/\(\)/);// reg expression to look for "()" at end of function call 
				if (functionCheck != -1)
				{
					var functionToCall = functionToCall.slice(0, functionCheck);// remove the '()' from end of function call 
					var functionReturn = caller(functionToCall, value);// make call to that function by passing it through special caller function
					targetUrl = targetUrl+'&'+name+'='+functionReturn;//create the target url
				} else
				{
					alert('An equals sign was put into a call to set a var name to the returned value of a function, but the call to the function was not done properly - must have "()"');
				}
			} else //if there was no '=' in the call, it's either a straight var being passed, or a call to a function which doesn't need it's value returned and appended to the url
			{
				var funcCheck = name.search(/\(\)/);// reg expression to look for "()" at end of function call 
				if (funcCheck != -1)// if it's a function... 
				{
					var funcToCall = name.slice(0, funcCheck);// remove the '()' from end of function call 
					caller(funcToCall, value);// make call to that function by passing it through special caller function
				} else //otherwise it's a var with value so append to targetUrl 
				{
					targetUrl = targetUrl+'&'+name+'='+value;//create the target url
				} 
			}
			i++
		}
	}
	if (targetUrl.search(/#@#@#/ != -1))//replace any substituted escaped chars with the original intended text
	{
		targetUrl = unSubstituteEscapedChars(targetUrl);//if there are any escaped chars call function to substitute them out
	}
	//alert('the targetUrl from makeRequest is: '+targetUrl);
	requester.open('get', targetUrl);
 	requester.onreadystatechange = receiveResponse;
	requester.send(null);
}

/* receiveResponse: primary ajax reply function (handles ajax responses)
Takes 1 or 3 parameters in a comma-delimited list:
1 - the div to populate with the returned content
2 (optional) - javascript var(s) to populate (semicolon-delimited if multiple);
	alternatively another function can be called by naming that function and appending '()' to the end of it (semi-colon delimited if multiple).
	if a semicolon must be entered as a value it can be escaped by preceding it with an ampersand (&).
3 (optional) - value of the javascript vars to populate (semicolon-delimited if multiple).
	alternatively the var(s) to pass to the function(s) (comma delimited with escaped commas: '&,') (semicolon-delimited if multiple).
	****** even if there are not to be any vars passed to a called function, the delimiter(s) (;) must still be in place to mark that spot; 
	the number of url Vars/Functions must match the number of values and vice versa ***** */
function receiveResponse()//respond to the ajax response: placing content onto page, populating variables, and firing off javascript functions as necessary
{
    if (requester.readyState == 4)
    {
		if (requester.status == 200)
		{
			var responseArray = requester.responseText.split('~|~|~');//separate content from vars/function calls passed back to javascript
			if (responseArray[0].search(/(&,)|(&;)/ != -1))//if there are any escaped chars call function to substitute them out
			{
				responseArray[0] = substituteEscapedChars(responseArray[0]);
			}
			var responseVars = responseArray[0].split(',');//first part of the reponse is the list of vars passed back and functions to call
				var target = trim(responseVars[0]);//'target' is the div to populate
				var responseContent = responseArray[1];
			if (target.search(/<br/) == 0)//check for PHP syntax errors and alert - GET RID OF LATER
			{
				alert(requester.responseText);
			}
			var contentPlacer = 'document.getElementById("'+target+'").innerHTML = responseContent;';
			eval(contentPlacer);// put the response content onto the page
			/*if (responseVars.length == 3)
			{*/
				var responseVarsArray = responseVars[1].split(';');
				var responseValuesArray = responseVars[2].split(';');
				if (responseVarsArray.length == responseValuesArray.length)
				{
					var i = 0;
					while (i < responseVarsArray.length)
					{
						var name = responseVarsArray[i];
						var value = responseValuesArray[i];
						if (value.search(/#@#@#/ != -1))//replace any substituted escaped chars with the original intended text
						{
							value = unSubstituteEscapedChars(value);//if there are any escaped chars call function to substitute them out
						}				
						var funcCheck = name.search(/\(\)/);// reg expression to look for "()" at end of function call 
						if (funcCheck != -1)// check to see if any of the passed elements are a call to a function 
						{
							var funcToCall = name.slice(0, funcCheck);// remove the '()' from end of function call 
							caller(funcToCall, value);// make call to that function by passing it through special caller function 
						} else //otherwise it's a var so set it 
						{
							varSetter = name+' = '+value;
							eval(varSetter);//set the variable
						} 
						i++;
					}
				} else
				{
					alert('receiveResponse: the number of vars/function calls and values does not match in the data returned from the responding page');
				}
			/*} else
			{
				alert('receiveResponse: The proper number of vars/function calls was not passed back from responding page');
			}*/
		} else
		{
 			alert('There was a problem with receiveResponse().');
		}
	}

}
