
// Initialize Variables


var popup=null;					// Persistent pop-up window handler
var pop2=null;


function thisFileName() {			// Returns the filename of the specified document
	
	var docName = document.location.href;

	var lastChar = (docName.indexOf("?") == -1) ? docName.length : docName.indexOf("?");
    return docName.substring(docName.lastIndexOf("/")+1, lastChar);	
}


function openURL(page, w, h) {		// Opens a resizable pop-up window

	if(popup) {
		popup.close();
	}
		popup = window.open(page, 'popup', 'height=' +h+ ',width=' +w+ ',scrollbars=yes,resizable=yes');
}



function preloadGIF() {					// Load button highlights into the browser's memory cache

	var d = document;

	if (d.images) { 
		if(!d.allImages) { 
			d.allImages=new Array(); 
		}
		var i,j=d.allImages.length;
		var imgList=preloadGIF.arguments;

		var lastImg = imgList.length;
		for(i=0; i < lastImg; i++) {
					d.allImages[j]=new Image; 
					d.allImages[j].src='images/' + imgList[i] + 'Bt_h.gif';
					j++;

		}
	}
}


function MM_CheckFlashVersion(reqVerStr,msg){
  with(navigator){
    var isIE  = (appVersion.indexOf("MSIE") != -1 && userAgent.indexOf("Opera") == -1);
    var isWin = (appVersion.toLowerCase().indexOf("win") != -1);
    if (!isIE || !isWin){  
      var flashVer = -1;
      if (plugins && plugins.length > 0){
        var desc = plugins["Shockwave Flash"] ? plugins["Shockwave Flash"].description : "";
        desc = plugins["Shockwave Flash 2.0"] ? plugins["Shockwave Flash 2.0"].description : desc;
        if (desc == "") flashVer = -1;
        else{
          var descArr = desc.split(" ");
          var tempArrMajor = descArr[2].split(".");
          var verMajor = tempArrMajor[0];
          var tempArrMinor = (descArr[3] != "") ? descArr[3].split("r") : descArr[4].split("r");
          var verMinor = (tempArrMinor[1] > 0) ? tempArrMinor[1] : 0;
          flashVer =  parseFloat(verMajor + "." + verMinor);
        }
      }
      // WebTV has Flash Player 4 or lower -- too low for video
      else if (userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 4.0;

      var verArr = reqVerStr.split(",");
      var reqVer = parseFloat(verArr[0] + "." + verArr[2]);
  
      if (flashVer < reqVer){
        if (confirm(msg))
          window.location = "http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash";
      }
    }
  } 
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_controlShockwave(objStr,x,cmdName,frameNum) { //v4.0
  var obj=MM_findObj(objStr);
  if (obj && obj[1]) obj=obj[1];
  if (obj) eval('obj.'+cmdName+'('+((cmdName=='GotoFrame')?frameNum:'')+')');
}


function getObjectByID(name) {				// Get an object's ID tag for easy referencing

	if (document.getElementById) {				// Firefox and Safari
		return document.getElementById(name);
	} else if (document.all) {				// IE
		return document.all[name]; 
	} else if (document.layers) {
		return document.layers[name];
	} else {
		return document.getElementById(name);		// Default for unknown browsers
	}
}

function disableFields() {				// Sets the disabled property of specified elements to true

	var lastObj = (disableFields.arguments.length);
	
	for(n=0; n<lastObj; n++) {
		thisID  = disableFields.arguments[n];
		thisObj = getObjectByID(thisID);

		if (!thisObj) {
			alert('disableFields Error: ' + thisID + " doesn't exist");
		} else {
			thisObj.disabled = true;
		}
	}
}

function enableFields() {				// Sets the disabled property of specified elements to false

	var lastObj = (enableFields.arguments.length);
	
	for(n=0; n<lastObj; n++) {
		thisID  = enableFields.arguments[n];
		thisObj = getObjectByID(thisID);

		if (!thisObj) {
			alert('enableFields Error: ' + thisID + " doesn't exist");
		} else {
			thisObj.disabled = false;
		}
	}
}

function setValue() {				// Sets the value property of a specified field or control

	var lastObj = (setValue.arguments.length);
	
	for(n=0; n<lastObj; n++) {
		thisID = setValue.arguments[n];
		thisObj = getObjectByID(thisID);
		thisVal = setValue.arguments[++n];

		if (!thisObj) {
			alert('setValue Error: '+thisID+' has no properties');
		} else {
			thisObj.value = thisVal;
		}
	}
}


function getValue(id) {			// Returns the value property of the specified object

	var obj = getObjectByID(id);
	return obj.value;
}

function getLabel(listID) {		// Returns the current label of the specified listBox <select> object

	var listObject   = top.getObjectByID(listID);

	var currentLabel = listObject[ listObject.selectedIndex ].innerHTML;
	return currentLabel;
}

function getValueForOption(selectObjID, n) {	// Accepts selectObjID and option # as input and returns the value of a particular listBox option #
	
	var selectObj              = getObjectByID(selectObjID);
	var selectObjValForOptionN = getObjectByID(selectObjID).options[n].value;
	
	return selectObjValForOptionN;
}

function joinValues(fields) {		// Accepts a string of comma-separated field names as input (with spaces) and returns a string of values
									// Delimiter = |
	var fieldList = fields.split(", ");
	var lastItem = fieldList.length;
	var v = '';
	var valList = new Array();
	
	for (n=0; n<lastItem; n++) {
		v = getValue( fieldList[n] );
		valList.push(v);
	}
	
	return valList.join("|");
}


function uncheck() {				// Accepts a list of IDs and unchecks the specified checkboxes

	var lastObj = (uncheck.arguments.length);
	
	for(n=0; n<lastObj; n++) {
		thisID = uncheck.arguments[n];
		thisObj = getObjectByID(thisID);
		
		if (!thisObj) {
			alert('uncheck Error: ' + thisID + " doesn't exist");
		} else {
			thisObj.checked = '';
		}
	}
}


function getRadio(formName, radioGroupName) {		// Returns the value of the currently selected radio item from a specified group.

	var radioObj = document.forms[formName].elements[radioGroupName];
	
	if (!radioObj) {
		return "";
	} else {
		
		var radioLength = radioObj.length;
		
		if (radioLength == undefined) {
			if (radioObj.checked) {
				return radioObj.value;
			} else {
				return "";
			}
		}
			
		for (var i = 0; i < radioLength; i++) {
			if (radioObj[i].checked) {
				return radioObj[i].value;
			}
		}
		return "";
	}
}


function setRadio(formName, radioGroupName, val) {			// Sets the identified radio button set to a named value
	
	var radioObj = document.forms[formName].elements[radioGroupName];
	
	if (!radioObj) {
		alert("setRadio error: Specified Radio Group doesn't exist");
		return;
		
	} else {
		
		var radioLength = radioObj.length;
		
		if (radioLength == undefined) {
			if (radioObj.checked) {
				radioObj.value = val;
			} else {
				alert("setRadio error: Radio Group can't be queried(?)");
				return;
			}
		}
			
		for (var i = 0; i < radioLength; i++) {
			if (radioObj[i].value == val) {

				radioObj[i].checked = 'checked';
				return;
			}
		}
	}
}



function embedFlash(thisFile, w, h) {	// Shows the activeX control without an annoying 'activate' prompt
	var embedCode = "<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' " 
		+ "codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0' width='" + w + "' height='" + h + "'> " 
		+ "<param name='allowScriptAccess' value='sameDomain' /> "
		+ "<param name='movie' value='" + thisFile + "' /> " 
		+ "<param name='quality' value='high' /> " 
		+ "<param name='wmode' value='transparent' /> " 
		+ "<embed src='" + thisFile + "' width='" + w + "' height='" + h + "' quality='high' " 
		+ "pluginspage='http://www.macromedia.com/go/getflashplayer' allowScriptAccess='sameDomain' type='application/x-shockwave-flash' wmode='transparent'> " 
		+ "</embed></object>";

	document.write(embedCode);
}


function emCode(prefix, suffix, text, loc, offset, mode) {	// E-mail obfuscator

								//	offset specifies how many garbage chars precede both prefix & text

								// 	mode 'a': pairs mailto href with text
								//		Example: emCode('zdn', 'p', 'zDavid Pedergnana', '', 1, 'a');

								//	mode 'n': shows e-mail only (as text)
								//		Example: emCode('zdn', 'p', '', '', 1, 'n');

								//	mode 'm': shows e-mail address as clickable mailto text
								//		Example: emCode('zdn', 'p', '', '', 1, 'm');
	var xString = prefix + suffix;
	var h = '<a href=\"mai';
	var nom = xString.substr(offset);
	h += 'lto:';
	text = text.substr(offset);
	var end = '\">';
	text += "<" + String.fromCharCode(47);
	var z = '@';

	if (!loc) {
		var n = 101;
		loc = 'ksu.' + String.fromCharCode(n) + 'du';
	}

	if (mode == 'n') {
		document.write(nom + z + loc);
	} else if (mode == 'm') {
		document.write(h + nom + z + loc + end);
		document.write(nom + z + loc + text + 'a>');
	} else {
		document.write(h + nom + z + loc + end);
		document.write(text + 'a>');
	}
}



function goPage(whichPage) {		// Highlights the main menu button and loads the specified page; also stores persistent values (cookie + hidden field)

	getObjectByID('mainFrame').scrollTop = 0;
	
	var url = whichPage + '.html';
	setValue('getPage', url);
	sendReq('getPageForm', 'mainFrame');

	setValue('currentPage', whichPage);					// Update the current page field
	setBtnH(whichPage);


		// Update currentPage and retain ignoreGETpage in the cookie

	var cookieData = readCookie('svsCurrentPage');						// In IE, hidden field values don't persist on refresh; so we use a cookie
	if (cookieData) {
		var parsedData = cookieData.split(";");
		var ignoreGETpage = parsedData[1];				//	If a refreshed query asks for THIS page again, ignore it!
	} else {
		var ignoreGETpage = '';
	}

	var cookieData = whichPage + ";" + ignoreGETpage;

	makeCookie('svsCurrentPage', cookieData);
}


function getPage(whichPage) {			// Loads the specified page without storing a cookie or altering the menu highlight

	getObjectByID('mainFrame').scrollTop = 0;
	
	var url = whichPage + '.html';
	setValue('getPage', url);
	sendReq('getPageForm', 'mainFrame');
}



function toggleBtn(whichBtn, state) {					// State = '_h' (highlighted) or ''

	var currentPage = getValue('currentPage');

	if (currentPage !== whichBtn) {						// Ignore requests if hovering over current page button
	
		var newState = 'images/' + whichBtn + 'Bt' + state + '.gif';
		getObjectByID(whichBtn + 'Bt').src = newState;			// Change the button state
	}
}


function setBtnH(whichBtn) {

		// Reset former button:

	var currentBtn = getValue('currentPage') + 'Bt';

	if(currentBtn !== 'Bt') {

		newState = 'images/' + currentBtn + '.gif';
		getObjectByID(currentBtn).src = newState;

			// Set current button:

		var btnObj = getObjectByID(whichBtn + 'Bt');

		var newState = 'images/' + whichBtn + 'Bt_h.gif';
		btnObj.src = newState;										// Change the state: higlight on
	}


}

function parseURL(param) {	// Reads a frame's URL and splits it into its components
				// 	returns the requested parameter
	var result = null;

	var parameterList = location.href.split("?");		// GET Parameters

	if (parameterList.length > 1) {			// No parameters; set defaults for home page:

				// Split list into name.value pairs

		var parameterPairs = parameterList[1].split("&");
		var nameAndValue = new Array();
		var paramValue;
		var paramKey;

		for (p=0; p < parameterPairs.length; p++) {	// Cycle through name/value pairs & store values

			nameAndValue = parameterPairs[p].split("=");
			paramKey = nameAndValue[0];
			paramValue = nameAndValue[1];

			if (paramKey == param) {		// Is this the target key?
				result = paramValue;
				break;
			}
		}
	}
	return result;
}


function getScreenSpecs(defaultW, defaultH) {		// Accepts default width and height as input and returns 
							// either actual screen width and height or the defaults
	screenH = defaultH
	screenW = defaultW;

	if (parseInt(navigator.appVersion)>3) {
		 screenH = screen.height;
		 screenW = screen.width;
	}
	else if (navigator.appName == "Netscape" 
	    && parseInt(navigator.appVersion)==3
	    && navigator.javaEnabled()
	) 
	{
	 var jToolkit = java.awt.Toolkit.getDefaultToolkit();
	 var jScreenSize = jToolkit.getScreenSize();
	 screenH = jScreenSize.height;
	 screenW = jScreenSize.width;
	}

	return [screenW, screenH];
}



function openDoc(file, w, h, resizable, hOffset) {		// Opens a document of specified dimensions in a separate pop-up window
														//		Resizable is a boolean value ("yes" or "no") or "fixedSizeScroll"
														// 	hOffset is an optional parameter for offsetting the position from center screen 
	if(popup) {
		popup.close();
	}
	
	if (!hOffset) {
		hOffset = 0;
	}

	if (!resizable) {
		var resizable = 'yes';
		var scrollbars = 'yes';
	} else if (resizable == 'fixedSizeScroll') {
		var resizable = 'no';
		var scrollbars = 'yes';
	} else {
		var resizable = 'no';
		var scrollbars = 'no';
	}
	
	var screenWH = getScreenSpecs(1024, 768);
	screenW = screenWH[0];
	screenH = screenWH[1];

	popup = window.open(file, 'popUpWindow', 'height=' +h+ ', width=' +w+ ', scrollbars=' + scrollbars +', resizable=' + resizable + ',left=' + Math.round((screenW/2)-(w/2)-hOffset)+ ',top=' + Math.round((screenH/3)-(h/2)) );
}


function openDefault(page) {		// Opens a document in a default window that includes the location bar and is resizable

	pop2 = window.open(page, 'fullWin', 'scrollbars=yes, status=yes, menubar=yes, toolbar=yes, location=yes, resizable=yes, width=1016, height=680');
	
	return pop2;
}


function initPage(resizeMode) {		// Size the content iFrame and content divs to fit the window height
												//	resizeMode 0: reload or load
												//	resizeMode 1: resize
												
												// vOffset is the amount of vertical height to remove from the bottom (with relatively-positioned elements)

	preloadGIF('whatIsSVS', 'prerequisites', 'teachingPartners', 'instructionalSupport', 'classMaterials', 'costEnroll', 'studentSide', 'partnerSide');
	
	MM_CheckFlashVersion('8,0,0,0','Content on this page requires a newer version of Adobe Flash Player. Do you want to download it now?');
	
	var h = fillHeight('mainFrame', 295);				// Adjust the frame: note +13px to compensate for for Safari's top margin

	getObjectByID('sidebarDiv').style.height = h + 'px';		// Adjust the sidebar
	var vPos = h * -1;
	getObjectByID('sidebarDiv').marginTop = vPos + 'px;' ;
		
	if ( !resizeMode ) {						// Set the default (or requested) page if not resizing

		var cookieData = readCookie('svsCurrentPage');				// In IE, hidden field values don't persist on refresh; so we use a cookie

		if(cookieData) {
			var parsedData = cookieData.split(";");
			var recentPage = parsedData[0];			//	cookie contains two pieces of info, separated by a semicolon
			var ignoreGETpage = parsedData[1];		//	If a refreshed query asks for THIS page again, ignore it!
		}

		var currentPage = getValue('currentPage');		// Upon refresh or load, get the current page menu highlight
		
		var requestedPage = parseURL('page');			// Did someone request a page via GET?

		if (!requestedPage) {
			var requestedPg = parseURL('pg');				// 'pg' is a requested page that has no associated menu button
			var highlight = parseURL('highlight');			// highlight = specifies a button to highlight (default: none)
		}
		

		if (requestedPage && (ignoreGETpage !== requestedPage)) {	// Only honor a GET request if the request is new;
			currentPage = requestedPage;
			var ignoreGETpage = currentPage;			// On next refresh, ignore this page
			var cookieData = currentPage + ";" + ignoreGETpage;

			makeCookie('svsCurrentPage', cookieData);

		} else if (!recentPage && !currentPage){			// Neither a currentPage is stored nor a cookie:
			currentPage = 'whatIsSVS';				//	use the default

		} else if (!currentPage) {
			currentPage = recentPage;				// No currentPage stored: use the recentPage (cookie)

		}
		
		if (requestedPg) {							// Go to a page without an associated menu button
			if (highlight) {
				setBtnH(highlight);
			}
		
			if (requestedPg == 'accountSetup') {	// User wants to edit personal account info: open the accountDialog
			
				var asID  = parseURL('asID');
				var asRef = parseURL('asRef');
				
				setValue('accoundSetupID', asID);
				setValue('accountSetupRef', asRef);
				sendReq('accountSetupForm', 'js');
				showObject('accountSetupDialog');
			
			} else {								// This is a normal page request
			
				var url = requestedPg + '.html';
				setValue('getPage', url);
				sendReq('getPageForm', 'mainFrame');

				setValue('currentPage', highlight);		// Update the current page field
			}
		} else {

			goPage(currentPage);					// Go to the current or requested page
		}
	}
}


function centerH(id, offset) {

	if (!offset) {
		offset = 0;
	}

	var w = getWidth(id);

	var windowW = getClientWidth();
	var leftPos = parseInt( (windowW / 2) - (w/2) + offset );

	getObjectByID(id).style.marginLeft = leftPos + 'px';
	
}

function centerV(id, offset) {

	if (!offset) {
		offset = 0;
	}

	var h = getHeight(id);
	var windowH = getClientHeight();
	var topPos = (windowH / 2) - (h/2) + offset;

	getObjectByID(id).style.marginTop = topPos + 'px';
}

function fillHeight(id, offset) {		// Checks Window Height then adjusts the height of a specified object.
						//	Offset can be specified to reduce height, in case of headers, etc.
						//	Returns the value h to the calling function
	if (!offset) {
		offset = 0;
	}

	var windowH = getWindowHeight();
	var h = parseInt(windowH) - offset;

	if (!h) {
		h = 420;
	}

		
	getObjectByID(id).style.height = h + 'px';
	
	// if (id == 'tableBody') {		// Adjust table height to scrollbar
	//	var offsetH = h - 18;
	//	getObjectByID('dataTable').style.height = offsetH +'px';
	// }
	
	return h;
}


function setFrame(whichPage) {					// Change the page within the mainFrame
	var frameObj = getObjectByID('mainFrame');
	frameObj.src = whichPage;
}

							
function getWindowHeight() {			
							
	if (window.innerHeight) {				// Firefox and Safari
		return window.innerHeight;
	} else {								// IE
		return document.body.clientHeight; 
	}
}
	

function getWindowWidth() {
   if (window.innerWidth) {
	return window.innerWidth;
   } else {
	return document.body.clientWidth;
   }	   	   	
}

function getClientWidth() {
	return filterResults (
		window.innerWidth ? window.innerWidth : 0,
		document.documentElement ? document.documentElement.clientWidth : 0,
		document.body ? document.body.clientWidth : 0
	);
}

function getClientHeight() {
	return filterResults (
		window.innerHeight ? window.innerHeight : 0,
		document.documentElement ? document.documentElement.clientHeight : 0,
		document.body ? document.body.clientHeight : 0
	);
}
function getScrollLeft() {
	return filterResults (
		window.pageXOffset ? window.pageXOffset : 0,
		document.documentElement ? document.documentElement.scrollLeft : 0,
		document.body ? document.body.scrollLeft : 0
	);
}
function getScrollTop() {
	return filterResults (
		window.pageYOffset ? window.pageYOffset : 0,
		document.documentElement ? document.documentElement.scrollTop : 0,
		document.body ? document.body.scrollTop : 0
	);
}

function filterResults(n_win, n_docel, n_body) {
	var n_result = n_win ? n_win : 0;
	if (n_docel && (!n_result || (n_result > n_docel)))
		n_result = n_docel;
	return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}


function getWidth(id) {			// Returns the width of the specified object
	var obj = getObjectByID(id);

	if (obj.style.width) {
		return obj.style.width;
	} else if (obj.style.pixelWidth) {
		return obj.style.pixelWidth;
	} else {
		return obj.offsetWidth;
	}
}


function getHeight(id) {		// Returns the height of the specified object
	var obj = getObjectByID(id);

	if (obj.style.height) {
		return obj.style.height;
	} else if (obj.style.pixelHeight) {
		return obj.style.pixelHeight;
	} else {
		return obj.offsetHeight;
	}
}

function setStyleRule(selector, rule) {		// Redefine a CSS style class definition
	
    var stylesheet = document.styleSheets[(document.styleSheets.length - 1)];
	
    if(stylesheet.addRule) {
        stylesheet.addRule(selector, rule)
		
    } else if(stylesheet.insertRule) {
        stylesheet.insertRule(selector + ' { ' + rule + ' }', stylesheet.cssRules.length);
    }
};

function showObject() {				// Show a dynamic form field or menu
										// Iterates through argument list if an array is input
										
	var lastObj = showObject.arguments.length;
	for(n=0; n<lastObj; n++) {
		thisObj = getObjectByID(showObject.arguments[n]);
		thisObj.style.display = "";
	}
}



function hideObject() {					// Show a dynamic form field or menu
											// Iterates through argument list if an array is input
	var lastObj = hideObject.arguments.length;
	for(n=0; n<lastObj; n++) {
		
		var objectName = hideObject.arguments[n];
		
		if (objectName == 'editDialog') {
			top.startKeyDetection();			// Resume key detection for quick searching using showLettersDiv when editDialog closes
		}
		
		var thisObj = getObjectByID(objectName);
		thisObj.style.display = "none";
	}
}


function focusOn(targetID) {		// Gives focus to the named field or form object

	var targetObj = getObjectByID(targetID);
	targetObj.focus();
}


function showDiv(whichDiv) {			// Changes the background color of the link to match the specified div; then
										// shows the div
	var divID = whichDiv + 'Div';
	var tabID = whichDiv + 'Link';
	var hrefID = whichDiv + 'href';

	getObjectByID(divID).className = 'infoBlockOpen';		// Show the div
	getObjectByID(tabID).className = 'tabOpen';				// Change the link background color
	getObjectByID(hrefID).className = 'tabLinkOpen';		// Change the link background color
}


function hideDiv(whichDiv) {			// Changes the background color of the link to white; then
										// shows the div
	var divID = whichDiv + 'Div';
	var tabID = whichDiv + 'Link';
	var hrefID = whichDiv + 'href';

	getObjectByID(divID).className = 'hidden';				// Hide the div
	getObjectByID(tabID).className = 'tabClosed';			// Change the link background color
	getObjectByID(hrefID).className = 'tabLinkClosed';		// Change the link background color
}


function toggleInfoBlock(whichDiv) {	// Either hides or shows a specified div, depending on its current state

	var divID = whichDiv + 'Div';

	if (getObjectByID(divID).className == 'hidden') {		// Div is hidden: show it

		showDiv(whichDiv);
	} else {															// Div is visible: hide it
		hideDiv(whichDiv);
	}
}


function isShown(id) {

	if ( getObjectByID(id).style.display == 'none') {
		return 0;
	} else {
		return 1;
	}
}


function toggle(id) {	// Alternately show or hide content found in the specified div

	if ( isShown(id) ) {
		hideObject(id);
	} else {
		showObject(id);
	}
}


function validateEmailField(id) {				// Checks to see if the field named 'email' has @ and . chars
												// Returns 1 if invalid
	var email = getObjectByID(id).value;

	var emailRegEx = /^[^@]+@[^@]+.[a-z]{2,}$/i;

	if(email.search(emailRegEx) == -1){
		return 1;
	} else {
		return 0;
	}
}

function requireFields() {				// Accepts a list of field ids that must be not be empty, followed by an error prompt and a highlight class.
							// If any fields are empty, returns the specified error mesage and highlights them.
							// If no error message is specified, the alert is surpressed.
							// Returns an array list of invalid field ids
	var idList = requireFields.arguments;
	var badFields = new Array();

	var lastItem = (idList.length)-1;

	var hClass = idList[lastItem];
	var msg = idList[--lastItem];

	for (var n=0; n < lastItem; n++) {		// Cycle through the fields and check their contents

		var thisV = getValue( idList[n] );
		if (!thisV) {							// This field's empty:
			getObjectByID( idList[n] ).className = hClass;		// Change its color
			badFields.push( idList[n] );
		} else {
			getObjectByID( idList[n] ).className = 'valid';
		}
	}

	var badFieldsExist = badFields.length;
	if (badFieldsExist) {
		if (msg) {
			alert(msg);
		}
		return badFields;
	} else {
		return 0;
	}
}


// Phone number validation scripts (origin: SmartWebby.com)

function isInteger(s)
{   var i;
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

function stripCharsInBag(s, bag)
{   var i;
    var returnString = "";

	if(!s) {
		return "";
	}

    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function checkInternationalPhone(strPhone) {
	s = stripCharsInBag(strPhone, "()- +.");			// Valid non-integers in a phone number
	return (isInteger(s) && s.length >= 10);			// Minimum digits in an international phone number
}

function checkLocalPhone(strPhone) {
	s = stripCharsInBag(strPhone, "()- +." );			// Valid non-integers in a phone number
	return (isInteger(s) && s.length == 7);				// Minimum digits in an international phone number
}

function validatePhone(id){		// Accepts phone field id and error prompt as input and returns 1 if invalid
					// If msg is empty, it surpresses the prompt
	var Phone = getValue(id);
	var msg = '';

	if (!checkInternationalPhone(Phone)) {
		if (checkLocalPhone(Phone)) {		// Is it only missing the prefix?

			msg = 'Please include a full phone number with area code';

		} else {				// It's just wrong

			msg = 'Please use a valid phone number';
		}
	} else {
		msg = '';
	}
	return msg;
 }

function validateContactForm() {		// First validates the e-mail field, then verifies that all required fields are complete before submitting

	if (getObjectByID('shortForm').style.display == 'none') {	// New user: validate the entire form

		var invalidE = validateEmailField('email');
		var invalidPhPrompt = validatePhone('phone');

		var emptyFields = requireFields('firstName', 'lastName', 'school', 'district', 'addr1', 'city', 'zip', 'Please complete the form first.', 'invalid');
		var incompleteForm = emptyFields.length;

		if (!incompleteForm) {
			var incompleteE = requireFields('email', '', '');
			var incompletePh = requireFields('phone', '', '');
			var notReady = 0;

			if (incompleteE && incompletePh) {			// Neither e-mail nor phone is included: form is incomplete!
				notReady = 1;
				alert('Please include an e-mail address or \nphone number so we can contact you.');
				getObjectByID('phone').className = 'invalid';
				getObjectByID('email').className = 'invalid';
				setTimeout("focusOn('email');", 120);

			} else if (incompleteE && invalidPhPrompt) {		// Phone is invalid
				alert(invalidPhPrompt);
				getObjectByID('phone').className = 'invalid';
				getObjectByID('email').className = '';
				setTimeout("focusOn('phone');", 120);
				notReady = 1;

			} else if (incompletePh && invalidE) {			// E-mail is invalid
				alert('Please use a valid e-mail');
				getObjectByID('phone').className = '';
				getObjectByID('email').className = 'invalid';
				setTimeout("focusOn('email');", 120);
				notReady = 1;
			}
		} else {
			var cmd = "focusOn('" + emptyFields[0] + "');" ;	// Focus on the first blank form element
			setTimeout(cmd, 120);
		}

		if (!incompleteForm && !notReady) {				// Form is complete and valid: submit
			sendReq('contactForm', 'mainFrame');
		}

	} else {							// Returning user: submit the short form
		sendReq('contactForm', 'mainFrame');
	}
}


function updateRequestForm(refBy) {		// Hides and show selected fields on costEnroll.html

	if (refBy == 1) {
		hideObject('defaultForm');
		hideObject('schoolDetailsForm');
		showObject('shortForm');
	} else {
		hideObject('shortForm');
		showObject('defaultForm');
		showObject('schoolDetailsForm');
		setValue('login', '', 'pwd', '');
	}
}



function HideContent(d) {
if(d.length < 1) { return; }
document.getElementById(d).style.display = "none";
}
function ShowContent(d) {
if(d.length < 1) { return; }
document.getElementById(d).style.display = "block";
}
function ReverseContentDisplay(d) {
if(d.length < 1) { return; }
if(document.getElementById(d).style.display == "none") { document.getElementById(d).style.display = "block"; }
else { document.getElementById(d).style.display = "none"; }
}


function statusAlert(msg) {				// Send a stylized prompt to the statusDiv

	msg = "<img src='images/icon-exclaim.gif'>" + msg;
	setText('statusHead', msg);
}


function setAlert(nodeID, msg) {			// Send alert text to the specified node
	
	msg = "<img src='images/icon-exclaim.gif'>" + msg;
	setText(nodeID, msg);
}


function recoverLostPwd(fieldID, formID, formField) {		// Retrieve a forgotten password (if it exists)

	var email = getValue(fieldID);						// Ensure that e-mail field is filled correctly
	var alertMsg = '';

	if (email == '') { 											// E-mail field is blank

		alertMsg = 'Type your e-mail address first.';
	}

	var invalidEmail = validateEmailField(fieldID);				// Validate e-mail field before submitting request

	if(invalidEmail) {
		alertMsg = "Please type a valid e-mail address.";
	}

	if (alertMsg) {
		statusAlert(alertMsg);
	} else {											// No warnings: e-mail address is OK
					
		setValue(formField, email);				// Update recoverPwd form with e-mail address & send request
		sendReq(formID, 'eval');
	}
}


function setText() {					// Sets the innerHTML of specified objects to desired text.

	var lastObj = (setText.arguments.length);
	for(n=0; n<lastObj; n++) {
		thisID = setText.arguments[n]
		thisObj = getObjectByID(thisID);

		if(!thisObj) {
			alert("setText error: " + thisID + " doesn't exist");
			++n;
		} else {
			thisText = setText.arguments[++n];
			thisObj.innerHTML = thisText;
		}
	}
}

function getText(ID) {						// Returns the innerHTML of a specified <span> field

	var textSpanObj = getObjectByID(ID);
	var text = textSpanObj.innerHTML;

	return(text);
}


function padLeft(inputString, padChar, count) {	// Pads inputString with the specified number of padChars. Example: padLeft('Z', '0', 3) yields '00Z'

var outputString = inputString + '';

	while (outputString.length < count) {
		outputString = padChar + outputString;
	}
	
	return outputString;
}


function sqlDate(slashedDate) {			// Accepts slashed date format as input and returns a dashed date
	
	var dateParts = slashedDate.split("/");
	var mm = padLeft(dateParts[0], '0', 2);
	var dd = padLeft(dateParts[1], '0', 2);
	var yyyy = padLeft(dateParts[2], '0', 2);
	
	if (yyyy.length == 2) {
		yyyy = '20' + yyyy;
	}
	
	return yyyy + '-' + mm + '-' + dd;
}

function fixDatesAndSubmit() {   		// Accepts a formName and list of fields as input and converts unix dates to slashed dates.
										//	If formName is specified, submits that form after encoding the dates
										//	Typically used in conjunction with datePicker.js
											
	var formName   = fixDatesAndSubmit.arguments[0];
	var dateFields = fixDatesAndSubmit.arguments;
	var lastField  = fixDatesAndSubmit.arguments.length;
	
	var thisDate;
	var fieldID;
		
	for(var n=1; n<lastField; n++) {
		
		fieldID  = dateFields[n];
		
		thisDate = getValue( fieldID );
		thisDate = sqlDate(thisDate);
		
		setValue(fieldID, thisDate);
	}
	
	if (formName) {
		getObjectByID(formName).submit();	
	}
}


function slashDate() {						// Accepts a list of field names as input and converts their dates from unix format to mm/dd/yyyy

	var fieldList = slashDate.arguments;
	var lastObj = fieldList.length;
	
	for(var n=0; n<lastObj; n++) {

		var thisID = fieldList[n];
		var thisDate = getValue(thisID);

		var dateParts = thisDate.split("-");

		formattedDate = dateParts[1] + "/" + dateParts[2] + "/" + dateParts[0];
		
		if (formattedDate == '00/00/0000') {
			formattedDate = '';
		}
		setValue(thisID, formattedDate);
	}
	
}


		// General Routines :

function createDialog(dialogID, w, topPos, textColor, bgColor, bgImg, htmlText) {		// Constructs a new dialog of the specified type if it doesn't already exist

																// dialogID  : name or ID for the dialog
																// w         : specified width of the dialog (required)
																// topPos    : absolute top position of the dialog (required)
																// textColor : optional text color
																// bgColor   : color of the dialog's background
																// bgImg     : optional background image
																// htmlText  : optional dialog contents

	dialogObject = getObjectByID(dialogID);						// Does the requested dialog already exist?
	
	if ( !dialogObject ) {
		var dialogObject   = document.createElement('div');			// Dialog doesn't exist yet: create a new div and add it to the page body
		dialogObject.setAttribute('id', dialogID);					// 		Give the element an id and initialize its properties
		dialogObject.className      = 'dialog';
		dialogObject.style.position = 'absolute';
		dialogObject.style.display = 'none';
		document.body.appendChild( dialogObject );					// 		Place the dialog at the end of the element list
	}
	
			// Style dialogObject for display

	dialogObject.style.width    = w      + 'px';
	dialogObject.style.top      = topPos + 'px';
	dialogObject.style.left     = '50%';
	dialogObject.style.padding  = '18px';
	
	var leftPos             = parseInt( w / 2 ) * -1;
	dialogObject.style.marginLeft = leftPos + 'px';
	
	if (textColor) {
		dialogObject.style.color = textColor;
	}
	
	if (bgColor) {
		dialogObject.style.backgroundColor = bgColor;
	}
	
	if (bgImg) {
		dialogObject.style.backgroundImage = bgImg;
	}
	
	dialogObject.innerHTML = htmlText;								//		Populate dialogObject with HTML
}


function makeDialog(header, msg, buttonLabel, action) {				// Configures and shows the standard alert dialog, which includes an optional button click action

	if (!action) {																// Alert action is optional; dialogue always hides upon click
		setValue('alertAction', '');
		hideObject('alertCancelButton');
	} else {
		setValue('alertAction', action);
		showObject('alertCancelButton');										// Show a [Cancel] button when there is an action
	}
	
	setAlert('alertHead', header);
	setText('alertPrompt', msg);
	
	if (!buttonLabel) {															// The default button label is 'OK'
		setValue('alertButton', 'OK');
	} else {
		setValue('alertButton', buttonLabel);
	}
	
	showObject('alertDialog');
}


function doAlertAction() {

	var action = getValue('alertAction');
	hideObject('alertDialog');
	
	if (action) {
		eval(action);
	}
}

function askInput(askInputHead, askPrompt, id, inputWidth, buttonLabel, jsAction, dialogWidth, cancelButtonLabel) {		
								// Configures and shows a standard text input dialog with an optional custom action button
								
								//	askPrompt:      question to display along with the text entry field
								//	id:             optional ID or other value to store that can be referenced by the JS action
								//	inputWidth:     width of the text field in pixels
								//	buttonLabel:    text description for the optional action button (i.e., [OK] )
								//	jsAction:       custom script to run if the action button is clicked
								//	dialogWidth:	the dialog box's width
								//	cancelButtonLabel:	if set to 'none', no [Cancel] button is included; if blank, defaults to "Cancel"

			// Construct the dialog
	
	if (!dialogWidth) {
		var dialogWidth = 400;
	}
	var topPos     = 148;
	var textColor  = '#ffffff';
	var bgColor    = '#4e2800';
	var bgImg      = '';
	
	var htmlText  = "<input id='askInputType' type='hidden' />";
	htmlText     += "<input id='askInputID' type='hidden' />";
	htmlText     += "<input id='askInputAction' type='hidden' />";
	
	htmlText     += "<h2 id='askInputHead' class='noMarginTop'>askInput Header</h2>";
	htmlText     += "<label for='askInputText' id='askInputPrompt' class='labelType'>A Prompt or Question Here</label> ";
	htmlText     += "<input style='width:180px;' id='askInputText' type='text' ";
	
				   // Prototype: submitOnReturn(e, formID, sendFormTarget, hideDialog);

	htmlText     += "onkeypress=\"submitOnReturn(event, 'doAskInputAction();', 'e', 'askInputDialog');\" />";
	htmlText     += "<br /><br />";
	
	htmlText     += "<div style='float:right;'>";
	htmlText     += "<input id='askInputButton' type='button' value='OK' onClick='doAskInputAction(); startKeyDetection();' />";
	htmlText     += "<input id='askInputCancelButton' type='button' value='Cancel' style='margin-left: 18px;' onClick=\"hideObject('askInputDialog'); startKeyDetection();\" />";
	htmlText     += "</div>";
	
	createDialog('askInputDialog', dialogWidth, topPos, textColor, bgColor, bgImg, htmlText);


			// Populate the dialog

	setValue('askInputText', '');					// Clear askInputText of possible former entry

	if (jsAction) {									// askInput action is optional... dialogue always hides upon click
		setValue('askInputAction', jsAction);
	} else {
		setValue('askInputAction', '');
	}
	
	if (id) {
		setValue('askInputID', id);
	} else {
		setValue('askInputID', '');
	}

	setText('askInputHead', askInputHead);
	setText('askInputPrompt', askPrompt);
	
	if (!buttonLabel) {															// The default button label is 'OK'
		setValue('askInputButton', 'OK');
		hideObject('askInputCancelButton');										// Hide [Cancel] button when defaulting to [OK]
	} else {
		setValue('askInputButton', buttonLabel);
		showObject('askInputCancelButton');										// Show a [Cancel] button when there is an action
	}
	
		
	if (inputWidth) {
		getObjectByID('askInputText').style.width = '' + inputWidth + 'px';				// Set the dimensions of the input field
	}

	if (cancelButtonLabel == 'none') {
		hideObject('askInputCancelButton');	
		
	} else if (cancelButtonLabel) {
		getObjectByID('askInputCancelButton').value = cancelButtonLabel;
		showObject('askInputCancelButton');	
		
	} else {
		getObjectByID('askInputCancelButton').value = 'Cancel';
		showObject('askInputCancelButton');	
	}
	
	showObject('askInputDialog');
	focusOn('askInputText', 500);
}

function doAskInputAction() {				// Do the specified action when the askInputDialog confirm button is clicked

	var action = getValue('askInputAction');
	hideObject('askInputDialog');
	
	if (action) {
		eval(action);
	}
}

function handleAskInput(askInputType,targetID) {	// Submit askInput to the server for processing

														//	askInputType : describes the interaction for use in subs-handleAskInput case switching
														//	targetID     : optional ID of an element whose HTML will update when processing completes
	if (!targetID) {
		targetID = '';
	}
	var url          = 'subs-handleAskInput.php';
	var callbackFunc = '';
	var syncReqFlag  = '';
			
	var oData = {
		askInputType   : askInputType,
		askInputID     : getValue('askInputID'),
		askInputText   : getValue('askInputText')
	};

	sendData(url, targetID, callbackFunc, oData, syncReqFlag);
	hideObject('askInputDialog');
}


function fetchRadio(type, radioSet, id) {			// Ajax call to retrieve radio button status
													// Note: radioSetForm must be named as radioSetName + 'Form'
	setValue('fetchRadioID', id);
	setValue('fetchRadioType', type);
	setValue('radioForm', radioSet + 'Form');
	setValue('fetchRadioSet', radioSet);
	sendReq('fetchRadioForm', 'js');		
}


function showIfChecked(hiddenObj, radioID) {		// If the radioID is checked, the named object (usually a span or div) is made visible

	if (getObjectByID(radioID).checked) {
		showObject(hiddenObj);
	} else {
		hideObject(hiddenObj);	
	}
}


function update(type, id, fieldList, dialog, doRefresh) {		// Ajax call to update the database via updateForm
									// 	type:      identifies which table and columns to update on the server
									// 	id:        id of the row to update
									// 	fieldList: a series of field ids to send for updating
									//	dialog:    optional dialog to hide after updating
									//	doRefresh: optional flag to specify page refresh after updating (values: 'refresh', '')
	setValue('updateType', type);
	setValue('updateID', id);
								  
	var valueList = joinValues(fieldList);

	setValue('updateV', valueList);
	sendReq('updateForm', doRefresh); 
	
	if (dialog) {
		hideObject(dialog);
	}
}

function updateCheckbox(type, id, field, refreshMode) {						// Simple Ajax call to update the database when a checkbox is checked via updateForm

	setValue('updateType', type);
	setValue('updateID', id);

	var checkedVal;
	
	if ( getObjectByID(field).checked ) {								// Get the value of this box if checked
		checkedVal = getValue(field);
	} else {
		checkedVal = '';
	}

	setValue('updateV', checkedVal);
	sendReq('updateForm', refreshMode); 
}


		// ****************************************
		//   Shared Application-Specific Routines
		// ****************************************

		// Scripts for adminUsers.php, adminPartners.php :

function editUser(id) {				// Populates and opens the editDialog. If id=0, mode=new user

	top.suspendKeyDetection();						// Since user must type in fields, halt key detection for quick searches using showLettersDiv
	setValue('userID', id);						// Update the userID in the editDialog
		
	if (id == 0) {
		setValue('firstName', '', 'lastName', '', 'role', 4, 'email', '', 'phone', '', 'school', '', 'district', '', 'addr1', '', 'addr2', '', 'city', '', 'state', '??', 'zip', '', 'schoolPhone', '', 'fax', '');
		getObjectByID('teachingpartner').checked='checked';
		
		fetch('userDetails', id, 'editDialog', 'firstName', '');

} else {
		fetch('userDetails', id, 'editDialog', 'firstName', '');
		
			// Get the radio button value
			
		setValue('fetchRadioID', id);
		setValue('fetchRadioType', 'accessLevel');
		setValue('radioForm', 'accessLevelForm');
		setValue('fetchRadioSet', 'accessLev');
		sendReq('fetchRadioForm', 'js');	
	}
	
			// Get school info
			
	fetch('schoolInfo', id, 'editDialog', 'firstName', '');
	top.showObject('editDialog');
}
		
function delUser(id, name) {			// Deletes the specified user from the database

	top.setValue('deleteID', id);
	top.setValue('deleteType', 'user');
	top.setAlert('deleteHead', "Delete " + name + "?");
	top.setText('deletePrompt', "You can't undo this action.");
	top.showObject('deleteDialog');
}

function updateAccess(userID, accessLevel, firstBtn, skipBtn, doRefresh) {			// Deselect 4 radio buttons in a set, then store the new accessLevel
																					// doRefresh: if 'refresh' or 'js', allows callbacks or page refreshes
	for (n = firstBtn; n < (firstBtn + 4) ; n++) {

		var radioBtn = 'r' + n;
		
		if (n == skipBtn) {
			getObjectByID(radioBtn).checked = 'checked';
		} else {
			getObjectByID(radioBtn).checked = '';
		}
	}
	
//	setValue('updateType', 'accessLevel');
//	setValue('updateID', userID);
//	setValue('updateV', accessLevel);
//	sendReq('updateForm', doRefresh);

	var url          = 'subs-update.php';
	var targetID     = '';
	var callbackFunc = '';
	var syncReqFlag  = '';
			
	var oData = {
		'updateType'   : 'accessLevel',
		'updateID'     : userID,
		'updateV'      : accessLevel
	};

	sendData(url, targetID, callbackFunc, oData, syncReqFlag);
}


function updateUser() {		// Submit user or partner details to the server

	var userID           = getValue('userID');
	var originalSchoolID = getValueForOption('schoolID', 1);
	
	var valueList = joinValues('firstName, lastName, role, email, phone, schoolID, school, district, addr1, addr2, city, state, zip, schoolPhone, fax');

	valueList = getRadio('accessLevelForm', 'accessLev') + "|" + valueList + "|" + originalSchoolID;	
	
	var url          = 'subs-update.php';
	if (userID == 0) {
		var targetID  = '';
	} else {
		var targetID  = 'row' + userID;
	}
	var callbackFunc = '';
	var oData        = {
		updateType : 'userInfoAndSchool',
		updateID   : userID,
		updateV    : valueList
	};
	var syncReqFlag = '';
	
	getObjectByID('dataFrame').contentWindow.sendData(url, targetID, callbackFunc, oData, syncReqFlag);
	
	hideObject('editDialog');
}
	
function inviteUser(userID) {

	setValue('inviteID', userID);
	sendReq('inviteForm', 'js');
}


function setPwd(userID, possessiveName) {			// Prompts Administrator to change a User's Password
	
	suspendKeyDetection();
	
	var askInputHead      = 'Change or Specify ' + possessiveName + ' Password';
	var askPrompt         = 'New Password:';
	var inputWidth        = 250;
	var buttonLabel       = 'Set Password';
	var jsAction          = "handleAskInput('setPwd', ''); ";
	var dialogWidth       = 388;
	var cancelButtonLabel = 'Cancel';
	
	askInput(askInputHead, askPrompt, userID, inputWidth, buttonLabel, jsAction, dialogWidth, cancelButtonLabel);
}


function sendPwdNotification(userID) {		// Notify a user when their e-mail address has changed.

	var url          = 'adminUsers-sendPwdNotification.php';
	var targetID     = '';
	var callbackFunc = '';
	var syncReqFlag  = '';
			
	var oData = {
		userID   : userID
	};

	sendData(url, targetID, callbackFunc, oData, syncReqFlag);
}
