
			// ============================================================================================
			//
			//          A j a x   S u b s :   In conjunction with the zXML routines that handle XHR requests,
			//				  these subroutines handle common asynchronous Javascript calls.
			//
			//
			//    Original author unknown; modified & enhanced at the KSU Educational Communications Center
			//
			//    David Noel Pedergnana, Media Architect
			//
			//    www.ksu.edu/ecc       *       dnp@ksu.edu
			//
			//    © MMVIII D.N.B. Pedergnana
			//    
			// ============================================================================================


function encodedPair(param, val) {				// URI Encodes a single parameter/value pair for use in an array:
													//   ("this param", 3) becomes "this%20param=3"
	var encParam = encodeURIComponent(param);		//   Called by the method getReqBody
	encParam += "=";
	encParam += encodeURIComponent(val);
	return encParam;
}

function submitOnReturn(e, formID, sendFormTarget, hideID) {		// Accepts a keypress event, formID, and sendFormTarget ID (or
																	// callback method) as input, and submits the form if [RETURN]
																	// or [ENTER] are pressed
	var keynum;														//	If sendFormTarget = 'e' : Interpret the formID as javascript
																	// on pressing [ENTER]
	var Esc;														//	hideID: optional dialog box to hide when [ESC] is pressed
	
		// Capture the keypress value and define the Esc key code


 	keynum  = (window.event) ? event.keyCode : e.keyCode;
    Esc = (window.event) ? 27 : e.DOM_VK_ESCAPE;	 				// Capture keypress event for either MSIE : Firefox
	
	if (keynum == Esc) {								// if pressed key = [ESC] : Hide the dialog
		if (hideID) {
			hideObject(hideID);	
		}
	}

	if (keynum == 13 || keynum == 3) {
		if (sendFormTarget == 'e') {					// Treat the sendFormTarget as javascript
			eval(formID);
		} else {
			sendForm(formID, sendFormTarget);
		}
	
	}
}


function getReqFormBody(formID) {				// Accepts formID reference as input and outputs a URI-encoded parameter string
												//    that can be sent via XHR post. Called by sendForm()

	var paramList = new Array();				// * Using an array instead of combining strings avoids memory leaks
	var formObj = getObjectByID(formID);

	if (formObj == '') { alert('* getReqFormBody Error: No '+formID); }	// TEMPORARY ERROR MSG


	// Get selected form element types and append them to the parameter list:

	for(var i=0; i < formObj.elements.length; i++) {

		var fieldObj = formObj.elements[i];		// Get the current field object

		switch (fieldObj.type) {

			case "button":			// omit buttons
			case "submit":
			case "reset":
				break;

			case "checkbox":		// include checkboxes and radio buttons only if selected
			case "radio":
				if (!fieldObj.checked) {
					break;
				}

			case "text":			// include text, hidden, and password fields
			case "hidden":
			case "password":
				paramList.push(encodedPair(fieldObj.name, fieldObj.value));
				break;

			default:			// handle dropLists, multiline lists, and other form objects

				switch(fieldObj.tagName.toLowerCase()) {

					case "select":
						paramList.push(encodedPair(fieldObj.name, 
							fieldObj.options[fieldObj.selectedIndex].value));
						break;

					default:
						paramList.push(encodedPair(fieldObj.name, fieldObj.value));
						break;			
				}
		}
	}
	return paramList.join("&");
}


function sendForm(formID, targetID, callbackFunc, syncReqFlag) {	// Ajax call that submits a specified form and:

																	//  	(1) displays the resulting XHR response via targetID
																	//		    --an optional <span>, <div>, or form object-- OR

																	//		(2) does the requested action and executes a callback

			//	callbackFunc: the name of a client-side function to send echoed parameters to
			//	syncReqFlag: if true, sends a synchronous request (i.e., halts javascript execution while waiting for a response)

	if (syncReqFlag) {
		var async = false;
	} else {
		var async = true;
	}

	var formObj = getObjectByID(formID);			
	var params = getReqFormBody(formID);

	var xhrObj = zXmlHttp.createRequest();
	xhrObj.open("post", formObj.action, async);
	
	xhrObj.setRequestHeader("Content-Type", "application/x-www-form-urelencoded");
	xhrObj.onreadystatechange = function () {

		if (xhrObj.readyState == 4) {							 // xhr task complete
 
			if (xhrObj.status == 200 || xhrObj.status == 304) {						// Status OK: 200 = response not cached
										 											//            304 = reply cached from browser
				if (targetID) {	
										 											// write result to target span, div or obj
					processResponse(targetID, callbackFunc, xhrObj.responseText);
				}
			} else {
				alert('sendForm Error: ' + xhrObj.statusText );
			}
		}
	};
	xhrObj.send(params);
}

function encodeData(oData) {	// Loops through an object array and creates a URL-encoded string

	var paramList = new Array();

	for (var key in oData) {
		paramList.push( encodedPair(key, oData[key]) );
	}

	return paramList.join("&");
}


function sendData(url, targetID, callbackFunc, oData, syncReqFlag) {		// Accepts a url, targetID, and data object as input 
																//	Sends the data via post to the specified script (url) and
																// displays the resulting XHR response via targetID

			//	syncReqFlag: if true, sends a synchronous request (i.e., halts javascript execution while waiting for a response)

	if (syncReqFlag) {
		var async = false;
	} else {
		var async = true;
	}

	var params = encodeData(oData);	

	var xhrObj = zXmlHttp.createRequest();
	xhrObj.open("post", url, async);
	
	xhrObj.setRequestHeader("Content-Type", "application/x-www-form-urelencoded");
	xhrObj.onreadystatechange = function () {

		if (xhrObj.readyState == 4) {							 // xhr task complete
 
			if (xhrObj.status == 200 || xhrObj.status == 304) {	 // Status OK: 200 = response not cached
																 //            304 = reply cached from browser
					processResponse(targetID, callbackFunc, xhrObj.responseText);
			} else {
				alert('sendData Error: ' + xhrObj.statusText );
			}
		}
	};
	xhrObj.send(params);
}

function processResponse(targetID, callbackFunc, text) {		// Accepts targetID, a function name, and xhrObj response text
																//   and puts the response in a target div, span, or other object.

									// Response text has two parts: HTML |,| Callback Parameter 1 |,| Callback Parameter 2...
									// If callbackFunc is named and parameters are returned, sends data via the specified callback

	var codeStart = text.indexOf('var js = ');
	if ( codeStart > -1 ) {												// response text includes a callback

		var lastChar          = text.length - 1;
		if (codeStart > 0 && targetID) {								// 		the callback is precdeded by HTML

			var HTML              = text.substring(0, codeStart-1);
			var responseArguments = text.substring(codeStart);
		} else {														//		the callback isn't preceded by HTML
			var responseArguments = text;
		}
		
	} else {
		var HTML = text;												// no callback in response text
	}

	if (HTML && targetID) {
		
			// Handle special cases: targetID = 'refresh' or 'refreshData'
	
		if (targetID == 'refresh') {
			location.reload(true);
		} else if (targetID == 'refreshData') {
			top.getObjectByID('dataFrame').contentWindow.location.reload(true);
		} else {
		
			setText(targetID, HTML);		// Populate the target object with HTML received from the server
		}
	}

	if (responseArguments) {				// Send responseArguments to the callbackFunc or handle the callback

		var js = responseArguments;

		var codeHeader = /var js = /;

		if (js.search(codeHeader) == 0) {		// Valid header: start parsing code

			var lastChar = js.length - 4;		// Remove garbage chars
			js = js.substring(13, lastChar);	// Strip the opening delimiter required for interpreted statements

			if(callbackFunc) {				// Perform the callback (if any)

				var callback = callbackFunc + "(" + responseArguments + ");"
				eval( callback );

			} else {												// No callbackFunc specified: interpret the responseArgument
				eval( js );
			}
		}
	}
}


		// Custom Password Encryption Routine
		
function dpEncode(inputString, targetLength) {

	var keyString = 'givhPo65ymXSzuW';
	var legalChars = 'vWhPo65yzugmXSiRC.1D80@ZepGMIqUOQB7Ear-fYlA 2tksbnw9Vxd4KN3Tj_FcHLJ';
	
	var thisChar, thisCharIndex, codedChar, keyChar, keyCharIndex
	var keyCharPos = 0;
	var charCount = 0;		// Counter that notes the output string length. Result is always 16 chars + one char that stores the actual string length (outputString is padded to 16 chars)
	var outputString = '';


		// Encode each character of the inputString

	for (var n=0; n < inputString.length; n++) {

		thisChar = inputString.charAt(n);
		thisCharIndex = legalChars.indexOf(thisChar);

		keyChar = keyString.charAt(keyCharPos);
		keyCharIndex = legalChars.indexOf(keyChar);

		codedChar = thisCharIndex + keyCharIndex + 33;

		outputString += String.fromCharCode(codedChar);		

		keyCharPos = keyCharPos + 1;

		if (keyCharPos >= keyString.length) {
			keyCharPos = 0;
		}
	}

		// Pad with random characters until string length = 16 chars

	var stringLength = inputString.length;
	var randIndex;

	for (n = stringLength; n < targetLength; n++) {
		randIndex = Math.floor(Math.random()*legalChars.length);
		outputString += legalChars.charAt(randIndex);
	}

		// Encode the length of the original string and append it to the encrypted string

	keyChar = keyString.charAt(0);
	keyCharIndex = legalChars.indexOf(keyChar);

	var codedStringLength = stringLength + 97;
	outputString = outputString + String.fromCharCode(codedStringLength);

	return outputString;
}
