/// <reference path="~/include/jquery-1.3.2-vsdoc.js" />

//Set this to a new version when users should clear their cache
//Also set the the value in web.config to the same version
var jsVersion = 2.4;

/*******************************************************************
Function Index
********************************************************************
1.) function Rtrim(thestr)
2.) function errNumeric(formField,fieldLabel, min, max, len, noBlank, round, showalert)
- check field for numeric, alert them or return error, round
3.) function errNumPunc(formField,fieldLabel,delims,numdigits,showalert)
- Checks a field for numbers and punctuation. Allows user to specify the punctuation 
and required length
4.) function dollarFormat(expr)
5.) function decimalFormat(expr, decplaces)
6.) function getRadioIndex(buttonGroup)
- returns the index of the selected radio button (ex: getRadioIndex(this.form.active_ind))
7.) function getRadioValue(buttonGroup)
- returns the value of the selected radio button (ex: getRadioValue(this.form.active_ind))
8.) function getRadioValues(buttonGroup)
- returns comma delim list of all values within the radio button group 
(ex: getRadioValues(this.form.active_ind))
9.) function confirmButton(buttonGroup,prevvalue_field,confirmStr)
10.) function setRadioButton(buttonGroup,theValue)
11.) function isInteger (s)
12.) function isYear (s)
- isYear returns true if string s is a valid Year number.  Must be 4 digits only.
13.) function isIntegerInRange (s, a, b)
- isIntegerInRange returns true if string s is an integer within the range of integer arguments a and b, inclusive.
14.) function isMonth (s)
- isMonth returns true if string s is a valid month number between 1 and 12.
15.) function isDay (s)
- isDay returns true if string s is a valid day number between 1 and 31.
16.) function daysInFebruary (year)
- daysInFebruary (INTEGER year) returns number of days in February of that year.
17.) function isDate (year, month, day, fieldLabel, noBlank, showalert)
- isDate checks if string arguments year, month, and day form a valid date.  Error string returned with/out data.
18.a) function errDate(thefield, fieldLabel, noBlank, showalert) validates date value, takes a text-control as input param
18.b) function errDateValue(fieldValue, fieldLabel, noBlank, showalert) (6/9/2011 - DLynch - new function) validates date value, this takes a string as input param
19.) function CompareDates(firstDate, secondDate)
- Compares two dates in format 01/01/1999 and returns -1 if first one less, 0 if same, 
and 1 if second greater.  Assumes that dates have already been validated
if firstDate < secondDate function returns the number of years as negative
20.) function errCompareDates(firstDate, secondDate)
- Compares two dates in format 01/01/1999 and returns -1 if first one less, 0 if same, 
and 1 if second greater.  Returns -999 if firstDate has error, +999 if second has error
if firstDate < secondDate function returns the number of years as negative
21.) function GetPickList(thelist)
- GetPickList returns the value from a single selection SELECT list
22.) function GetPickListText(thelist)
- GetPickListText returns the Text from a single selection SELECT list
23.) function ItemSelected(thelist)
- Check to see if the default item is selected
24.) function setPickList(thelist, thevalue)
- Sets specific value in list
25.) function setPickListMulti(thelist, thevalue)
- Sets specific value in list
26.) function setPickListLike(thelist, thevalue)
- Sets similar value in list used in places like quick fill 
27.) function setPickListLikeMulti(thelist, thevalue)
- Sets similar value in list
28.) function GetPickListMulti(thelist)
- Returns comma delimited list of values from a MULTI-Select box 
29.) function GetPickListMultiQuoted(thelist)
- Returns QUOTED comma delimited list of values from a MULTI-Select box 
30.) function GetPickListTextMulti(thelist)
- Returns comma delimited list of text from a MULTI-Select box 
31.) function RemovePickListMulti(thelist)
- Removes all selected options from a MULTI-Select box 
32.) function MovePickListMulti(fromlist,tolist)
- Moves options FROM a multi Select box to another 
33.) function GetPickListMultiAll(thelist)
- Returns comma delimited list of ALL values from a MULTI-Select box 
34.) function GetPickListTextMultiAll(thelist)
- Returns comma delimited list of ALL text from a MULTI-Select box 
35.) function checkbox_check_all() 
- Check all checkboxs on the page
36.) function checkbox_un_check_all()
- Un-check all checkboxs on the page
37.) function checkbox_check_all_v2(form, startwith) 
- Check all checkboxs on the page who's ids start with 'startwith'
38.) function checkbox_un_check_all_v2(form, startwith)
- Un-check all checkboxs on the page who's ids start with 'startwith'
39.) function make_textarea_larger(objName, icols, irows)
- for a textarea, pass in the number of cols and rows you want to increase by
40.) function getCheckBoxValues(form, btn_name)
- returns comm delimited list of all values from textboxes
41.) function IsNumeric(sText)
42.) function loading(text, color, load_height, load_width)
- displays a loading window in the center of the screen with color being the border color
43.) function fakeAJAX([serverscript],[function], [var1], [var2], [var3],...)
- emulates AJAX by calling a server side script in a hidden IFRAME and then calling a javascript function after the serverside script is complete.
- serverscript: the file that will be loaded on the server.  Use /fakeAJAX_temp.asp as a template
- function: the name of the function that will be called when the server is finished (do not use parenthesis)
- var1, var2, var3: will be sent along with the fakeAJAX return value when "function" is called. (Ex: tempFunct(returnVal, var1, var2, var3))
44.) object BrowserDetect
- Used for pulling the browser, version, and OS off of the client: BrowserDetect.browser, BrowserDetect.version, BrowserDectect.OS
44.) function getIndex(field)
- returns a integer value that can be used in the form.elements collection to reference "field"
45.) function moveUpDown(e, currentField)
- used to move up and down columns of fields named <field_name>_<id> with arrow keys.
- to use place 'onKeyDown="moveUpDown(event, this);"' into every field you wish the action to be fired
- Note: requires getIndex(field)
- Note: this function disables any normal function of the up and down arrow keys for the input field in question. For instance select boxes!!
46.) function function get_cookie ( cookie_name ) - read cookie
47.) function set_cookie ( name, value, exp_y, exp_m, exp_d, path, domain, secure ) - set cookie
48.) function spsReplaceAll(SourceString, FindText, ReplacementText)
49.) function spsRemoveTrailingBRs(HTMLString) - removes all trailing (ending) <br> and spaces from an html string
50.) function spsRemoveTrailingCharacters(Source, InputRemoveChar) - Removes all 'trailing' characters (in the InputRemoveChar) from the Source string
51.) function spsTrim(s) - removes all leading and trailing spaces
52.) function spsLtrim(s) - removes all leading spaces
53.) function spsRtrim(s) - removes trailing leading spaces
54.) function spsGetScrollbarWidth - get width of scroll bar for a user (width can be different depending on os, browser, color scheme, font size etc..)
55.) releaseNotes(extra) - optional anchor tag parameter
*******************************************************************
*******************************************************************/
function drewstest(varx) {
	alert("whats up?");
	return false;
}
function OpenTechPaths(Target) {
	self.location = "/external/from_pt_2_techpaths.asp?Target=" + Target
}
function OpenTechPathsMap(go_to_courseid) {
	self.location = "/external/from_pt_2_techpaths.asp?go_to_courseid=" + go_to_courseid;
}
function OpenTechPathsMap_report_popup(go_to_class_map_id) {
	var win_location;
	win_location = "/external/from_pt_2_techpaths.asp?Target=view_map_report&go_to_class_map_id=" + go_to_class_map_id;
	/*	this shows how to open a resizable window 
	of a particular height and width, 
	with a defined offset from the top and left, 
	displaying the status, menubar and location showing:
	*/
	//sessionwin = window.open(win_location,"newwindow","height=400,width=800,left=50,top=50,resizable,scrollbars,status,menubar,location,toolbar,copyhistory,directories")
	sessionwin = window.open(win_location, '_blank', 'resizable=yes, scrollbars=yes, status=yes, menubar=yes');
	if (sessionwin) {
		sessionwin.focus();
	}
}
function OpenWindow(vNewWin, url) {
	var win_location;
	var NewWinInd;
	NewWinInd = vNewWin;
	//NewWinInd = 1 //for right now always open a new window, until the link finally works
	win_location = url;
	if (NewWinInd == 1) {
		/*	this shows how to open a resizable window 
		of a particular height and width, 
		with a defined offset from the top and left, 
		displaying the status, menubar and location showing:
		*/
		//sessionwin = window.open(url,"newwindow","height=400,width=800,left=50,top=50,resizable,scrollbars,status,menubar,location,toolbar,copyhistory,directories")
		sessionwin = window.open(win_location, '_blank', 'resizable=yes, scrollbars=yes, status=yes, menubar=yes');
		if (sessionwin) {
			sessionwin.focus();
		}
	}
	else {
		self.location = win_location;
	}
}
function windowpopup_view_cb_question(cb_question_id, assessment_question_id) {
	/*	
	If you don't have an assessment_question_id, pass empty string
	*/
	var url;
	if (cb_question_id != '0') {	//war 9/16/2010 P10.12; if there is no cb id, open assessment question popup instead
		url = "/content_builder/question_view_popup.asp?cb_question_id=" + cb_question_id + "&assessment_question_id=" + assessment_question_id;
	}
	else {
		url = "/assessments/assessment_question_view_popup.asp?assessment_question_id=" + assessment_question_id;
	}
	//sessionwin = window.open(url,"newwindow","height=400,width=800,left=50,top=50,resizable,scrollbars,status,menubar,location,toolbar,copyhistory,directories")
	//sessionwin = window.open(url,"newwindow","height=250,width=450,left=50,top=50,resizable,scrollbars")
	sessionwin = window.open(url, "newwindow", "height=400,width=500,left=50,top=50,resizable,scrollbars")
	// this shows how to refocus on the above window (so that we don't continuously open new windows)
	if (sessionwin) {
		sessionwin.focus();
	}
}

function Rtrim(thestr) {
	var cont = true;
	while (cont) {
		trailing = thestr.substring(thestr.length - 1, thestr.length);
		// if last char is a space, strip it off and continue testing the last space 
		if (trailing == " ") {
			thestr = thestr.substring(0, thestr.length - 1);
		}
		else {
			cont = false;
		}
	}
	return thestr;
}

function spsTrim(s) {
	return spsRtrim(spsLtrim(s));
}
function spsLtrim(s) {
	var i = 0;
	while (i < s.length && s[i] == ' ') {
		i++;
	}
	return s.substring(i, s.length);
}


function spsRtrim(s) {
	var r = s.length - 1;
	while (r > 0 && s[r] == ' ') {
		r -= 1;
	}
	return s.substring(0, r + 1);
}



/*******************************************************************
*                 NUMERIC CHECKS                                   *
*                                                                  *
*                                                                  *
*******************************************************************/

// check field for numeric, alert them or return error, round
function errNumeric(formField, fieldLabel, min, max, len, noBlank, round, showalert) {
	// numeric field check
	var errorStr = ""
	var numcomma = 0;
	var notanum = false;
	if (formField.value.length > 0) {
		notanum = isNaN(parseFloat(formField.value));
		//alert("parseFloat(formField.value) = " + parseFloat(formField.value));
		//alert("isNaN(formField.value) = " + isNaN(formField.value));
	}
	if (notanum) {
		errorStr += fieldLabel + " is not a number.\n";
		// rich added to return the error
		if (showalert) {
			alert(errorStr);
		}
		else {
			return errorStr;
		}
	}

	// no blanks & if length is 0, then just return
	if (formField.value.length == 0) {
		if (noBlank == true) {
			errorStr += fieldLabel + " cannot be blank.\n"
			if (showalert == true)
				alert(errorStr);
			return errorStr
		}
		else {
			return errorStr;
		}
	}
	// if field ends in period, truncate
	var vlength = formField.value.length;
	if (formField.value.substring(vlength - 1, vlength) == '.') {
		formField.value = formField.value.substring(0, vlength - 1);
	}
	// field must be numeric or comma or period
	for (var i = 0; i < formField.value.length; i++) {
		var ch = formField.value.substring(i, i + 1)
		if (ch == ",")
			numcomma++

		if ((ch < "0" || ch > "9") && (ch != ",") && (ch != ".") && (ch != "-")) {
			errorStr += fieldLabel + " must be numeric.\n"
			if (showalert == true)
				alert(errorStr);
			return errorStr
		}
	}
	// add rounding back to number
	if (round == true) {
		// Check for decimal and round value past decimal
		var decindex = formField.value.lastIndexOf(".");
		var dec = 0;
		var left = '0';
		if (decindex > -1) {
			// if number in front of decimal
			if (decindex > 0) {
				left = formField.value.substring(0, decindex);
			}
			dec = 0 + Math.round(formField.value.substring(decindex, formField.value.length));
		}
		else
			left = formField.value;
		// get string with only digits and store string + round back
		var numwoutcomma = "";
		for (var i = 0; i < left.length; i++) {
			var ch = left.substring(i, i + 1)
			if (ch != ",")
				numwoutcomma += ch;
		}
		if (parseInt(numwoutcomma) >= 0)
			formField.value = parseInt(numwoutcomma, 10) + dec;
		else
			formField.value = parseInt(numwoutcomma, 10) - dec;
	}

	// max/min
	if ((min != 0 || max != 0) && len > -1) {
		if ((formField.value < min) || (formField.value > max)) {
			errorStr += fieldLabel + " must be between " + min + " and " + max + ".\n";
			if (showalert == true)
				alert(errorStr);
			return errorStr
		}
	}
	// max/min when only warning for negatives
	// only alert if -1, -2 means do not alert (used in CheckAndSubmit)
	if ((min != 0 || max != 0) && len < 0) {
		if ((((parseInt(formField.value) < 0) && (Math.abs(parseInt(formField.value))) > Math.abs(min)) && ((parseInt(formField.value) > 0) && (Math.abs(parseInt(formField.value))) < Math.abs(min))) || (Math.abs(parseInt(formField.value)) < Math.abs(max))) {
			// within bounds so check if need to warn (do not return since not error)
			if ((len != -2) && ((formField.value < min) || (formField.value > max))) {
				errorStr += fieldLabel + " is typically between between " + min + " and " + max + ".\n";
				if (showalert == true)
					alert(errorStr);
			}
		}
		else {
			// outside bounds
			if ((formField.value < min) || (formField.value > max)) {
				if (len == -1)
					errorStr += fieldLabel + " is typically between between " + min + " and " + max + ".\n";
				else
					errorStr += fieldLabel + " must be between " + min + " and " + max + ".\n";
				if (showalert == true)
					alert(errorStr);
				return errorStr
			}
		}
	}
	// length
	if (len > 0 && formField.value.length != len - numcomma && formField.value.length > 0) {
		errorStr += fieldLabel + " must be " + len + " characters long.\n"
		if (showalert == true)
			alert(errorStr);
	}
	return errorStr
}

//
// Checks a field for numbers and punctuation.
// allows user to specify the punctuation and required length
function errNumPunc(formField, fieldLabel, delims, numdigits, showalert) {
	var errorStr = ""
	var testStr = "";

	testStr = stripCharsNotInBag(formField.value, delims + '0123456789');
	if (testStr.length != formField.value.length) {
		errorStr += fieldLabel + " contains invalid characters.\n"
		if (showalert == true)
			alert(errorStr);
	}
	else {
		testStr = stripCharsNotInBag(formField.value, '0123456789');
		// normal check is length vs number of digits
		if (numdigits != 0) {
			if (formField.value.length != numdigits) {
				// but if created by system will include single alpha
				//if ((numdigits < 0) && (testStr.length < (Math.abs(numdigits)-1))) {
				errorStr += fieldLabel + " must be " + Math.abs(numdigits) + " digits.\n"
				if (showalert == true)
					alert(errorStr);
				//}
			}
		}
	}
	return errorStr
}
function dollarFormat(expr) {
	return "$" + decimalFormat(expr, 2);
}
function decimalFormat(expr, decplaces) {
	// raise by power of 10 times the decplaces; round to an int; convert to str
	var str = "" + Math.round(eval(expr) * Math.pow(10, decplaces));
	// pad with zeros 
	while (str.length <= decplaces) {
		str = "0" + str;
	}
	// get location of decimal point
	var decpoint = str.length - decplaces;
	return str.substring(0, decpoint) + "." + str.substring(decpoint, str.length);
}



// returns the index of the selected radio button (ex: getRadioIndex(this.form.active_ind))
function getRadioIndex(buttonGroup) {
	theindex = "";
	for (var i = 0; i < buttonGroup.length; i++) {
		if (buttonGroup[i].checked) {
			theindex = i;
		}
	}
	return theindex;
}
// returns the value of the selected radio button (ex: getRadioValue(this.form.active_ind))
function getRadioValue(buttonGroup) {
	var thevalue = "";
	//6/12/2007 - DLynch - Fix if button is not a group
	if (!buttonGroup.length || buttonGroup.length == "") {
		//alert("Not a group");
		if (buttonGroup.checked) {
			thevalue = buttonGroup.value;
		}
	}
	else
	//alert("It is a group");
	{
		for (var i = 0; i < buttonGroup.length; i++) {
			if (buttonGroup[i].checked) {
				thevalue = buttonGroup[i].value;
			}
		}
	}
	return thevalue;
}

// returns comma delim list of all values within the radio button group (ex: getRadioValues(this.form.active_ind))
function getRadioValues(buttonGroup) {
	var listValues = "";
	for (var i = 0; i < buttonGroup.length; i++) {
		if (listValues > "") {
			listValues += ",";
		}
		listValues += buttonGroup[i].value;
	}
	return listValues;
}

function confirmButton(buttonGroup, prevvalue_field, confirmStr) {
	var rUstr = "Are you sure you want to:\n";
	var oldIndex = "";
	var oldValue = "";
	var currentIndex = "";
	var currentValue = "";

	confirmStr = rUstr + confirmStr;
	oldValue = prevvalue_field.value;
	currentIndex = getRadioIndex(buttonGroup); // returns the selected button's index
	currentValue = getRadioValue(buttonGroup); // returns the selected button's value
	var listValues = getRadioValues(buttonGroup); // returns list of all values for the radio button group
	//	alert("listValues: " + listValues + "\ncurrentIndex: " + currentIndex + "\ncurrentValue: " + currentValue);

	var arrayValues = listValues.split(","); // convert returned list into an array, loop thru and get the index of the old value
	for (var i = 0; i < arrayValues.length; i++) {
		if (oldValue == arrayValues[i]) {
			oldIndex = i;
			break;
		}
	}
	// make sure the user didn't click the currently selected button
	if (oldIndex != currentIndex) {
		if (confirm(confirmStr)) {
			buttonGroup[currentIndex].checked = true;
			prevvalue_field.value = currentValue;
			return true;
		}
		else {
			buttonGroup[oldIndex].checked = true;
			return false;
		}
	}
}
function setRadioButton(buttonGroup, theValue) {
	var theIndex = "";
	var listValues = getRadioValues(buttonGroup);
	var arrayValues = listValues.split(","); // convert returned list into an array
	//	alert(listValues);
	// loop thru and find the index of the value
	for (var i = 0; i < arrayValues.length; i++) {
		if (theValue == arrayValues[i]) {
			theIndex = i;
			break;
		}
	}
	if (theIndex > -1) {
		buttonGroup[theIndex].checked = true;
	}
}

function isInteger(s) {
	var i;
	// Search through string's characters one by one
	// until we find a non-numeric character.
	// When we do, return false; if we don't, return true.
	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;
}

/*******************************************************************
*                 DATE CHECKS                                      *
*                                                                  *
*                                                                  *
*******************************************************************/
// define number of days for month - except february which is checked
var daysInMonth = new Array(12);
daysInMonth[1] = 31;
daysInMonth[2] = 29;   // must programmatically check this
daysInMonth[3] = 31;
daysInMonth[4] = 30;
daysInMonth[5] = 31;
daysInMonth[6] = 30;
daysInMonth[7] = 31;
daysInMonth[8] = 31;
daysInMonth[9] = 30;
daysInMonth[10] = 31;
daysInMonth[11] = 30;
daysInMonth[12] = 31;
// isYear returns true if string s is a valid 
// Year number.  Must be 4 digits only.
function isYear(s) {
	if (!isIntegerInRange(s, 1900, 2100)) return false;
	return (s.length == 4);

}
// isIntegerInRange returns true if string s is an integer 
// within the range of integer arguments a and b, inclusive.
function isIntegerInRange(s, a, b) {
	// Catch non-integer strings to avoid creating a NaN below,
	// which isn't available on JavaScript 1.0 for Windows.
	if (!isInteger(s, false)) return false;
	// check if leading 0 and remove
	if ((s.substring(0, 1) == "0") && (s.length > 1))
		s = s.substring(1, s.length);

	// Now, explicitly change the type to integer via parseInt
	// for JS 1.1/1.2 compatability
	var num = parseInt(s, 10);
	return ((num >= a) && (num <= b));
}
// isMonth returns true if string s is a valid 
// month number between 1 and 12.
//
function isMonth(s) {
	return isIntegerInRange(s, 1, 12);
}
// isDay returns true if string s is a valid 
// day number between 1 and 31.
// 
function isDay(s) {
	return isIntegerInRange(s, 1, 31);
}
// daysInFebruary (INTEGER year)
// 
// returns number of days in February of that year.
function daysInFebruary(year) {   // February has 29 days in any year evenly divisible by four,
	// EXCEPT for centurial years which are not also divisible by 400.
	return (((year % 4 == 0) && ((!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28);
}
// isDate checks if string arguments year, month, and day 
// form a valid date.  Error string returned with/out data.
// 
function isDate(year, month, day, fieldLabel, noBlank, showalert) {
	var errorStr = "";
	// check for missing values & exit
	if ((year.length == 0) || (month.length == 0) || (day.length == 0)) {
		if (noBlank == true) {
			errorStr += fieldLabel + " cannot be blank.\n";
			if (showalert == true)
				alert(errorStr);
		}
		return errorStr;
	}
	// catch invalid years (not 2- or 4-digit) and invalid months and days.
	if (!(isYear(year, false) && isMonth(month, false) && isDay(day, false))) {
		errorStr += "Please enter " + fieldLabel + " in mm/dd/yyyy format.\nFor example, 08/01/1999.\n";
		if (showalert == true)
			alert(errorStr);
		return errorStr
	}
	// Explicitly change type to integer to make code work in both
	// JavaScript 1.1 and JavaScript 1.2.
	var intYear = parseInt(year, 10);
	var intMonth = parseInt(month, 10);
	var intDay = parseInt(day, 10);
	// catch invalid days, except for February
	if (intDay > daysInMonth[intMonth]) {
		errorStr += "Please enter " + fieldLabel + " in mm/dd/yyyy format.\nFor example, 08/01/1999.\n";
		if (showalert == true)
			alert(errorStr);
		return errorStr
	}
	if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) {
		errorStr += "Please enter " + fieldLabel + " in mm/dd/yyyy format.\nFor example, 08/01/1999.\n";
		if (showalert == true)
			alert(errorStr);
		return errorStr
	}
	return errorStr;
}
function errDate(thefield, fieldLabel, noBlank, showalert) {
	var fieldValue = "";
	fieldValue = new String(thefield.value);
	return errDateValue(fieldValue, fieldLabel, noBlank, showalert);
}
function errDateValue(fieldValue, fieldLabel, noBlank, showalert) {
	//6/9/2011 - DLynch - new function to check date values, this takes a string input param
	//The orig routine errDate needed a 'text' control) but this takes a string variable instead 
	//moved all the orig code from errDate() to this new one and recoded it to handle string var and errDate() now calls this one
	var thefield_value = new String(fieldValue);
	var errorStr = "";
	var isplit = 0;
	var sMonth = "";
	var sDay = "";
	var sYear = "";

	if (thefield_value.length == 0) {
		if (noBlank == true) {
			errorStr += "Please enter " + fieldLabel + " in mm/dd/yyyy format.\nFor example, 08/01/1999.\n";
			if (showalert == true)
				alert(errorStr);
		}
		return errorStr;
	}
	//Returns true if value is a date in the mm/dd/yyyy format
	isplit = thefield_value.indexOf('/');

	// Added the 2nd 'OR' clause below to catch dates added with '/' as the first character
	if (isplit == -1 || isplit == thefield_value.length || thefield_value.substring(0, 1) == "/") {
		errorStr += "Please enter " + fieldLabel + " in mm/dd/yyyy format.\nFor example, 08/01/1999.\n";
		if (showalert == true)
			alert(errorStr);
		return errorStr;
	}

	sMonth = thefield_value.substring(0, isplit);
	isplit = thefield_value.indexOf('/', isplit + 1);

	if (isplit == -1 || (isplit + 1) == thefield_value.length) {
		errorStr += "Please enter " + fieldLabel + " in mm/dd/yyyy format.\nFor example, 08/01/1999.\n";
		if (showalert == true)
			alert(errorStr);
		return errorStr;
	}
	sDay = thefield_value.substring((sMonth.length + 1), isplit);
	sYear = thefield_value.substring(isplit + 1);
	// to pickup the following formats as errors:
	//  0101//2000 OR //01012000
	//	001/1/2000 OR 1/001/2000
	//	0101//2000 OR /0101/2000
	if (thefield_value.indexOf('//') > -1) {
		errorStr += "Please enter " + fieldLabel + " in mm/dd/yyyy format.\nFor example, 08/01/1999.\n";
		if (showalert == true)
			alert(errorStr);
		return errorStr;
	}
	if (sMonth.length == 3 || sMonth.length == 4 || sDay.length == 3 || sDay.length == 4) {
		errorStr += "Please enter " + fieldLabel + " in mm/dd/yyyy format.\nFor example, 08/01/1999.\n";
		if (showalert == true)
			alert(errorStr);
		return errorStr;
	}
	return isDate(sYear, sMonth, sDay, fieldLabel, noBlank, showalert)
}
function spsConvertLazyDates(InputDateString) {
	//this will return an empty string if an invalid date was passed in
	//this will return a full 4 year digit formatted date
	//InputDateString formats: mm/dd OR mm/dd/ OR mm/dd/yy OR it could be mm/dd/yyyy
	//handles:
	//1. user types in no year: 5/1  and wanted system to assume 5/1 of the  current year
	//2. user types in 2 digit year: 5/1/99  and wanted system to assume 5/1/1999
	var sNewDateVal = new String(InputDateString);
	var sGoodDateVal = new String("");
	var bValidDate = false;
	var rc = errDateValue(InputDateString, 'Some Date', false, false)
	if (rc.length === 0) {
		bValidDate = true;
		sGoodDateVal = InputDateString; //hey its a fully formatted good year...
	}
	//Calculate Current School Year (Aug thru Dec = 2010; Jan thru Jul = 2011
	var sYear = "";
	var sOriginalYear = "";
	var sFullYear = "";
	var dt1 = new Date
	var lSysYear = dt1.getFullYear();
	var lSysMonth = dt1.getMonth() + 1; //javascript represents months starting Jan = 0, Feb = 1 etc...
	var CurrSchoolYear = 0;
	var sMonth = spsDateGetDatePart(InputDateString, 'MONTH');
	var lMonth = parseInt(sMonth, 10);
	if ((lMonth >= 1) && (lMonth <= 7)){
		if (lSysMonth <= 7){
			CurrSchoolYear = lSysYear;
		} else {
		CurrSchoolYear = lSysYear + 1;
		}
	}
	if ((lMonth >= 8) && (lMonth <= 12)) {
		if (lSysMonth >= 8) {
			CurrSchoolYear = lSysYear;
		} else {
			CurrSchoolYear = lSysYear - 1;
		}
	}
	if (CurrSchoolYear === 0) {
		//user must have entered an invalid 'month' (a value not between 1 thru 12)
		//lets return empty string to signify its a bad date....
		bValidDate = false;
		return ''; 
	}
	//lets see if user entered a mm/dd (without year) ex: 7/1  or 7/1/
	//lets try and find the double slash..
	if (bValidDate === false) {
		//first lets see if user has entered no year or a 2 digit year
		sOriginalYear = spsDateGetDatePart(InputDateString, 'YEAR');
		sYear = (sOriginalYear.length === 1) ? "0" + sOriginalYear : sOriginalYear;      // SJL allow one-digit years
		if (sYear.length === 0) {
			sNewDateVal += '/' + CurrSchoolYear; // if a user entered 7/1/ then we just made it 7/1//2011 ; if user typed in 9/1 this would make it 9/1/2010
		} else {
			if (sYear.length === 2) {
				//appears industry is 00 - 29 assume 2000's/ 30 - 99 = 1900's
				if (parseInt(sYear, 10) < 30) {
					sFullYear = '20' + sYear;
				} else {
					sFullYear = '19' + sYear;
				}
				sNewDateVal = sNewDateVal.substring(0, sNewDateVal.length - sOriginalYear.length) + sFullYear;   // SJL allow one-digit years
			}
		}
		sNewDateVal = spsReplaceAll(sNewDateVal, '//', '/');
		var rc = errDateValue(sNewDateVal, 'Some Date', false, false)
		if (rc.length === 0) {
			//we have a good date
			sGoodDateVal = sNewDateVal;
		} else {
			sGoodDateVal = ''; //we basicallly have a date string we cant figure out
		}

	}
	return sGoodDateVal;

}
function spsDateGetDatePart(sInputDateString, sDatePart) {
	//sDatePart = YEAR, MONTH, DAY
	//InputDate format must be mm/dd OR mm/dd/yy OR mm/dd/yyyy
	var NbrSlashes = 0
	var miPos = 0;
	var sMyDate = new String(sInputDateString);
	var miDone = false;
	var sMonth = "";
	var sDay = "";
	var sYear = "";
	var lMaxLoop = 100;
	var lCtr = 0;
	if (sDatePart === 'YEAR') {
		miPos = 0
		while (miDone === false) {
			lCtr = lCtr + 1;
			if (lCtr > lMaxLoop) {
				miDone = true;
			}
			miPos = sMyDate.indexOf('/', miPos);
			if (miPos === -1) {
				//Im at the end lets exit
				miDone = true;
			}
			if (miPos > -1) {
				//found one
				NbrSlashes = NbrSlashes + 1;
				if (NbrSlashes >= 2) {
					miDone = true;
					sYear = sMyDate.substring(miPos + 1);
				}
				miPos = miPos + 1;
			}
		}
		return sYear;
	}
	if (sDatePart === 'MONTH') {
		miPos = sMyDate.indexOf('/', miPos);
		if (miPos === -1){
			return ""; //did not find any slash
		}
		sMonth = sMyDate.substring(0, miPos);
		return sMonth;
	}
	var miPosFirstSlash;
	if ((sDatePart === 'DAY') || (sDatePart === 'YEAR')) {
		miPos = 0
		miPosFirstSlash = 0;
		while (miDone === false) {
			lCtr = lCtr + 1;
			if (lCtr > lMaxLoop) {
				miDone = true;
			}
			miPos = sMyDate.indexOf('/', miPos);
			if (miPos === -1) {
				//Im at the end lets exit
				miDone = true;
			}
			if (miPos > -1) {
				//found one
				NbrSlashes = NbrSlashes + 1;
				if (NbrSlashes === 1) {
					miPosFirstSlash = miPos;
				}
				if (NbrSlashes >= 2) {
					miDone = true;
					sYear = sMyDate.substring(miPos + 1);
					sDay = sMyDate.substring(miPosFirstSlash + 1, miPos);
				}
				miPos = miPos + 1;
			}
		}
		if (sDatePart === 'DAY') {
			return sDay;
		} else {
			return sYear;
		}
	}
}


// Compares two dates in format 01/01/1999 and returns -1 if first one less, 0 if same, 
// and 1 if second greater.  Assumes that dates have already been validated
// if firstDate < secondDate function returns the number of years as negative
function CompareDates(firstDate, secondDate) {
	var isplit = 0;
	var s1Month = "";
	var s1Day = "";
	var s1Year = "";
	var s2Month = "";
	var s2Day = "";
	var s2Year = "";

	isplit = firstDate.value.indexOf('/');
	s1Month = firstDate.value.substring(0, isplit);
	isplit = firstDate.value.indexOf('/', isplit + 1);
	s1Day = firstDate.value.substring((s1Month.length + 1), isplit);
	s1Year = firstDate.value.substring(isplit + 1);

	isplit = secondDate.value.indexOf('/');
	s2Month = secondDate.value.substring(0, isplit);
	isplit = secondDate.value.indexOf('/', isplit + 1);
	s2Day = secondDate.value.substring((s2Month.length + 1), isplit);
	s2Year = secondDate.value.substring(isplit + 1);

	date1 = new Date(s1Year, s1Month - 1, s1Day);
	date2 = new Date(s2Year, s2Month - 1, s2Day);

	if (date1 < date2)
		return -1 * Math.round(.51 + (date2 - date1) / 31536000000);

	if (date1 > date2)
		return 1;
	else
		return 0;
}
// Compares two dates in format 01/01/1999 and returns -1 if first one less, 0 if same, 
// and 1 if second greater.  Returns -999 if firstDate has error, +999 if second has error
// if firstDate < secondDate function returns the number of years as negative
function errCompareDates(firstDate, secondDate) {
	if (firstDate.value.length > 0) {
		isplit = firstDate.value.indexOf('/');
		if (isplit == -1 || isplit == firstDate.value.length)
			return -999;
		s1Month = firstDate.value.substring(0, isplit);
		isplit = firstDate.value.indexOf('/', isplit + 1);
		if (isplit == -1 || (isplit + 1) == firstDate.value.length)
			return -999;
		s1Day = firstDate.value.substring((s1Month.length + 1), isplit);
		s1Year = firstDate.value.substring(isplit + 1);
		if (!(isYear(s1Year, false) && isMonth(s1Month, false) && isDay(s1Day, false)))
			return -999;
		var intYear = parseInt(s1Year, 10);
		var intMonth = parseInt(s1Month, 10);
		var intDay = parseInt(s1Day, 10);
		if (intDay > daysInMonth[intMonth])
			return -999;
		if ((intMonth == 2) && (intDay > daysInFebruary(intYear)))
			return -999;
		date1 = new Date(s1Year, s1Month - 1, s1Day);
	}
	if (secondDate.value.length > 0) {
		isplit = secondDate.value.indexOf('/');
		if (isplit == -1 || isplit == secondDate.value.length)
			return 999;
		s2Month = secondDate.value.substring(0, isplit);
		isplit = secondDate.value.indexOf('/', isplit + 1);
		if (isplit == -1 || isplit == secondDate.value.length)
			return 999;
		s2Day = secondDate.value.substring((s2Month.length + 1), isplit);
		s2Year = secondDate.value.substring(isplit + 1);
		if (!(isYear(s2Year, false) && isMonth(s2Month, false) && isDay(s2Day, false)))
			return 999;
		var intYear = parseInt(s2Year, 10);
		var intMonth = parseInt(s2Month, 10);
		var intDay = parseInt(s2Day, 10);
		if (intDay > daysInMonth[intMonth])
			return 999;
		if ((intMonth == 2) && (intDay > daysInFebruary(intYear)))
			return 999;
		date2 = new Date(s2Year, s2Month - 1, s2Day);
	}
	if ((firstDate.value.length > 2) && (secondDate.value.length > 2)) {
		if (date1 < date2)
			return -1 * Math.round(.51 + (date2 - date1) / 31536000000);
		if (date1 > date2)
			return 1;
	}
	return 0;
}


/*******************************************************************
*                 PICK LISTS                                       *
*                                                                  *
*                                                                  *
*******************************************************************/
// GetPickList returns the value from a single selection SELECT list
function GetPickList(thelist) {
	var PickList = '';
	for (var i = 0; i < thelist.length; i++) {
		if (thelist.options[i].selected) {
			PickList = thelist.options[i].value;
			return PickList;
		}
	}
	return PickList;
}

// GetPickListText returns the Text from a single selection SELECT list
function GetPickListText(thelist) {
	var PickList = '';
	for (var i = 0; i < thelist.length; i++) {
		if (thelist.options[i].selected) {
			PickList = thelist.options[i].text;
			return PickList;
		}
	}
	return PickList;
}

// Check to see if the default item is selected
function ItemSelected(thelist) {
	for (var i = 0; i < thelist.length; i++) {
		if (thelist.options[i].selected)
			return i;
	}
	return -1;
}
// Sets specific value in list
function setPickList(thelist, thevalue) {
	for (var i = 0; i < thelist.length; i++) {
		if (thelist.options[i].value == thevalue) {
			thelist.options[i].selected = true;
			break;
		}
	}
}
// Sets specific value in list
function setPickListMulti(thelist, thevalue) {
	// first clear all previously selected options
	for (var i = 0; i < thelist.length; i++) {
		thelist.options[i].selected = false;
	}
	for (var i = 0; i < thelist.length; i++) {
		if (thelist.options[i].value == thevalue) {
			thelist.options[i].selected = true;
		}
	}
}
// Sets similar value in list used in places like quick fill 
function setPickListLike(thelist, thevalue) {
	for (var i = 0; i < thelist.length; i++) {
		var thelistvalue = thelist.options[i].value.toLowerCase();
		if (thelistvalue.substring(0, thevalue.length) == thevalue) {
			thelist.options[i].selected = true;
			break;
		}
	}
}
// Sets similar value in list
function setPickListLikeMulti(thelist, thevalue) {
	// first clear all previously selected options
	for (var i = 0; i < thelist.length; i++) {
		thelist.options[i].selected = false;
	}
	// if the value is not null then loop thru
	if (thevalue.length > 0) {
		for (var i = 0; i < thelist.length; i++) {
			var thelistvalue = thelist.options[i].value.toLowerCase();
			if (thelistvalue.substring(0, thevalue.length) == thevalue) {
				thelist.options[i].selected = true;
			}
		}
	}
}

// Returns comma delimited list of values from a MULTI-Select box 
function GetPickListMulti(thelist) {
	var picklist = "";
	for (var i = 0; i < thelist.length; i++) {
		if (thelist.options[i].selected) {
			// determine if we need to start separating with commas 
			if (picklist > "") {
				picklist += ",";
			}
			picklist += String(thelist.options[i].value);
		}
	}
	return picklist;
}
// Returns QUOTED comma delimited list of values from a MULTI-Select box 
function GetPickListMultiQuoted(thelist) {
	var picklist = "";
	for (var i = 0; i < thelist.length; i++) {
		if (thelist.options[i].selected) {
			// determine if we need to start separating with commas 
			if (picklist > "") {
				picklist += ",";
			}
			picklist += "'" + String(thelist.options[i].value) + "'";
		}
	}
	return picklist;
}
// Returns comma delimited list of text from a MULTI-Select box 
function GetPickListTextMulti(thelist) {
	var picklist = "";
	for (var i = 0; i < thelist.length; i++) {
		if (thelist.options[i].selected) {
			// determine if we need to start separating with commas 
			if (picklist > "") {
				picklist += ",";
			}
			picklist += String(thelist.options[i].text);
		}
	}
	return picklist;
}

// Removes all selected options from a MULTI-Select box 
function RemovePickListMulti(thelist) {
	var picklist = "";
	for (var i = 0; i < thelist.length; i++) {
		if (thelist.options[i].selected) {
			thelist.options[i] = null;
			// recursively call itself until all are found and removed
			RemovePickListMulti(thelist);
		}
	}
}
// Moves options FROM a multi Select box to another 
function MovePickListMulti(fromlist, tolist) {
	// create comma delim lists
	tempindex = GetPickListMulti(fromlist);
	temptext = GetPickListTextMulti(fromlist);

	// now remove the options from the fromlist
	temp = RemovePickListMulti(fromlist);

	// create arrays, loop thru and add to the tolist 
	var arrayindex = tempindex.split(",");
	var arraytext = temptext.split(",");
	var startat = tolist.length;
	for (var i = 0; i < arrayindex.length; i++) {
		var newoption = startat + i;
		tolist.options[newoption] = new Option(arraytext[i], arrayindex[i]);
	}
}

// Returns comma delimited list of ALL values from a MULTI-Select box 
function GetPickListMultiAll(thelist) {
	var picklist = "";
	for (var i = 0; i < thelist.length; i++) {
		if (picklist > "") {
			picklist += ",";
		}
		picklist += String(thelist.options[i].value);
	}
	return picklist;
}

// Returns comma delimited list of ALL text from a MULTI-Select box 
function GetPickListTextMultiAll(thelist) {
	var picklist = "";
	for (var i = 0; i < thelist.length; i++) {
		if (picklist > "") {
			picklist += ",";
		}
		picklist += String(thelist.options[i].text);
	}
	return picklist;
}

function windowpopup(url) {
	/*	this shows how to open a resizable window 
	of a particular height and width, 
	with a defined offset from the top and left, 
	displaying the status, menubar and location showing:
	*/
	//sessionwin = window.open(url,"newwindow","height=400,width=800,left=50,top=50,resizable,scrollbars,status,menubar,location,toolbar,copyhistory,directories")
	sessionwin = window.open(url, "newwindow", "height=400,width=800,left=50,top=50,resizable,scrollbars,status,menubar")
	// this shows how to refocus on the above window (so that we don't continuously open new windows)
	if (sessionwin) {
		sessionwin.focus();
	}
}

//Check  all checkboxs on the page
function checkbox_check_all(form) {
	var i;
	for (i = 0; i < form.length; i++) {
		if (form.elements[i].type == "checkbox") {
			form.elements[i].checked = true;
		}
	}
}

//un-check all checkboxs on the page
function checkbox_un_check_all(form) {
	var i;
	for (i = 0; i < form.length; i++) {
		if (form.elements[i].type == "checkbox") {
			form.elements[i].checked = false;
		}
	}
}

//Check  all checkboxs on the page who's names start with 'startwith'
function checkbox_check_all_v2(form, startswith) {
	//WARNING!! THIS code only works with classic asp.  For .NET pages, you would have to change the  " == 0" to " > 0" because .NET pages prefix the controls with the IDs from top master and containing controls etc.  ex: a checkbox named: chkSelectedStandard could be prefixed with; "ctl00_cphTop_gvAreaStandards_ctl02_"
	var i;
	for (i = 0; i < form.length; i++) {
		if (form.elements[i].type == "checkbox" && form.elements[i].name.indexOf(startswith) == 0) { 
			form.elements[i].checked = true;
		}
	}
}

//un-check all checkboxs on the page who's names start with 'startwith'
function checkbox_un_check_all_v2(form, startswith) {
	//WARNING!! THIS code only works with classic asp.  For .NET pages, you would have to change the  " == 0" to " > 0" because .NET pages prefix the controls with the IDs from top master and containing controls etc.  ex: a checkbox named: chkSelectedStandard could be prefixed with; "ctl00_cphTop_gvAreaStandards_ctl02_"
	var i;
	for (i = 0; i < form.length; i++) {
		if (form.elements[i].type == "checkbox" && form.elements[i].name.indexOf(startswith) == 0) {
			form.elements[i].checked = false;
		}
	}
}

function make_textarea_larger(objName, icols, irows) {
	var field = objName;
	var current_rows;
	var current_cols;

	current_rows = field.rows
	current_cols = field.cols

	field.rows = (current_rows + irows)
	field.cols = (current_cols + icols)
	field.focus()
}

function deleteCurriculum(id) {
	var confirm_ret;
	confirm_ret = confirm("Are you sure you want to delete this curriculum set? \n\n (WARNING: this action cannot be undone.)");
	if (confirm_ret == true) {
		window.location = "DeleteCurriculum.asp?curriculum_id=" + id;
	}
	else {
		return;
	}
}

function deleteDepartment(id) {
	var confirm_ret;
	confirm_ret = confirm("Are you sure you want to delete this department? \n\n (WARNING: this action cannot be undone.)");
	if (confirm_ret == true) {
		window.location = "DeleteDepartment.asp?department_id=" + id;
	}
	else {
		return;
	}
}
function deleteCourse(id) {
	var confirm_ret;
	confirm_ret = confirm("Are you sure you want to delete this course? \n\n (WARNING: this action cannot be undone.)");
	if (confirm_ret == true) {
		window.location = "DeleteCourse.asp?course_id=" + id;
	}
	else {
		return;
	}
}

// returns comma delim list of all values within the checkbox group (ex: getCheckBoxValues(this.form.active_ind))
function getCheckBoxValues(form, btn_name) {
	var listValues = "";
	var i;
	for (i = 0; i < form.length; i++) {
		if ((form.elements[i].type == "checkbox") && (form.elements[i].name == btn_name)) {
			if (form.elements[i].checked == true) {
				if (listValues > "") {
					listValues += ",";
				}
				listValues += form.elements[i].value;
			}

		}
	}
	return listValues;
}

function IsNumeric(sText) {
	var ValidChars = "0123456789.";
	var IsNumber = true;
	var Char;


	for (i = 0; i < sText.length && IsNumber == true; i++) {
		Char = sText.charAt(i);
		if (ValidChars.indexOf(Char) == -1) {
			IsNumber = false;
		}
	}
	return IsNumber;

}


function HideSelects() {
	var form;
	for (i = 0; i < document.forms.length; i++) {
		form = document.forms[i]
		for (j = 0; j < form.length; j++) {
			if (form.elements[j].type == "select-one") {
				form.elements[j].style.visibility = 'hidden';
			}
		}
	}
}

function ShowSelects() {
	var form;
	for (i = 0; i < document.forms.length; i++) {
		form = document.forms[i]
		for (j = 0; j < form.length; j++) {
			if (form.elements[j].type == "select-one") {
				form.elements[j].style.visibility = 'visible';
			}
		}
	}
}

function loading(text, color, load_height, load_width) {
	var loading_layer = document.createElement('div')
	loading_layer.id = 'loading_layer';

	document.getElementsByTagName('BODY')[0].appendChild(loading_layer);
	//document.appendChild(loading_layer);

	with (document.getElementById('loading_layer')) {
		style.backgroundColor = '#FFFFFF';
		style.border = 'solid 3px ' + color;
		style.textAlign = 'center';
		style.verticalAlign = 'text-bottom';

		style.height = load_height;
		style.width = load_width;

		style.position = 'absolute';

		style.top = '50%';
		style.left = '50%';

		style.top = offsetTop - offsetHeight / 2;
		style.left = offsetLeft - offsetWidth / 2;

		style.display = 'block';
	}

	var closeurl = location.href;

	document.getElementById('loading_layer').innerHTML = '' +
		'<div style="position: absolute; top: 0; left: 0; width: ' + load_width + '; height: ' + load_height + ';">' +
			'<table border="0" cellpadding="0" cellspacing="0" height="100%" width="100%">' +
				'<tr>' +
					'<td align="center" style="font: bold 15px Arial">' +
						text + '<br>' +
						'<img src="/images/loading.gif" name="loading_gif" id="loading_gif" WIDTH="220" HEIGHT="19">' +
					'</td>' +
				'</tr>' +
			'</table>' +
		'</div>' +
		'<div style="position: absolute; top: 0; left: 0; width: ' + load_width + '; height: 10px; background-color: transparent; text-align: right;">' +
			'<a href="' + closeurl + '" style="font-family: Arial; color: Black; text-decoration: none;">' +
				'X&nbsp;&nbsp;&nbsp;' +
			'</a>' +
		'</div>';

	animate_load();
}

function animate_load() {
	loading_timer = window.setTimeout('if(document.getElementById("loading_gif")){document.getElementById("loading_gif").src = "/images/loading.gif";}', 200);
}

function fakeAJAX() {
	if (typeof (window['showIFrame']) == 'undefined') {
		showIFrame = false;
	}

	args = fakeAJAX.arguments;
	var script = args[0];

	var ifrm = document.createElement('IFRAME');
	ifrm.setAttribute('src', script);
	ifrm.id = 'ifrm';
	if (showIFrame == true) {
		ifrm.style.display = 'block';
	} else {
		ifrm.style.display = 'none';
	}
	document.body.appendChild(ifrm);

	var returnDiv = document.createElement('DIV');
	returnDiv.id = 'returnVal';

	returnDiv.style.display = 'none';

	returnDiv.innerHTML = '-1';
	document.body.appendChild(returnDiv);

	var FAStatus = document.createElement('DIV');
	FAStatus.id = 'FAStatus';
	FAStatus.style.display = 'none';
	returnDiv.innerHTML = '0';
	document.body.appendChild(FAStatus);

	var myCmd = 'if(document.getElementById(FAStatus.id).innerHTML=="1"){clearInterval(myInterval);fakeAJAXstep2("' + ifrm.id + '", "' + returnDiv.id + '", "' + FAStatus.id + '"';
	for (i = 1; i < args.length; i++) {
		myCmd += ', args[' + i + ']';
	}
	myCmd += ');}'

	//alert(myCmd);
	myInterval = setInterval(myCmd, 100);
}

function fakeAJAXstep2() {
	args = fakeAJAXstep2.arguments;
	var ifrm = document.getElementById(args[0]);
	var returnDiv = document.getElementById(args[1]);
	var FAStatus = document.getElementById(args[2]);
	var returnVal = returnDiv.innerHTML;

	if (showIFrame != true) {
		document.body.removeChild(ifrm);
	}

	document.body.removeChild(returnDiv);
	document.body.removeChild(FAStatus);

	var myCmd = args[3] + '("' + returnVal + '"';
	for (i = 4; i < args.length; i++) {
		myCmd += ', args[' + i + ']';
	}
	myCmd += ');';
	//alert(myCmd);
	setTimeout(myCmd, 1);
}

var BrowserDetect = {
	init: function() {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function(data) {
		for (var i = 0; i < data.length; i++) {
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function(dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
	},
	dataBrowser: [
		{ string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS: [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();

function getIndex(field) {
	var elms = field.form.elements;
	for (var i = 0; i < elms.length; i++)
		if (elms[i] == field)
		return i;
	return -1;
}

function moveUpDown(e, currentField) {
	var evt;
	var form = currentField.form;
	var elms = form.elements;

	if (window.event)
		evt = e.keyCode;
	else if (e.which)
		evt = e.which;

	var fieldIndex;
	if (evt == 38 || evt == 40)
		fieldIndex = getIndex(currentField);

	var fieldName
	fieldName = currentField.name.substring(0, currentField.name.lastIndexOf('_'));

	var newField
	switch (evt) {
		case 38: //up
			for (i = fieldIndex - 1; i > 0; i--) {
				if (elms[i].name.substring(0, fieldName.length) == fieldName && elms[i].type != 'hidden') {
					newField = form.elements[i];
					i = 0;
				}
			}
			break;
		case 40: //down
			for (i = fieldIndex + 1; i < form.length; i++) {
				if (elms[i].name.substring(0, fieldName.length) == fieldName && elms[i].type != 'hidden') {
					newField = form.elements[i];
					i = form.length;
				}
			}
			break;
		default:
			return true;
			break;
	}

	if (newField) {
		newField.focus();
		newField.select();
	}
	return false;
}

function createPopUpUrl(url, title) {
	if (parent != self) {
		parent.createPopUpUrl(url, title, arguments[2], arguments[3]);
	} else {
		var now = new Date();
		var div_id = 'puIFrameDiv_' + now.getTime();
		var iframe_blocker_id = 'puIFrameBlockerDiv_' + now.getTime();
		var iframe_id = 'puIFrame_' + now.getTime();
		var buttons_div_id = 'puIFrameDivButtons_' + now.getTime();
		//$('<div id="' + div_id + '" style="background: white; padding: 0; position: relative;"><div id="' + iframe_blocker_id + '" style="overflow: hidden; position: absolute; top: 0; left: 0; width: 0; height: 0;"></div><iframe id="' + iframe_id + '" name="' + iframe_id + '" src="' + url + '" style="height: 100%; width: 100%; border: none;" frameborder="no"></iframe></div>').appendTo($('#content_container')).hide()
		$('<div id="' + div_id + '" style="background: white; padding: 0; position: relative;"><div id="' + iframe_blocker_id + '" style="overflow: hidden; position: absolute; top: 0; left: 0; width: 0; height: 0;"></div><iframe id="' + iframe_id + '" name="' + iframe_id + '" src="" style="height: 100%; width: 100%; border: none;" frameborder="no"></iframe></div>').appendTo($('#content_container')).hide()
		createPopUp({
			  div_id		: div_id
			, title			: title
			, width			: arguments[2]
			, height		: arguments[3]
			, onBeforeClose	: function() {
				//$('#' + iframe_id)[0].src = '';
				$('#' + iframe_id).remove();
			}
		});
		$('#' + iframe_id)[0].src = url;

		// Resize issues: if you have an IFrame and you try to resize it, the moment you move the mouse you can potentially
		// enter or leave the IFrame.  This code puts a DIV on top of the IFrame, then resizes the DIV to match the IFrame.
		// When you're done resizing, the DIV gets resized to zero.  Likewise with moving the IFrame.
		$popup = $('#' + div_id);
		$popup.dialog('option', 'resizeStart', function() {
			$('#' + iframe_blocker_id).height($('#' + iframe_id).height());
			$('#' + iframe_blocker_id).width($('#' + iframe_id).width());
		});

		$popup.dialog('option', 'resize', function() {
			$('#' + iframe_blocker_id).height($('#' + iframe_id).height());
			$('#' + iframe_blocker_id).width($('#' + iframe_id).width());
		});

		$popup.dialog('option', 'resizeStop', function() {
			$('#' + iframe_blocker_id).height(0);
			$('#' + iframe_blocker_id).width(0);
		});

		$popup.dialog('option', 'dragStart', function() {
			$('#' + iframe_blocker_id).height($('#' + iframe_id).height());
			$('#' + iframe_blocker_id).width($('#' + iframe_id).width());
		});

		$popup.dialog('option', 'drag', function() {
			$('#' + iframe_blocker_id).height($('#' + iframe_id).height());
			$('#' + iframe_blocker_id).width($('#' + iframe_id).width());
		});

		$popup.dialog('option', 'dragStop', function() {
			$('#' + iframe_blocker_id).height(0);
			$('#' + iframe_blocker_id).width(0);
		});

		var $thisTitleBar = $('#ui-dialog-title-' + div_id).parent();
		var $thisCloseButton = $thisTitleBar.find('.ui-dialog-titlebar-close')

		$thisCloseButton.clone(false).removeClass('ui-dialog-titlebar-close').addClass('ui-dialog-titlebar-help').appendTo($thisTitleBar);
		$thisCloseButton.clone(false).removeClass('ui-dialog-titlebar-close').addClass('ui-dialog-titlebar-maximize').appendTo($thisTitleBar);
		$thisCloseButton.clone(false).removeClass('ui-dialog-titlebar-close').addClass('ui-dialog-titlebar-refresh').appendTo($thisTitleBar);
		$thisCloseButton.clone(false).removeClass('ui-dialog-titlebar-close').addClass('ui-dialog-titlebar-print').appendTo($thisTitleBar);

		var $thisHelpButton = $thisTitleBar.find('.ui-dialog-titlebar-help');
		$thisHelpButton.find('span').removeClass('ui-icon-closethick').addClass('ui-icon-help').html('Help');
		$thisHelpButton.mouseover(function() {
			$thisHelpButton.addClass('ui-state-hover');
		});
		$thisHelpButton.mouseout(function() {
			$thisHelpButton.removeClass('ui-state-hover');
		});
		$thisHelpButton.click(function() {
			popupLoadHelp(iframe_id);
			return false;
		});
		$thisHelpButton.attr('alt', 'Help');
		$thisHelpButton.attr('title', 'Help');

		var $thisMaximizeButton = $thisTitleBar.find('.ui-dialog-titlebar-maximize');
		$thisMaximizeButton.find('span').removeClass('ui-icon-closethick').addClass('ui-icon-newwin').html('Maximize');
		$thisMaximizeButton.mouseover(function() {
			$thisMaximizeButton.addClass('ui-state-hover');
		});
		$thisMaximizeButton.mouseout(function() {
			$thisMaximizeButton.removeClass('ui-state-hover');
		});
		$thisMaximizeButton.click(function() {
			window.open($('#' + iframe_id)[0].contentWindow.location.href);
			$('#' + iframe_id)[0].src = '';
			//$('#' + div_id).dialog('destroy');
			removePopUp(0 ,0 , div_id);
			return false;
		});
		$thisMaximizeButton.attr('alt', 'Open in New Window/Tab');
		$thisMaximizeButton.attr('title', 'Open in New Window/Tab');

		var $thisRefreshButton = $thisTitleBar.find('.ui-dialog-titlebar-refresh');
		$thisRefreshButton.find('span').removeClass('ui-icon-closethick').addClass('ui-icon-arrowrefresh-1-e').html('Refresh');
		$thisRefreshButton.mouseover(function() {
			$thisRefreshButton.addClass('ui-state-hover');
		});
		$thisRefreshButton.mouseout(function() {
			$thisRefreshButton.removeClass('ui-state-hover');
		});
		$thisRefreshButton.click(function() {
			$('#' + iframe_id).attr('src', $('#' + iframe_id)[0].contentWindow.location.href);
			return false;
		});
		$thisRefreshButton.attr('alt', 'Refresh');
		$thisRefreshButton.attr('title', 'Refresh');

		var $thisPrintButton = $thisTitleBar.find('.ui-dialog-titlebar-print');
		$thisPrintButton.find('span').removeClass('ui-icon-closethick').addClass('ui-icon-print').html('Print');
		$thisPrintButton.mouseover(function() {
			$thisPrintButton.addClass('ui-state-hover');
		});
		$thisPrintButton.mouseout(function() {
			$thisPrintButton.removeClass('ui-state-hover');
		});
		$thisPrintButton.click(function() {
			window.frames[iframe_id].focus();
			window.frames[iframe_id].print();
			return false;
		});		
		$thisPrintButton.attr('alt', 'Print');
		$thisPrintButton.attr('title', 'Print');
	}
}


function DoPopUpAsyncPostBack(action_id, value_id, action, value, postback_call) {
	$('#' + action_id).val(action);
	$('#' + value_id).val(value);
	postback_call();
}

function createServerPopUp(div_id, title, height, width, action_id, value_id, postback_call) {
	createPopUp(div_id, title, height, width, function() {
		$('#' + div_id).remove();
		DoPopUpAsyncPostBack(action_id, value_id, 'closePopup', '', postback_call);
	});
}

function createPopUp(div_id, title) {
	/* Optional Arguments */

	/*Demensions*/
	//Argument 3 = width [string]
	//Argument 4 = height [string]
	//Note excepts % (default) or px (string 'px' required)

	//Argument 5 = onClose [function]

	//Argument 6 = helpcode [string]

	//Argument 7 = Fully Destroy [boolean]

	//Argument 8 = HeaderSpacing
	
	//Argument 9 = onResize [function]
	
	$('body').css('overflow', 'hidden');
	var width = arguments[2];
	var height = arguments[3];
	var popup_onclose = arguments[4];
	var help_code = arguments[5];
	var fully_destroy = arguments[6];
	var header_spacing = arguments[7];
	var popup_onresize = arguments[8];
	var popup_onbeforeclose;
	
	var options;
	if (typeof div_id === 'object') {
		options = div_id;
		div_id = options.div_id;
		title = options.title;
		width = options.width;
		height = options.height;
		popup_onclose = options.onClose;
		help_code = options.help_code;
		fully_destroy = options.fullyDestroy;
		header_spacing = options.headerSpacing;
		popup_onresize = options.onResize;
		popup_onbeforeclose = options.onBeforeClose;
	}
	
	var $popup = $('#' + div_id)
	var $popupparent = $popup.parent()
	
	if (typeof (header_spacing) == 'undefined') {
		header_spacing = true;
	}
	
	// "Pop-up" here is not a pop-up window, but rather a DIV that is styled to look and act like a popup.
	$popup.dialog({
		autoOpen: false
		, modal: true
		, position: 'center'
		, hide: 'fold'
		, title: 'PerformancePlus - ' + title
		, closeText: 'close'
		, open: function() {
			// jQueryUI moves content out of the form tag and puts it at the end of the page.  This breaks .NET's postback
			// mechanism, so here we're checking if this is an ASPX page.  If it is, artificially tack the popup to be the
			// last element of the parent window's form - now we have access to the .NET structure.
			if (window.location.pathname.indexOf('.aspx') >= 0) {
				$popup.parent().appendTo('form');
			}
			// Any control buttons or such that need to scroll along with the page contents.
			setupPopUpHeader($popup);
			if ($popup.find('.ui-dialog-header').length > 0 && header_spacing) {
				$popup.css('padding-top', '55px');
			}
			if ($.browser.msie) {
				$popup.dialog('option', 'width', ($popup.width() * 1 + 20) + 'px');
			}
		}
		, beforeclose: function(evt, ui) {
			if (typeof (tinyMCE) != 'undefined') {
				$popup.find('textarea:tinymce').each(function() {
					tinyMCE.execCommand('mceRemoveControl', false, this.id);
				});
			}
			(typeof popup_onbeforeclose === 'function') && popup_onbeforeclose(evt, ui);
		}
		, close: function() {
			if (typeof ($visSelects) != 'undefined') {
				$visSelects.show();
			}
			$('body').css('overflow', 'auto');
			$(window).unbind('resize');
			$popup.dialog('destroy');
			if (typeof (popup_onclose) == 'function') {
				popup_onclose();
			}
			if (fully_destroy) {
				$popup.remove();
			}
		}
		, resize: function() {
			setupPopUpHeader($popup);
			if (typeof (popup_onresize) == 'function') {
				popup_onresize();
			}
		}
	});

	$popup.scroll(function() {
		setupPopUpHeader($popup);
	});

	if ($.browser.safari) {
		$popup.dialog('option', 'show', null);
	}

	if (setPopUpDems(div_id, width, height)) {
		$(window).resize(function() {
			setPopUpDems(div_id, width, height);
			setupPopUpHeader($popup);
		});
	} else {
		$(window).resize(function() {
			$popup.dialog('option', 'position', 'center');
			setupPopUpHeader($popup);
		});
	}

	$popup.css({ overflow: 'auto' });

	if (typeof (help_code) == 'string') {
		var $thisTitleBar = $('#ui-dialog-title-' + div_id).parent();
		var $thisCloseButton = $thisTitleBar.find('.ui-dialog-titlebar-close')

		$thisCloseButton.clone(false).removeClass('ui-dialog-titlebar-close').addClass('ui-dialog-titlebar-help').appendTo($thisTitleBar);

		var $thisHelpButton = $thisTitleBar.find('.ui-dialog-titlebar-help');
		$thisHelpButton.find('span').removeClass('ui-icon-closethick').addClass('ui-icon-help').html('Help');
		$thisHelpButton.mouseover(function() {
			$thisHelpButton.addClass('ui-state-hover');
		});
		$thisHelpButton.mouseout(function() {
			$thisHelpButton.removeClass('ui-state-hover');
		});
		$thisHelpButton.click(function() {
			loadHelp(window.location.pathname, helpcode);
			return false;
		});
	}

	if ($.browser.msie && $.browser.version < 7) {
		$('.ui-widget-overlay').css({
			background: 'url(/images/overlay.gif) repeat'
		});
		$visSelects = $('select:visible').hide();
	}
	if (typeof (Sys) != 'undefined') {
		if (Sys.WebForms.PageRequestManager.getInstance()) {
			var prm = Sys.WebForms.PageRequestManager.getInstance();
			prm.add_endRequest(function() {

			});
		}
	}
	$popup.dialog('open');
	
	var $thisTitleBar = $('#ui-dialog-title-' + div_id).parent();
	var $thisCloseButton = $thisTitleBar.find('.ui-dialog-titlebar-close');
	$thisCloseButton.attr('alt', 'Close (Esc)')
	$thisCloseButton.attr('title', 'Close (Esc)');
}

function setupPopUpHeader($popup) {
	$popup.find('.ui-dialog-header').css({
		position: 'absolute',
		paddingTop: '20px',
		display: 'block',
		top: $popup.scrollTop(),
		left: $popup.scrollLeft(),
		zIndex: 60000,
		width: $popup.width(),
		borderBottom: 'solid 1px #C0C0C0'
	});
}

function setPopUpDems(div_id, width, height) {
	var puWidth = 0;
	var puHeight = 0;
	var percentage = true;

	if (typeof (width) != 'undefined') {
		puWidth = width + '';
	} else {
		puWidth = '80%';
	}

	if (puWidth.indexOf('px', 0) > 0 || puWidth == 'auto') {
		puWidth = puWidth.replace('px', '');
		percentage = false
	} else {
		puWidth = puWidth.replace('%', '');
		puWidth = $(window).width() * puWidth / 100;
	}

	if (typeof (height) != 'undefined') {
		puHeight = height + '';
	} else {
		puHeight = '80%';
	}
	if (puHeight.indexOf('px', 0) > 0 || puHeight == 'auto') {
		puHeight = puHeight.replace('px', '');
		percentage = false
	} else {
		puHeight = puHeight.replace('%', '');
		puHeight = $(window).height() * puHeight / 100;
	}

	if (puWidth != 'auto') puWidth = puWidth * 1;
	if (puHeight != 'auto') puHeight = puHeight * 1;

	$popup = $('#' + div_id);
	$popup.dialog('option', 'width', puWidth).dialog('option', 'height', puHeight).dialog('option', 'position', 'center');
	if (puHeight != 'auto') {
		$popup.height(puHeight - 23)
	}
	if (puWidth != 'auto') {
		$popup.width(puWidth);
	}

	$popup.css({ width: 'auto' });
	$('.ui-dialog').css({ height: 'auto' });

	return percentage;
}

function LoadMapPopUp(UnitID, lea_id, MonthID, school_year, MapID, CourseID, teacher_id, /*optional*/searchText) {
	$('<div id="dummy"></div>').hide().appendTo($('body'));
	currentUnitID = UnitID;
	if (typeof (LoadMap) == 'function') {
		LoadMap({
			container_id: 'dummy'
			, lea_id: lea_id
			, month_id: MonthID
			, school_year: school_year
			, map_id: MapID
			, CourseID: CourseID
			, teacher_id: teacher_id
			, read_only: true
			, onDone: createUnitPopUp
			, searchText: searchText
		});
	}
}
function createUnitPopUp() {
	createPopUp('dummy', currentUnitID, '80', '80', function() {
		$('#dummy').remove();
	});
}
/*
function createPopUp(div_id, title) {
overlay = document.createElement('div');
overlay.id = 'overlay';
$(overlay).addClass('popup_' + div_id);
scrollx = getScrollXY('x');
scrolly = getScrollXY('y');
window.scrollTo(0, 0);

popup = document.createElement('table');
popup.id = 'popup';
$(popup).addClass('popup_' + div_id);
popup.cellPadding = 0;
popup.cellSpacing = 0;
if (typeof (arguments[2]) != 'undefined') {
popup.style.width = ($(window).width() * arguments[2] / 100) + 'px';
popup.style.left = ($(window).width() * (100 - arguments[2]) / 100) / 2 + 'px';

popup.style.height = ($(window).height() * arguments[2] / 100) + 'px';
popup.style.top = ($(window).height() * (100 - arguments[2]) / 100) / 2 + 'px';
}
if (typeof(arguments[3]) != 'undefined') {
popup.style.height = ($(window).height() * arguments[3] / 100) + 'px';
popup.style.top = ($(window).height() * (100 - arguments[3]) / 100) / 2 + 'px';
}

popup_body = document.createElement('tbody');
popup_body.style.height = '100%';
	
popup_title_row = document.createElement('tr');
popup_title = document.createElement('td');
popup_title.id = 'popup_title';
popup_title.innerHTML = '<table style="width: 100%; height: 23px;" cellpadding="0" cellspacing="0">' +
'	<tr>' +
'		<td>' +
'			PerformancePlus - ' + title +
'		</td>' +
'		<td style="text-align: right;">' +
'			<img src="/images/close.gif" class="clickable" onclick="removePopUp(' + scrollx + ', ' + scrolly + ', \'' + div_id + '\');" />' +
'		</td>' +
'	</tr>' +
'</table>';
popup_title_row.appendChild(popup_title);
popup_body.appendChild(popup_title_row);

popup_content_row = document.createElement('tr');
popup_content_cell = document.createElement('td');
popup_content_cell.id = 'popup_content_cell';
popup_content_cell.style.height = popup.style.height.replace('px', '') - 23 + 'px';
popup_content_cell.style.verticalAlign = 'top';
popup_content_cell.style.border = 'solid 1px red';
popup_content = document.createElement('div');
popup_content.id = 'popup_content';
popup_content_cell.appendChild(popup_content);
popup_content_row.appendChild(popup_content_cell);
popup_body.appendChild(popup_content_row);
$(popup_content).css({
backgroundColor: '#FFFFFF'
});
popup.appendChild(popup_body);

document.body.appendChild(overlay);
document.body.appendChild(popup);
//document.body.style.overflow = 'hidden';

if ($.browser.msie && $.browser.version < 7) {
overlay.style.background = 'url(/images/overlay.gif)';
$('select').hide();
}

makePopUpVisible(popup, overlay, $(popup).height(), $(popup).width());
$(window).resize(function() {
makePopUpVisible(popup, overlay, $(popup).height(), $(popup).width());
});
	
$('#' + div_id).remove().appendTo(popup_content);
$('#' + div_id).css('display', 'block');
}

function makePopUpVisible(popup, overlay, orig_height, orig_width) {
if ($(popup).height() >= $(overlay).height()) {
$(popup).height($(overlay).height());
$(popup).css('top', 0);
} else {
$(popup).height(orig_height);
$(popup).css('top', ($(overlay).height() - $(popup).height()) / 2);
}
$(popup).find('#popup_content').height(($(popup).height() - 23) + 'px');
$(popup).find('#popup_content_cell').height(($(popup).height() - 23) + 'px');
if ($(popup).width() >= $(overlay).width()) {
$(popup).width($(overlay).width());
$(popup).css('left', 0);
} else {
$(popup).height(orig_width);
$(popup).css('left', ($(overlay).width() - $(popup).width()) / 2);
}
$(popup).find('#popup_content').width($(popup).width() + 'px');
$(popup).find('#popup_content_cell').width($(popup).width() + 'px');
$(popup).find('#popup_content').css('overflow', 'auto');
}

function createPopUpUrl(url, title) {
overlay = document.createElement('div');
overlay.id = 'overlay';
scrollx = getScrollXY('x');
scrolly = getScrollXY('y');
window.scrollTo(0, 0);
				
popup = document.createElement('table');
popup.id = 'popup';
popup.cellPadding = 0;
popup.cellSpacing = 0;
if (arguments[2]) {
popup.style.width = arguments[2] + '%';
popup.style.left = (100 - arguments[2])/2 + '%';
		
popup.style.height = arguments[2] + '%';
popup.style.top = (100 - arguments[2])/2 + '%';
}
if (arguments[3]) {
popup.style.height = arguments[3] + '%';
popup.style.top = (100 - arguments[3])/2 + '%';
}
	
popup_body = document.createElement('tbody');
	
popup_title_row = document.createElement('tr');
popup_title = document.createElement('td');
popup_title.id = 'popup_title';
popup_title.innerHTML = '<table style="width: 100%; height: 23px;" cellpadding="0" cellspacing="0">' +
'	<tr>' +
'		<td>' +
'			PerformancePlus - ' + title +
'		</td>' +
'		<td style="text-align: right;">' +
'			<image src="/images/print.gif" class="clickable" onclick="printPopUpIframe();" />&nbsp;&nbsp;' +
'			<image src="/images/refresh.gif" class="clickable" onclick="reloadPopUp(\'' + url + '\', ' + scrollx + ', ' + scrolly +');" />&nbsp;&nbsp;' +
'			<image src="/images/maximize.gif" class="clickable" onclick="realPopUp(\'' + url + '\', ' + scrollx + ', ' + scrolly +');" />&nbsp;&nbsp;' +
'			<image src="/images/help.gif" class="clickable" onclick="popupLoadHelp();" />&nbsp;&nbsp;' + 
'			<image src="/images/close.gif" class="clickable" onclick="removePopUp(' + scrollx + ', ' + scrolly +');" />' +
'		</td>' +
'	</tr>' +
'</table>';
popup_title_row.appendChild(popup_title);
popup_body.appendChild(popup_title_row);
	
popup_content_row = document.createElement('tr');
popup_content = document.createElement('td');
popup_content.id = 'popup_content';
popup_content.style.height = '100%';
newiframe = document.createElement('iframe');
newiframe.id = 'popup_iframe';
newiframe.name = 'popup_iframe';
newiframe.border = '0';
newiframe.frameBorder = '0';
newiframe.height = "100%";
newiframe.width = "100%";
newiframe.src = url;
popup_content.appendChild(newiframe);
popup_content_row.appendChild(popup_content);
popup_body.appendChild(popup_content_row);
	
popup.appendChild(popup_body);
	
document.body.appendChild(overlay);
document.body.appendChild(popup);
document.body.style.overflow = 'hidden';
}
*/
function popupLoadHelp() {
	var popup_id = 'popup_iframe';
	if (typeof (arguments[0]) != 'undefined') {
		popup_id = arguments[0];
	}

	var myIframe = document.getElementById(popup_id);
	if (myIframe) {
		var url = myIframe.contentWindow.location.href;
		url = url.replace('http://', '').replace('https://', '')
		url = url.substring(url.indexOf('/'), url.indexOf('?') == -1 ? url.length - 1 : url.indexOf('?'))
		loadHelp(url, '');
	}
}

function removePopUp(scrollx, scrolly) {
	if (arguments[2]) { //close a individual popup is specified
		$('#' + arguments[2]).dialog('close');
	} else { //close all popups
		$('.ui-dialog-content').dialog('close');
	}
	//    if (arguments[2]) {
	//        $('.popup_' + arguments[2]).remove();        
	//    } else {
	//        if (document.getElementById('overlay')) {
	//            document.body.removeChild(document.getElementById('overlay'));
	//        }
	//        if (document.getElementById('popup')) {
	//            document.body.removeChild(document.getElementById('popup'));
	//        }
	//    }
	//    if ($('#overlay').length == 0) {
	//        document.body.style.overflow = 'auto';

	//        window.scrollTo(scrollx, scrolly);

	//        if ($.browser.msie && $.browser.version < 7) {
	//            $('select').show();
	//        }
	//    }
}

function realPopUp(url, scrollx, scrolly) {
	window.open(url);
	removePopUp(scrollx, scrolly);
}

function reloadPopUp() {
	if (document.getElementById('popup_iframe')) {
		document.getElementById('popup_iframe').src = document.getElementById('popup_iframe').src;
	}
}

function printPopUpIframe() {
	if (document.popup_iframe) {
		document.popup_iframe.focus();
		document.popup_iframe.print();
	} else if (window.frames['popup_iframe']) {
		window.frames['popup_iframe'].focus();
		window.frames['popup_iframe'].print();
	} else {
		alert('What?!?!?!?');
	}
}

function printPopUp() {
	if (document.getElementById('popup_content_div')) {
		popup_copy = document.getElementById('popup_content_div').cloneNode(true);
		popup_copy.id = 'popup_copy';
		popup_copy.style.width = '100%';
		popup_copy.style.height = '100%';
		popup_copy.style.background = 'white';
		remove_popup_div = document.createElement('div');
		remove_popup_div.id = 'remove_popup_div';
		remove_popup_button = document.createElement('input');
		remove_popup_button.id = 'remove_popup_button';
		remove_popup_button.type = 'button'
		remove_popup_button.value = 'Go Back';
		remove_popup_button.onclick = function() {
			if (document.getElementById('popup_copy')) {
				document.getElementById('popup_copy').parentNode.removeChild(document.getElementById('popup_copy'));
			}
			if (document.getElementById('popup')) {
				document.getElementById('popup').style.display = 'table';
			}
			if (document.getElementById('overlay')) {
				document.getElementById('overlay').style.display = 'block';
			}
			if (document.getElementById('title_banner')) {
				document.getElementById('title_banner').style.display = 'block';
			}
			if (document.getElementById('primary_nav')) {
				document.getElementById('primary_nav').style.display = 'block';
			}
			document.body.style.overflow = 'none';
			if (document.getElementById('content_container')) {
				document.getElementById('content_container').style.display = 'block';
			}
		}
		remove_popup_div.appendChild(remove_popup_button);
		popup_copy.insertBefore(remove_popup_div, popup_copy.firstChild)

		if (document.getElementById('overlay')) {
			document.getElementById('overlay').style.display = 'none';
		}
		if (document.getElementById('popup')) {
			document.getElementById('popup').style.display = 'none';
		}
		if (document.getElementById('title_banner')) {
			document.getElementById('title_banner').style.display = 'none';
		}
		if (document.getElementById('primary_nav')) {
			document.getElementById('primary_nav').style.display = 'none';
		}
		document.body.style.overflow = 'auto';
		if (document.getElementById('content_container')) {
			document.getElementById('content_container').style.display = 'none';
			document.getElementById('content_container').parentNode.insertBefore(popup_copy, document.getElementById('content_container').nextSibling);
			window.print();
		}
	}
}


function getScrollXY(axis) {
	var scrOfX = 0, scrOfY = 0;
	if (typeof (window.pageYOffset) == 'number') {
		//Netscape compliant
		scrOfY = window.pageYOffset;
		scrOfX = window.pageXOffset;
	} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
		//DOM compliant
		scrOfY = document.body.scrollTop;
		scrOfX = document.body.scrollLeft;
	} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
		//IE6 standards compliant mode
		scrOfY = document.documentElement.scrollTop;
		scrOfX = document.documentElement.scrollLeft;
	}
	if (axis == 'x') {
		return scrOfX;
	} else if (axis == 'y') {
		return scrOfY;
	}
}


function get_cookie(cookie_name) {
	var results = document.cookie.match('(^|;) ?' + cookie_name + '=([^;]*)(;|$)');
	if (results)
		return (unescape(results[2]));
	else
		return null;
}

function set_cookie(name, value, exp_y, exp_m, exp_d, path, domain, secure) {
	//expires - (opt) value sets the date that the cookie will expire on. The date should be in the format returned by the toGMTString() method of the Date object. If the expires value is not given, the cookie will be destroyed the moment the browser is closed.
	//path - (opt) value specifies a path within the site to which the cookie applies. Only documents in this path will be able to retrieve the cookie. Usually this is left blank, meaning that only the path that set the cookie can retrieve it.
	//domain - (opt) value specifies a domain within which the cookie applies. Only websites in this domain will be able to retrieve the cookie. Usually this is left blank, meaning that only the domain that set the cookie can retrieve it.
	//secure - (opt) flag indicates that the browser should use SSL when sending the cookie to the server. This flag is rarely used.
	//document.cookie = "name=value; expires=date; path=path; domain=domain; secure";
	//document.cookie = "username=John; expires=15/02/2003 00:00:00";
	var cookie_string = name + "=" + escape(value);
	if (exp_y) {
		var expires = new Date(exp_y, exp_m, exp_d);
		cookie_string += "; expires=" + expires.toGMTString();
	}
	if (path)
		cookie_string += "; path=" + escape(path);
	if (domain)
		cookie_string += "; domain=" + escape(domain);
	if (secure)
		cookie_string += "; secure";
	document.cookie = cookie_string;
}

function getJSVersion() {
	return jsVersion;
}

function SafariIFrameFix(popupdivid) {
	var currentSrc = '';
	$('div#' + popupdivid + ' iframe').each(function() {
		currentSrc = this.src;
		this.src = '';
		this.src = currentSrc;
	});
}

function customCheckSpelling(id) {
	window.open('/ASPSpellCheck/ASPSpellCheck.asp?fields=' + id, 'aspSpellWin', 'width=460, height=290, scrollbars=no');
	return ;
}

function showLoading() {
	var msgLoading = '<div style="position: relative;"><div id="divCancelPostback" class="clickable" style="position: absolute; top: 0; right: 5px; font-size: 9px; font-weight: bold; display: none;">X</div>Loading...</div>';
	if (window.location.toString().indexOf('/messages/default.aspx', 0) > 0) {
		msgLoading = '';
	}
	$.blockUI({
		message: msgLoading,
		centerY: false,
		overlayCSS: {
			backgroundColor: '#F0F0F0',
			opacity: 0.2,
			zIndex: 60001
		},
		css: {
			width: '250px',
			top: '10px',
			left: '',
			zIndex: 60002,
			right: '10px',
			border: 'none',
			padding: '5px',
			fontWeight: 'bold',
			fontFamily: 'Arial',
			backgroundColor: '#003F62',
			'-webkit-border-radius': '10px',
			'-moz-border-radius': '10px',
			color: '#fff'
		}
	});
	$('#divCancelPostback').click(function() {
		if (Sys) {
			if (Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {
				Sys.WebForms.PageRequestManager.getInstance().abortPostBack();
			}
		}
	});
}

function setupTinyMCEs() {
	var contextElement, tinymceClass, currentVersionPath, $taCollection, options, onComplete,
		delayEditorDisplay, mceOptions, resizable, minHeight, maxHeight, minWidth, maxWidth,
		enabled, spellCheckWindow, handles,
		stopNextEditorBlur = false,
		spellChecking = function () {
			return spellCheckWindow ? !spellCheckWindow.closed : false;
		},
		tinyMCEPath = '/include/tinymce_3.4.2/',
		withDelay = function () {

			$taCollection
				.addClass('mce_converted')
				.wrap('<div style="position: relative;"></div>')
			//affectively "hides" the text area to account for small browser discrepancies
				.css({
					border: 0,
					color: 'white !important',
					resize: 'none',
					overflow: 'hidden'
				})
				.focus(function () {
					renderEditor($(this));
				})
				.change(function () {
					var $ta = $(this);
					$ta.parent().find('> div.edContent').html($ta.val());
				})
				.each(function (i, elem) {
					var $ta = $(elem),
						$taParent = $ta.parent(),
						taHeight = $ta.height(),
						taWidth = $ta.width(),
						taVal = $ta.val();

					// Padding since the height and width of the resizable div is not 
					// exact.  When items are pushed up against it they may be covered
					// up.  This div is an attempt to fix that. 
					$('<div style="height: 15px;" />').insertAfter($taParent);

					$taParent
						.width(taWidth)
						.height(taHeight)
						.append(
							$('<div />', {
								css: {
									backgroundColor: '#FFFFFF'
									, border: 'solid 1px #C0C0C0'
									, cursor: enabled ? 'text' : 'default'
									, height: taHeight - 14
									, left: 0
									, overflow: 'auto'
									, padding: '7px'
									, position: 'absolute'
									, top: 0
									, width: taWidth - 14
								},
								html: taVal,
								click: function () {
									renderEditor($(this).parent().find('> textarea'));
								}
							}).addClass('edContent')
						);

					resizable && $taParent.resizable({
						alsoResize: $taParent.find('> div.edContent'),
						maxHeight: maxHeight,
						minHeight: minHeight,
						maxWidth: maxWidth,
						minWidth: minWidth,
						handles: handles,
						start: function (evt, ui) {
							$ta.css('visibility', 'hidden');
						},
						stop: function (evt, ui) {
							$ta
								.height(ui.size.height - 10)
								.width(ui.size.width - 10)
								.css('visibility', 'visible');
						}
					});
				});
		},
		withoutDelay = function (){
			$taCollection.tinymce(mceOptions);
		},
		renderEditor = function ($ta) {
			if (enabled && !spellChecking()) {
				$ta
					.parent()
						.resizable('disable')
						.removeClass('ui-state-disabled')
						.find('> div.edContent')
							.hide()
						.end();

				$ta.tinymce(mceOptions);

				spellChecking() && spellCheckWindow.focus();
				
				$ta.parent().scrollintoview({
					duration: 0
				});

				$ta.removeData('convertAfterResize');
			}			
		},
		blurEditor = function (ed) {
			$ta = $('#' + ed.id);
			$ta.parent()
				.resizable('enable')
				.find('> div.edContent')
					.html($ta.val())
					.show();
			ed.remove();

			$('body').unbind('.' + $ta[0].id);
		};


	if (typeof (arguments[0]) === 'object') {
		options = arguments[0];
		contextElement = options.contextElement || 'body';
		tinymceClass = options.tinymceClass || 'tinymce_basic';
		currentVersionPath = options.currentVersionPath || tinyMCEPath;
		onComplete = options.onComplete;
		delayEditorDisplay = typeof options.delayEditorDisplay === 'undefined' ? true : options.delayEditorDisplay;
		resizable = typeof options.resizable === 'undefined' ? true : options.resizable;
		minHeight = options.minHeight || 150;
		maxHeight = options.maxHeight;
		minWidth = options.minWidth;
		maxWidth = options.maxWidth;
		handles = options.handles;
		enabled = typeof options.enabled === 'undefined' ? true : options.enabled;
	} else {
		contextElement = arguments[0] || 'body';
		tinymceClass = arguments[1] || 'tinymce_basic';
		currentVersionPath = tinyMCEPath;
	}

	$taCollection = $(contextElement).find('textarea.' + tinymceClass).not('.mce_converted');

	//if the editor is disabled than force delay
	!enabled && (delayEditorDisplay = true);

	//These are the options that apply to all editors by default.
	//Type-specific overrides should be made in the the switch statement below.
	mceOptions = {
		// Location of TinyMCE script
		//script_url: '/include/tiny_mce/tiny_mce.js', //full tiny_mce file debug only
		script_url: currentVersionPath + 'tiny_mce_gzip.aspx', //compressed setup, much faster

		// General options
		theme: "advanced",
		plugins: "inlinepopups,insertdatetime,searchreplace,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,advlist,tabfocus,safari",
		paste_text_sticky: true,
		button_tile_map: true, //sends buttons down as 1 image (google "css sprite" for more info
		force_br_newlines: true,
		force_p_newlines: false,
		forced_root_block: false,
		imagemanager_contextmenu: false,
		setup: function (ed) {
			var $ta = $(ed.getElement());

			//sets editor to be the same size as the textbox it is replacing.  This allows you to set the height and width at the server
			$(ed.getContainer()).height($ta.height());
			$(ed.getContainer()).width($ta.width());

			//adds the custom spellcheck button
			ed.addButton('spellcheck', {
				title: 'Spell Check',
				'class': 'spellcheck_button',
				onclick: function () {
					stopNextEditorBlur = true;
					var targetID = 'iframe:' + $(ed.getContentAreaContainer()).find('iframe')[0].id;
					ed.focus();
					spellCheckWindow = window.open('/ASPSpellCheck/ASPSpellCheck.asp?fields=' + targetID, 'aspSpellWin', 'width=460, height=290, scrollbars=no');
					spellCheckWindow.focus();
				}
			});

			//applies the image for the spellcheck button
			ed.onInit.add(function (ed) {
				var $container = $(ed.getContainer());

				$container
					.find('.spellcheck_button')
						.css({
							backgroundPosition: '-120px -20px'
						})
					.end();

				delayEditorDisplay &&
					$('body').bind('click.' + $ta[0].id, function (evt) {
						$(evt.target).parents('span.mceEditor').length === 0 && blurEditor($ta.tinymce());
					});

				//Turns Paste as Text on by default
				ed.execCommand('mcePasteText');
			});

			delayEditorDisplay &&
				ed.onKeyDown.add(function (ed, e) {

					//about to blur
					e.keyCode === 9 && tinymce.dom.Event.add($.browser.mozilla ? ed.contentDocument : ed.contentWindow, 'blur', function (e) {
						blurEditor(ed);
					});
				});

			ed.onPostRender.add(function (ed) {
				tinymce.dom.Event.add($.browser.mozilla ? ed.contentDocument : ed.contentWindow, 'blur', function (e) {
					//onBlur

					stopNextEditorBlur = false;
				});

				tinymce.dom.Event.add($.browser.mozilla ? ed.contentDocument : ed.contentWindow, 'focus', function (e) {
					spellChecking() && spellCheckWindow.focus();
				});
			});
		},

		// Theme options
		theme_advanced_buttons1: "bold,italic,underline,strikethrough,forecolor,backcolor,|,justifyleft,justifycenter,justifyright,justifyfull,|,,bullist,numlist,|,outdent,indent,|,sub,sup,ltr,rtl",
		theme_advanced_buttons2: "newdocument,|,cut,copy,paste,pastetext,pasteword,|,removeformat,search,replace,spellcheck,|,undo,redo,|,link,unlink,cleanup,|,charmap,insertdate,inserttime,|,fullscreen",
		theme_advanced_buttons3: "",
		theme_advanced_toolbar_location: "top",
		theme_advanced_toolbar_align: "left",
		theme_advanced_statusbar_location: "none",
		theme_advanced_resizing: true,

		// Example content CSS (should be your site CSS)
		content_css: "/PerfTracker.css",
		body_class: "body_normal",
		debug: false
	};
	
	switch (tinymceClass) {
		case 'tinymce_basic':
			//mceOptions = $.extend(mceOptions, {});
			break;
		case 'tinymce_compact':
			mceOptions = $.extend(mceOptions, {
				theme_advanced_buttons1: "bold,italic,underline,forecolor,backcolor,|,justifyleft,justifycenter,justifyright,justifyfull,|,,bullist,numlist,|,outdent,indent",
				theme_advanced_buttons2: "cut,copy,paste,pastetext,pasteword,|,removeformat,spellcheck,|,undo,redo,|,link,unlink,cleanup,|,charmap,|,fullscreen"
			});
			break;

		// SJL 2/15/2011    Add "bare bones" editor, showing only a minimal subset of the available tools.  -->
		// I wish I knew more about the various options - some of them probably don't make sense for this context, but
		// I'm reluctant to remove things I don't grok.
		case 'tinymce_barebones':
			mceOptions = $.extend(mceOptions, {
				theme_advanced_buttons1: "bold,italic,underline,strikethrough,spellcheck",
				theme_advanced_buttons2: "",
				fullscreen_new_window: true
			});
			break;        // <-- SJL 2/15/2011
	}

	delayEditorDisplay ? withDelay() : withoutDelay();		

	typeof (onComplete) === 'function' && onComplete();
}

function removeTinyMCEs() {
	if (typeof (tinyMCE) != 'undefined') {
		tinyMCE.triggerSave();
	}
	return true;
}
function spsReplaceAll(Source, StringToFind, StringToReplace) {
	//replaces all occurences of the 'StringToFind' with the StringToReplace from the Source
    var temp = '';
    var index = 0;
    temp = Source.toString();
    index = temp.indexOf(StringToFind);
    while(index != -1){
       temp = temp.replace(StringToFind,StringToReplace);
       index = temp.indexOf(StringToFind);
    }
    return temp;
}

function spsRemoveTrailingBRs(Source) {
	//removes all trailing (ending) <br> and spaces from an html string
	var temp = '';
	var index = 0;
	temp = Source.toString();
	//fix all know variations of BR
	temp = spsReplaceAll(temp, '<BR>', '<br>');
	temp = spsReplaceAll(temp, '<BR/>', '<br>');
	temp = spsReplaceAll(temp, '<BR />', '<br>');
	temp = spsReplaceAll(temp, '<br/>', '<br>');
	temp = spsReplaceAll(temp, '<br />', '<br>');
	var temp_before = temp;
	var miDone = false;
	while (miDone !== true) {
		temp_before = temp;
		temp = spsRemoveTrailingCharacters(temp, ' '); //remove trailing spaces first
		temp = spsRemoveTrailingCharacters(temp, '<br>');
		if (temp_before == temp) {
			miDone = true;
		}
	}
	return temp;
}

function spsRemoveTrailingCharacters(Source, InputRemoveChar) {
	//Removes all 'trailing' characters (in the InputRemoveChar) from the Source string
	var temp = '';
	var msg = '';
	var index = 0;
	temp = Source.toString();
	var SourceOrig = temp;
	var RemoveChar = InputRemoveChar.toString();
	var miDone = false;
	var FromIndex = 0;
	var TheLength = 0;
	var MySubString = "";
	var CharChunk = "";
	var i = 0;

	if (RemoveChar.length === 0) {
		return Source;
	}
	while (miDone !== true) {
		i = i + 1;
		if (temp.length < RemoveChar.length) {
			miDone = true;
		}

		FromIndex = temp.length;
		FromIndex = FromIndex - RemoveChar.length;
		if (FromIndex > -1) {
			CharChunk = temp.substr(FromIndex, RemoveChar.length); //substr is base zero
			TheLength = (RemoveChar.length + 1);
			if (CharChunk == RemoveChar) {
				;
				temp = temp.substr(0, (temp.length - TheLength + 1)); //substr is base zero
			} else {
				miDone = true;
			}
		} else {
			miDone = true;
		}
	}
	return temp;
}
function spsGetScrollbarWidth() {
	//scroll bar width can be different depending on color scheme (any where from 13 to 21 pixels)
	//also, depending upon the font size (normal, large, extra large etc) will change width even more
	//to dynamically calculate the width of a scroll bar for a user do the following:
	var d = document.createElement("DIV");
	d.style.position = 'absolute';
	d.style.visibility = 'hidden';
	d.style.overflowY = 'scroll';
	//d.style.width = 0; //with width of zero we get scrollbar width of zero
	//document.body.insertAdjacentElement("afterBegin", d); //fails in FF
	document.body.appendChild(d);
	var scrollBarW = d.offsetWidth;
	d.parentNode.removeChild(d);
	return scrollBarW;
}

function releaseNotes(extra) {
	var sessionwin;
	url = '/help/release_notes.asp' + extra;
	windowname = 'ReleaseNotes'
	attributes = 'width=725,height=520,resizable=yes,scrollbars=yes,toolbar=no,location=no,status=no,menubar=no';

	sessionwin = window.open(url, windowname, attributes);
	
	if (sessionwin) {
		sessionwin.focus();
	}
}
