/* ---------------------------------------------------------------------
Pure White Design, Web Development
  Common JavaScript Functions; Version 0.1
--------------------------------------------------------------------- */




/* ------------------------------------------------------------------ */
var functionObject = new Object();
/* ------------------------------------------------------------------ */


/* ---------------------------------------------------------------------
Function Set: AJAX
ajaxGetData(),ajaxQueue(),ajaxStateChange()
------------------------------------------------------------------------
Function: ajaxGetData()
  Will get information from a file and place the information into a HTML
  element specified.  The element types supported is dependant on the
  elements that the setContents and getContents actions support in
  js:elementManip();.

Input Variables:
 *filePath      str  Full (absolute or relative) path to the file
  elementId     str  The element ID to where the data will be inserted
  variables     str  Query string of variables to append to request
                     The filePath and elementId are automatically 
                     included in the request.
  loadingText   str  HTML to display while request is processing
  callFunction  str  Function to call when data is received
--------------------------------------------------------------------- */
functionObject.ajaxQueue = new Array();
function ajaxGetData(filePath,elementId,variables,loadingText,callFunction) {
	var mLocation = "js:ajaxGetData();";

	/* input validation and sanitization */
	var error = new Array();
	if (!triCheck(filePath)) { error.push("The value for input variable 'filePath' is null or undefined."); }
	if ((triCheck(elementId)) && (!isElement(elementId))) { error.push("The element ID '"+elementId+"' specified in input variable 'elementId' does not exist."); }
	if (triCheck(variables)) {
		if (variables.substr(0,1) == "&") { variables = variables.substr(1); }
		splitVariables = variables.split("&");
		var components;
		for (var loop1 = 0; loop1 < splitVariables.length; loop1++) {
			components = splitVariables[loop1].split("=");
			if (inArray(components[0],["filePath","elementId"])) { error.push("Variable '"+components[0]+"' can not be defined in the input variable 'variables'."); }
		}
	}
	if (error.length > 0) { 
		alert("ERROR["+mLocation+"]: "+error.join("\nERROR["+mLocation+"]: "));
		return false; 
	}

	if ((triCheck(loadingText)) && (isElement(elementId))) { elementManip(elementId,"setContents",[loadingText],["overwrite"]); }
	functionObject.ajaxQueue.push([filePath,elementId,variables,callFunction]);
	ajaxQueue();
	return true;
}
/* ---------------------------------------------------------------------
Function: ajaxQueue()
  Processes the queue populated by js:ajaxGetData();.
--------------------------------------------------------------------- */
function ajaxQueue() {
	var mLocation = "js:ajaxQueue();";
	if (functionObject.ajaxQueue.length == 0) { return true; }

	/* initializing variables */
	var ajaxRequest = functionObject.ajaxQueue.shift();
	if (window.XMLHttpRequest) { var ajaxObject = new XMLHttpRequest(); }
	else if (window.ActiveXObject("Msxml2.XMLHTTP")) { var ajaxObject = new ActiveXObject("Msxml2.XMLHTTP"); }
	else if (window.ActiveXObject("Microsoft.XMLHTTP")) { var ajaxObject = new ActiveXObject("Microsoft.XMLHTTP"); }
	else {
		alert("ERROR["+mLocation+"]: (110005) There was an error creating the XML HTTP object.");
		return false;
	}


	/* processing queue */
	try { 
		ajaxObject.open("POST",ajaxRequest[0]); 
		ajaxObject.setRequestHeader("Content-type","application/x-www-form-urlencoded");
		ajaxObject.send("filePath="+ajaxRequest[0]+"&elementId="+ajaxRequest[1]+"&"+ajaxRequest[2]);
		ajaxObject.onreadystatechange = function() { ajaxStateChange(ajaxObject,ajaxRequest); }
	}
	catch (error) { 
		alert("ERROR["+mLocation+"]: (110006) There was an error processing the XML HTTP request.");
		return false;
	}


	return true;
}
/* ---------------------------------------------------------------------
Function: ajaxStateChange(ajaxObject)
  This function is called with the state of an XML HTTP request changes.

Input Variables:
 *ajaxObject   obj  The object created for the XML HTTP request
 *ajaxRequest  ary  Array of request information
--------------------------------------------------------------------- */
function ajaxStateChange(ajaxObject,ajaxRequest) {
	var mLocation = "js:ajaxStateChange();";


	/* input validation */
	var error = new Array();
	if (typeof(ajaxObject) != "object") { error.push("The value for input variable 'ajaxObject' is invalid."); }
	if (!isArray(ajaxRequest)) { error.push("The value for input variable 'ajaxRequest' is invalid."); }
	if (error.length > 0) { 
		alert("ERROR["+mLocation+"]: "+error.join("\nERROR["+mLocation+"]: "));
		return false; 
	}


	/* processing the state change */
	if (inArray(ajaxObject.readyState,[0,1])) { 
		alert("ERROR["+mLocation+"]: (110007) The request is in an invalid state; the request did not correctly construct.");
		return false; 
	}
	else if (ajaxObject.readyState == 4) {
		if ((ajaxObject.status == 200) && (isElement(ajaxRequest[1]))) { 
			elementManip(ajaxRequest[1],"setContents",[ajaxObject.responseText],["overwrite"]); 
			return true;
		}
		if ((typeof(ajaxRequest[3]) != "undefined") && (ajaxRequest[3].length > 0)) { 
			eval(ajaxRequest[3]+"('"+ajaxObject.responseText+"')"); 
			return true;
		}
	}


	return true;
}
/* ------------------------------------------------------------------ */


/* ---------------------------------------------------------------------
Function: elementManip(elementId,action,parameters)
  Manipulates an element in several ways.

Input Variables:
 *elementId   str  The element ID of the element to manipulate
 *action      str  Action to take on element
  parameters  ary  Array of parameters unique to the action
  options     ary  Array of options unique to the action

Input Variables Explained:
  Parameters and options are unique to the action.  Some actions do not
  require parameters, and none require options, to be defined.

  Both parameters and options are arrays and this function will not 
  work if they are not defined that way; future expansion in mind.  
  Parameters must be defined in an order, while the order of options 
  does not matter.

  action="setContents"  Sets the contents of an element
    parameters: [value],[attribute]
    options: "append"|"prepend"|"overwrite"

  action="getContents"  Gets the contents of an element
    parameters: [attribute]
      By default the attribute is "value" for INPUT, SELECT, and 
      TEXTAREA, "innerHTML for DIV and P, and "src" for IMG.  You can
      specify something else here.
    options: none

  action="show"  Sets style.display to ''
  action="hide"  Sets style.display to 'none'
--------------------------------------------------------------------- */
functionObject.elementManip = new Object();
functionObject.elementManip.supportedElements = ["input","select","textarea","div","p","img"];
function elementManip(elementId,action,parameters,options) {
	var mLocation = "js:elementManip();";


	/* input validation */
	var error = new Array();
	if (!triCheck(elementId)) { error.push("The value for input variable 'elementId' is null or undefined."); }
	else if (!isElement(elementId)) { error.push("The element ID '"+elementId+"' specified in input variable 'elementId' does not exist."); }
	else if (!inArray(document.getElementById(elementId).tagName.toLowerCase(),functionObject.elementManip.supportedElements)) { error.push("The element type '"+document.getElementById(elementId).tagName.toLowerCase()+"' is not a supported element type in this function."); }
	if (!triCheck(action)) { error.push("The value for input variable 'action' is null or undefined."); }
	else if (!inArray(action,["setContents","getContents","show","hide"])) { error.push("The value for input variable 'action' is invalid."); }
	if ((triCheck(parameters)) && (!isArray(parameters))) { error.push("The value for input variable 'parameters' is invalid."); }
	if ((triCheck(options)) && (!isArray(options))) { error.push("The value for input variable 'options' is invalid."); }
	if (error.length == 0) {
		if (action == "setContents") {
			if (!triCheck(parameters)) { var parameters = [""]; }
			else if (!isArray(parameters)) { error.push("The value for input variable 'parameters' is invalid."); }
			else if (parameters.length > 2) { error.push("The input variable 'parameters' has too many rows for the value '"+action+"' specified for input variable 'action'."); }
			if (!triCheck(options)) { var options = ["overwrite"]; }
			else if (!isArray(options)) { error.push("The value for input variable 'options' is invalid."); }
			else if (options.length > 1) { error.push("The input variable 'options' has too many rows for the value '"+action+"' specified for input variable 'action'."); }
			else if (!inArray(options[0],["append","prepend","overwrite"])) { error.push("The value '"+options[0]+"' for input input variable 'options' is invalid."); }
		}
		if (action == "getContents") {
			if ((triCheck(parameters)) && (!isArray(parameters))) { error.push("The value for input variable 'parameters' is invalid."); }
			else if ((triCheck(parameters)) && (parameters.length > 1)) { error.push("The variable 'parameters' has too many rows for the value '"+action+"' specified for input variable 'action'."); }
			if ((triCheck(options)) && (isArray(options))) { error.push("The variable 'options' has too many rows for the value '"+action+"' specified for input variable 'action'."); }
			else if (triCheck(options)) { error.push("The value for input variable 'options' is invalid."); }
		}
	}
	if (error.length > 0) { 
		alert("ERROR["+mLocation+"]: "+error.join("\nERROR["+mLocation+"]: "));
		return false; 
	}


	/* setContents and getContents */
	if (inArray(action,["setContents","getContents"])) {	
		var elementObject = document.getElementById(elementId);

		if (action == "setContents") {
			if (inArray("append",options)) { var value = elementManip(elementId,"getContents")+parameters[0]; }
			else if (inArray("prepend",options)) { var value = parameters[0]+elementManip(elementId,"getContents"); }
			else { var value = parameters[0]; }
			if (triCheck(parameters[1])) { 
				try { elementObject.setAttribute(parameters[1],parameters[0]); }
				catch (error) {
					messageLog("error",mLocation,"(110009) Unable to set the attribute '"+parameters[1]+"' to value '"+parameters[0]+"' for element ID '"+elementId+"'"); 
					return false;
				}
				return true;
			}
		}
		else if ((action == "getContents") && (triCheck(parameters)) && (isArray(parameters))) { return elementObject.getAttribute(parameters[0]); }

		var tagName = elementObject.tagName.toLowerCase();
		if (inArray(tagName,["div","p"])) { 
			if (action == "getContents") { return elementObject.innerHTML; }
			else { elementObject.innerHTML = value; } 
		}
		else if (inArray(tagName,["input","textarea","select"])) { 
			if (action == "getContents") { return elementObject.value; }
			else { elementObject.value = value; }
		}
		else if (tagName == "img") { 
			if (action == "getContents") { return elementObject.src; }
			else { elementObject.src = value; }
		}
	}


	/* show and hide */
	else if (inArray(action,["show","hide"])) {
		if (action == "show") { document.getElementById(elementId).style.display = ""; }
		else if (action == "hide") { document.getElementById(elementId).style.display = "none"; }
	}


	return true;
}	
/* ------------------------------------------------------------------ */


/* ---------------------------------------------------------------------
Function: inArray(value,array)
  Returns true if the specified value is in the specified array.

Input Variables:
 *value  str  Value to find in the array (needle)
 *array  ary  The array of values (haystack)
--------------------------------------------------------------------- */
function inArray(value,array) {


	/* input validation */
	var error = new Array();
	if (!triCheck(value)) { error.push("The value for input variable 'value' is null or undefined."); }
	if (!isArray(array)) { error.push("The value for input variable 'array' is invalid."); }
	if (error.length > 0) { 
		alert("ERROR["+mLocation+"]: "+error.join("\nERROR["+mLocation+"]: "));
		return false; 
	}


	for (var loop1 = 0; loop1 < array.length; loop1++) { if (array[loop1] == value) { return true; } }
	return false;
}
/* ------------------------------------------------------------------ */


/* ---------------------------------------------------------------------
Function: isArray(array)
  Checks if the specified array is really an array.

Input Variables:
  array  ary  The array to check
--------------------------------------------------------------------- */
function isArray(array) {
	if (array.constructor == Array) { return true; }
	else { return false; }
}
/* ------------------------------------------------------------------ */


/* ---------------------------------------------------------------------
Function: triCheck(variable)
  Tests the variable for actual content; if undefined, null or of zero
  length, the function returns false or true otherwise.

Input Variables:
 *variable  n/a  The variable to check
--------------------------------------------------------------------- */
function triCheck(variable) {
	if ((typeof(variable) == "undefined") || (variable == null) || (variable.length < 1)) { return false; }
	else { return true; }
}
/* ------------------------------------------------------------------ */


/* ---------------------------------------------------------------------
Function: isElement(elementId)
  Returns true if the element exists on the page or false if it doesn't.
--------------------------------------------------------------------- */
function isElement(elementId) { 
	if (document.getElementById(elementId)) { return true; } 
	else { return false; } 
}
/* ------------------------------------------------------------------ */



