// IMPORTANT: each html file that uses this method must have a handleHttpResponse function
var xmlHttp = GetXmlHttpObject();
var g_clockId_Http = 0;
var g_aHttp = new Array();
if (typeof g_bHttpInUse == "undefined") {
	var g_bHttpInUse = false;
}
else {
	alert("g_bHttpInUse already defined");
}
function writeAjax(sUrl) {
	// document.getElementById('DebugInfo').innerHTML += sUrl + ",   g_bHttpInUse=" + g_bHttpInUse + "<br />";
	// if a real action (not the timer calling back)
	if (sUrl != '') {
		g_aHttp.push(sUrl);
	}
	
	// if already using the HTML object, then wait some time
	if (g_bHttpInUse == true) {
		// alert("delaying sUrl=" + sUrl);
		killTimer(g_clockId_Http);
		g_clockId_Http = setTimeout("writeAjax('')", 500);
		// alert("0");
		return;
	}
	
	// are there any Url's left to process?
	if (g_aHttp.length == 0) {
		// alert("g_aHttp.length=" + g_aHttp.length);
		return;
	}
	
	// ok, get the oldest one out of the array and process it
	g_bHttpInUse = true;
	sUrl = g_aHttp.pop();
	
	// alert("writeAjax: sUrl=" + sUrl);
	xmlHttp = GetXmlHttpObject();
	// alert("writeAjax: got object");
	xmlHttp.onreadystatechange=handleHttpResponse;
	// alert("writeAjax: got handle");
	xmlHttp.open("POST",sUrl,true);
	// alert("writeAjax: opened");
	xmlHttp.send(null);
	// alert("writeAjax: exiting writeAjax, xmlHttp=" + xmlHttp);
	// document.getElementById('DebugInfo').innerHTML += "Leaving writeAjax():  g_bHttpInUse=" + g_bHttpInUse + "<br />";
}

function GetXmlHttpObject() {
	var xmlHttp=null;
	try { // Firefox, Opera 8.0+, Safari
		xmlHttp=new XMLHttpRequest();
	} catch (e) {
		try { // Internet Explorer
			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e) {
			xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	return xmlHttp;
}

function killTimer(oTimer) {
	if(oTimer) {
		clearTimeout(oTimer);
		oTimer  = 0;
	}
}

function showElement(sId) {
	var oId = document.getElementById(sId);
	if (oId == null) {
		alert("Element '" + sId + "' is null in showElement(sId)");
		throw Err;
		return;
	}
	else {
		oId.style.display = "block";
	}
}

function hideElement(sId) {
	var oId = document.getElementById(sId);
	if (oId == null) {
		alert("Element '" + sId + "' is null in hideElement(sId)");
		return;
	}
	else {
		oId.style.display = "none";
	}
}

function MM_callJS(jsStr) { //v2.0
 	return eval(jsStr)
}

// isIllegalString(sStr)
function isIllegalString(sStr) {
	var sPatt1 = new RegExp("[^0-9a-zA-Z ',_-]");	// the '^' inside the bracket negates => means any characters other than the chars inside the brackets
	if (sPatt1.test(sStr)) {
		return true;	
	}
	return false;
}

//String.prototype.trim = function() {
//	return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
//};

// Removes leading whitespaces
function LTrim( value ) {
	// alert("LTrim value=" + value);
	var re = /\s*((\S+\s*)*)/;
	return value.replace(re, "$1");
	
}

// Removes ending whitespaces
function RTrim( value ) {
	// alert("RTrim value=" + value);
	var re = /((\s*\S+)*)\s*/;
	return value.replace(re, "$1");
	
}
// Removes leading and ending whitespaces
function trim( value ) {
	// alert("trim value=" + value);
	return LTrim(RTrim(value));
	
}

// returns true if the object exists
function isObject(sId) {
	var oObj = document.getElementById(sId);
	if (oObj != null) {
		return true;
	}
	return false;
}

// sets the checkbox to 'true' if sChecked = 'yes' or false otherwise
function checkCheckboxYesNo(sId, sChecked) {
	var oCheckbox = document.getElementById(sId);
	if (oCheckbox == null) {
		alert('checkCheckboxYesNo: sId=' + sId + "' does not exist");
		throw Err;
	}
	if (sChecked == 'yes') {
		oCheckbox.checked = true;
	}
	else {
		oCheckbox.checked = false;
	}
	return false;
}

// returns 'true' if the checkbox represented by the id is checked and 'false' if the it is not or if
// the object does not exist
function isCheckboxChecked(sId) {
	var oCheckbox = document.getElementById(sId);
	if (oCheckbox != null) {
		if (oCheckbox.checked) {
			return true;
		}
	}
	return false;
}

// returns 'yes' if the checkbox represented by the id is checked and 'no' if the it is not or if
// the object does not exist
function isCheckboxCheckedYesNo(sId) {
	if (isCheckboxChecked(sId)) {
		return 'yes';
	}
	return 'no';
}

// set the checkbox represented by the id to checked if sValue = 'yes' and unchecked otherwise
function setCheckboxCheckedYesNo(sId, sValue) {
	setCheckboxChecked(sId, sValue == 'yes');
}

// set the checkbox represented by the id to checked if sValue = 'true' and unchecked if 'false'
function setCheckboxChecked(sId, bValue) {
	var oCheckbox = document.getElementById(sId);
	if (oCheckbox != null) {
		oCheckbox.checked = bValue;
	}
}

// Note this function uses the NAME not the id
//function getRadioButtonValue(sId) {
//	var iDx = 1;
//	var sNextId = sId + iDx++;
//	alert("getRadioButtonValue: sNextId=" + sNextId + ",   iDx=" + iDx);
//	while (document.getElementById(sNextId) != null) {
//		if (document.getElementById(sNextId).checked) {
//			return document.getElementById(sNextId).value;
//		}
//		sNextId = sId + iDx++;
//	}
//	return 0;
//}
// Note this function uses the NAME not the id (see getRadioButtonValue(sName) below)
function isButtonSelected(sName) {
	var radioButtons = document.getElementsByName(sName);
	// alert("getRadioButtonValue: sName=" + sName + ",   radioButtons=" + radioButtons + ",   radioButtons.length=" + radioButtons.length);
	for (var i = 0; i < radioButtons.length; i ++) {
		if (radioButtons[i].checked) {
			// alert("You checked=" + radioButtons[i].id + ", with value=" + radioButtons[i].value);
			return true;
		}
	}
	return false;
}
function selectRadioButton(sId) {
	oButton = document.getElementById(sId);
	if (oButton == null) {
		alert("Error: object does not exist '" + sId + "' in selectRadioButton");
		return false;
	}
	oButton.checked = true;
	return true;
}
function getRadioButtonValue(sName) {
	var radioButtons = document.getElementsByName(sName);
	// alert("getRadioButtonValue: sName=" + sName + ",   radioButtons=" + radioButtons + ",   radioButtons.length=" + radioButtons.length);
	for (var i = 0; i < radioButtons.length; i ++) {
		if (radioButtons[i].checked) {
			// alert("You checked=" + radioButtons[i].id + ", with value=" + radioButtons[i].value);
			return radioButtons[i].value;
		}
	}
	return 0;
}

// getInnerHtml(sId)
function getInnerHtml(sId) {
	oSpan = document.getElementById(sId);
	if (oSpan == null) {
		alert("Error: object does not exist '" + sId + "' in getInnerHtml(sId)");
		return '';
	}
	return oSpan.innerHTML;
}

// setInnerHtml(sId, sStr)
function setInnerHtml(sId, sStr) {
	oSpan = document.getElementById(sId);
	if (oSpan == null) {
		alert("Error: object does not exist '" + sId + "' in setInnerHtml(sId, sStr)");
		return false;
	}
	oSpan.innerHTML = sStr;
	return true;
}
function getTextFieldText(sId) {
		oTextField = document.getElementById(sId);
		if (oTextField == null) {
			alert("Error: object does not exist '" + sId + "' in getTextFieldText");
			return false;
		}
		return oTextField.value;
}
function setTextFieldText(sId, sStr) {
		oTextField = document.getElementById(sId);
		if (oTextField == null) {
			alert("Error: object does not exist '" + sId + "' in setTextFieldText. Trying to set the field to " + sStr + "'");
			return false;
		}
		oTextField.value = sStr;
}

// clears all radio button of the radio button group
function clearButtons(buttonGroup){ 
	for (i=0; i < buttonGroup.length; i++) { 
		if (buttonGroup[i].checked == true) { 
			buttonGroup[i].checked = false 
		}
	} 
}

// returns the index of the selected text in the dropdown list, or false if no line is selected
function getSelectedIndex(sId) {
	// alert("getSelectedText(sId): sId=" + sId);
	var oList = document.getElementById(sId);
	if (oList == null) {
		alert("Error: object does not exist '" + sId + "' in getFieldText");
		return false;
	}
	var iIndex = oList.selectedIndex;
	
	// if nothing is selected
	if (iIndex < 0) {
		return false;
	}
	// ok, something selected, return it
	return iIndex;
}

// returns the text selected in the dropdown list, or false if no line is selected
// alerts if object does not exist
function getSelectedText(sId) {
	// alert("getSelectedText(sId): sId=" + sId);
	var oList = document.getElementById(sId);
	if (oList == null) {
		alert("Error: object does not exist '" + sId + "' in getFieldText");
		return false;
	}
	var iIndex = oList.selectedIndex;
	
	// if nothing is selected
	if (iIndex < 0) {
		return false;
	}
	// ok, something selected, get it
	var sText = oList.options[iIndex].text;
	return sText;
}

// returns the value of selected index in the dropdown list, or false if no line is selected
// alerts if object does not exist
function getSelectedValue(sId) {
	// alert("getSelectedText(sId): sId=" + sId);
	var oList = document.getElementById(sId);
	if (oList == null) {
		alert("Error: object does not exist '" + sId + "' in getFieldText");
		return false;
	}
	var iIndex = oList.selectedIndex;
	
	// if nothing is selected
	if (iIndex < 0) {
		return false;
	}
	// ok, something selected, get it
	var sText = oList.options[iIndex].value;
	return sText;
}

// selectIndexNumber(sId, iNumber)
// Selectes the index of the List box corresponding to the iNumber'th index
// Returns true if it finds the object, or false if it does not
function selectIndexNumber(sId, iNumber) {
	// alert("selectIndexNumber(" + sId + ", " + iNumber + ")");
	var oList = document.getElementById(sId);
	if (oList == null) {
		alert("Error: object does not exist '" + sId + "' in selectIndexNumber()");
		return false;
	}
	
	oList.selectedIndex = iNumber;
	return true;
}

// selectIndexThatEquals(sId, sStr)
// Selectes the index of the List box that has the text referred to by 'sStr'.
// Returns true if it finds the text, or false if it does not
function selectIndexThatEquals(sId, sStr) {
	return selectIndexThatEqualsOptionalError(sId, sStr, true);
}

// selectIndexThatEqualsOptionalError(sId, sStr, bReportError)
// Selectes the index of the List box that has the text referred to by 'sStr'.
// Returns true if it finds the text, or false if it does not
// If Error reporting is true, then it reports an error if it does not find the text
function selectIndexThatEqualsOptionalError(sId, sStr, bReportError) {
	// alert("selectIndexThatEquals(" + sId + ", " + sStr + ")");
	var oList = document.getElementById(sId);
	if (oList == null) {
		if (bReportError) alert("Error: object does not exist '" + sId + "' in selectIndexThatEquals()");
		return false;
	}
	
	// see if there is an exact match
	var i;
	for(i = oList.options.length - 1; i >= 0; i--){
		if (oList.options[i].text == sStr) {
			oList.selectedIndex = i;
			// alert("Found it. Selecting index " + i);
			return true;
		}
	}
	
	// give an error msg
	var sAll = '';
	for(i = oList.options.length - 1; i >= 0; i--){
		sAll += oList.options[i].text + ', ';
	}
	if (bReportError) deb("Error in selectIndexThatEquals(): sId=" + sId + ",  sStr=" + sStr + ",  sAll=" + sAll);
	// throw Err;
	return false;
}

function removeAllDropdownOptions(sId) {
	// alert("removeAllDropdownOptions: sId=" + sId);
	var oList = document.getElementById(sId);
	if (oList == null) {
		alert("Error: object does not exist '" + sId + "' in removeAllDropdownOptions");
		return false;
	}
	// alert("removeAllDropdownOptions 2");
	var i;
	for(i = oList.options.length - 1; i >= 0; i--){
		oList.remove(i);
	}
}

// Adds an option to the 'iIdx'th location of the dropdown with the id of 'sId'
// not tested
function addOption(sId, iIdx, sText) {
	var oList = document.getElementById(sId);
	if (oList == null) {
		alert("Error: object does not exist '" + sId + "' in addOption");
		return false;
	}
	oList.options[iIdx] = new Option(sText,sText);
}

// setListSize(sId, iSize)
// Adds an option to the 'iIdx'th location of the dropdown with the id of 'sId'
function setListSize(sId, iSize) {
	var oList = document.getElementById(sId);
	if (oList == null) {
		alert("Error: object does not exist '" + sId + "' in setListSize");
		return false;
	}
	oList.size = iSize;
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_showHideLayers() { //v6.0
  var i,p,v,obj,args=MM_showHideLayers.arguments;
  for (i=0; i<(args.length-2); i+=3) if ((obj=MM_findObj(args[i]))!=null) { v=args[i+2];
    if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v=='hide')?'hidden':v; }
    obj.visibility=v; }
}

// For a 2 dimensional array: Array[row][column], this method sorts by the content of 
// the column pointed to by g_iColumnToSort. It sorts in ascending order if g_bSortAscending
// is true, or in descending order otherwise.
// First, define g_iColumnToSort to be a number and g_bSortAscending to be a boolean. Then,
// invoke it with: Array.sort(sortByColumn);
var g_bSortAscending = true;
var g_iColumnToSort = 0;
function sortByColumn(a, b) {
	var x = a[g_iColumnToSort].toLowerCase();
	var y = b[g_iColumnToSort].toLowerCase();
	if (g_bSortAscending) 
		return ((x < y) ? -1 : ((x > y) ? 1 : 0));
	else
		return ((x < y) ? 1 : ((x > y) ? -1 : 0));
}

// numeric sort or an array
// example of use: document.writeln([5,8,12,50,25,80,93].sortNum()); // outputs 5,8,12,25,50,80,93
// Array.prototype.sortNum = function() {   return this.sort( function (a,b) { return a-b; } );}

// Array.shuffle() takes the contents of the array and randomizes them
// example of use: var myArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];myArray.shuffle();document.writeln(myArray); 
// outputs~: 8,1,13,11,2,3,4,12,6,14,5,7,10,15,9
Array.prototype.shuffle = function (){for(var rnd, tmp, i=this.length; i; rnd=parseInt(Math.random()*i), tmp=this[--i], this[i]=this[rnd], this[rnd]=tmp);};

// Array.compare(array)
// If you need to be able to compare Arrays this is the prototype to do it. Pass an Array you want to compare and if they are identical the method will return true. If there's a difference it will return false. The match must be identical so '80' is not the same as 80. 
// Array.prototype.compare = function(testArr) {if (this.length != testArr.length) return false;    for (var i = 0; i < testArr.length; i++) {        if (this[i].compare) {if (!this[i].compare(testArr[i])) return false;} if (this[i] !== testArr[i]) return false;    }    return true;}


// Browser Window Size and Position
// copyright Stephen Chapman, 3rd Jan 2005, 8th Dec 2005
// you may copy these functions but please keep the copyright notice as well
function pageWidth() {return window.innerWidth != null? window.innerWidth : document.documentElement && document.documentElement.clientWidth ?       document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;} 
function pageHeight() {return  window.innerHeight != null? window.innerHeight : document.documentElement && document.documentElement.clientHeight ?  document.documentElement.clientHeight : document.body != null? document.body.clientHeight : null;} 
function posLeft() {return typeof window.pageXOffset != 'undefined' ? window.pageXOffset :document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0;} 
function posTop() {return typeof window.pageYOffset != 'undefined' ?  window.pageYOffset : document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0;} 
function posRight() {return posLeft()+pageWidth();} function posBottom() {return posTop()+pageHeight();}

/*
* This function will not return until (at least)
* the specified number of milliseconds have passed.
* It does a busy-wait loop.
*/
function pause(numberMillis) {
	var now = new Date();
	var exitTime = now.getTime() + numberMillis;
	while (true) {
		now = new Date();
		if (now.getTime() > exitTime)
			return;
	}
}

// Use this: sStr.trim()
String.prototype.trim = function () {
   return this.replace(/^ */, "").replace(/ *$/, "");
   // return this.replace(/^\s*/, "").replace(/\s*$/, "");
}
function log(message) {
    if (!log.window_ || log.window_.closed) {
        var win = window.open("", null, "width=400,height=200," +
                              "scrollbars=yes,resizable=yes,status=no," +
                              "location=no,menubar=no,toolbar=no");
        if (!win) return;
        var doc = win.document;
        doc.write("<html><head><title>Debug Log</title></head>" +
                  "<body></body></html>");
        doc.close();
        log.window_ = win;
    }
    var logLine = log.window_.document.createElement("div");
    logLine.appendChild(log.window_.document.createTextNode(message));
    log.window_.document.body.appendChild(logLine);
}

// Converts 'sHours' from a 24 hour format to a 12 hour format
function getHours12(sHours) {
	// alert("getHours12(" + sHours + ")");
	var iHours = parseInt(sHours);
	if (iHours > 12) {
		sHours = iHours - 12;
	}
	// alert("getHours12(" + sHours + ") Returning:" + sHours);
	return sHours;
}

// Returns 'sHours'either 'am' or 'pm' from a 24 hour format
function getAmPm(sHours) {
	// alert("getAmPm(" + sHours + ")");
	var iHours = parseInt(sHours);
	if (iHours > 12) {
		return 'pm';
	}
	return 'am';
}

// return the number of minutes or seconds rounded to the nearest 0 or 5
function getTime5(sTime) {
	// alert("getTime5(" + sTime + ")");
	var iTens = parseInt(sTime / 10);
	var iOnes = sTime % 10;
	if (iOnes < 5) {
		return iTens * 10;
	}
	return iTens * 10 + 5;
}

// For date time operations where the format should be 01, but the string is just 1
function addLeadingZero(sStr) {
	// alert("addLeadingZero: sStr=" + sStr);
	if (sStr.length == 1) {
		sStr = '0' + sStr;
	}
	// alert("Returning: " + sStr);
	return sStr;
}

// For date time operations where the format should be 1, but the string is 01
function deleteLeadingZero(sStr) {
	// alert("deleteLeadingZero: sStr=" + sStr + ",  sStr.substr(0,1)=" + sStr.substr(0,1));
	if (sStr.substr(0,1) == '0') {
		sStr = sStr.substr(1);
	}
	// alert("Returning: " + sStr);
	return sStr;
}

function isYes(sStr) {
	return (sStr == 'yes')? true : false;
}

function getDateFromSqlDateTime(sSqlDateTime) {
	// alert("getDateFromSqlDateTime: sSqlDateTime=" + sSqlDateTime);
	var sYear = deleteLeadingZero(sSqlDateTime.substring(0, 4));
	var sMonth = deleteLeadingZero(sSqlDateTime.substring(5, 7));
	var sDate = deleteLeadingZero(sSqlDateTime.substring(8, 10));
	var sHour = deleteLeadingZero(sSqlDateTime.substring(11, 13));
	var sMinute = deleteLeadingZero(sSqlDateTime.substring(14, 16));
	var sSecond = deleteLeadingZero(sSqlDateTime.substring(17, 19));
	
	var dRequested = new Date(parseInt(sYear), parseInt(sMonth) - 1, parseInt(sDate), parseInt(sHour), parseInt(sMinute), parseInt(sSecond));
	// alert("getDateFromSqlDateTime: dRequested=" + dRequested);
	return dRequested;
}

// loadDateTimeDropdownsFmSqlDate(sIdPrefix, sSqlDate)
//	selects the appropriate indexes on dropdown lists such that:
//		sIdPrefix is the prefix to the ID of the dropdown and the rest of the word is described below
//		sSqlDate is a SQL date string
function loadDateTimeDropdownsFmSqlDate(sIdPrefix, sSqlDate) {
	var oDate = getDateFromSqlDateTime(sSqlDate);
	loadDateTimeDropdownsFmJsDate(sIdPrefix, oDate)
}

// loadDateTimeDropdownsFmJsDate(sIdPrefix, oDate)
//	selects the appropriate indexes on dropdown lists such that:
//		sIdPrefix is the prefix to the ID of the dropdown and the rest of the word is described below
//		oDate is a javascript date
function loadDateTimeDropdownsFmJsDate(sIdPrefix, oDate) {
	// alert("loadDateTimeDropdownsFmJsDate: sIdPrefix=" + sIdPrefix + ",  oDate=" + oDate);
	var year = oDate.getFullYear();
	var month = oDate.getMonth();
	var date = oDate.getDate();
	var hour = oDate.getHours();
	var minute = oDate.getMinutes();
	var second = oDate.getSeconds();
	// alert('year=' + year + ',  month=' + month + ',  date=' + date);
	// alert('hour=' + hour + ',  minute=' + minute);
	if (document.getElementById(sIdPrefix + 'YearList') != null)
		selectIndexThatEquals(sIdPrefix + 'YearList', year);
	if (document.getElementById(sIdPrefix + 'MonthList') != null)
		document.getElementById(sIdPrefix + 'MonthList').selectedIndex = month;
	if (document.getElementById(sIdPrefix + 'DateList') != null)
		document.getElementById(sIdPrefix + 'DateList').selectedIndex = date - 1;
	if (document.getElementById(sIdPrefix + 'AmPmList') != null)
		selectIndexThatEquals(sIdPrefix + 'AmPmList', getAmPm(hour));
	if (document.getElementById(sIdPrefix + 'HourList') != null)
		selectIndexThatEquals(sIdPrefix + 'HourList', getHours12(hour));
	if (document.getElementById(sIdPrefix + 'MinuteList') != null)
		selectIndexThatEquals(sIdPrefix + 'MinuteList', getTime5(minute));
	if (document.getElementById(sIdPrefix + 'SecondList') != null)
		selectIndexThatEquals(sIdPrefix + 'SecondList', second);
}

function getDropdownDateTimeInSqlFormat(sIdPrefix) {
	var sYear = Date.today().toString("yyyy");
	var sMonth = Date.today().toString("yyyy");
	var sDate = Date.today().toString("yyyy");
	var sHour = '05';
	var sMinute = '00';
	var sSecond = '00';
	if (document.getElementById(sIdPrefix + 'YearList') != null)
		sYear = getSelectedValue(sIdPrefix + 'YearList');
	if (document.getElementById(sIdPrefix + 'MonthList') != null)
		sMonth = getSelectedValue(sIdPrefix + 'MonthList');
	if (document.getElementById(sIdPrefix + 'DateList') != null)
		sDate = getSelectedValue(sIdPrefix + 'DateList');
	if (document.getElementById(sIdPrefix + 'HourList') != null)
		sHour = getSelectedValue(sIdPrefix + 'HourList');

	if (getSelectedValue(sIdPrefix + 'AmPmList') == 'pm') {
		// alert("sHour=" + sHour + ",  parseInt(sHour)=" + parseInt(sHour) + ",  parseInt(sHour) + 12=" + (parseInt(sHour) + 12));
		// parseInt doesn't like the leading zero
		if (sHour.substr(0,1) == '0'  &&  sHour.length == 2) {
			sHour = sHour.substring(1,2);
		}
		sHour = parseInt(sHour) + 12;		// this is an integer at present, but will be converted below
	}

	if (document.getElementById(sIdPrefix + 'MinuteList') != null)
		sMinute = getSelectedValue(sIdPrefix + 'MinuteList');  // getting the value will get the real time we want (no need to mult by 5)

	var sDate = sYear + '-' + sMonth + '-' + sDate + ' ' + sHour + ':' + sMinute + ':00';
	// alert("getDropdownDateTimeInSqlFormat: sDate=" + sDate);
	return sDate;
}

// getPrettyDate: change from yyyy-mm-dd hh:mm:ss to mm/dd/yyyy hh:mm:ss
//														0123456789012345678
// sSqlDate is a string (not a date object)
function getPrettyDate(sSqlDate) {
	var oDate = getDateFromSqlDateTime(sSqlDate);
	var iHour = oDate.getHours();
	if (iHour == 0) {
		sStr = oDate.toString("ddd MMM d, yyyy ") + "midnight";
	}
	else if (iHour == 12) {
		sStr = oDate.toString("ddd MMM d, yyyy ") + "noon";
	}
	else {
		sStr = oDate.toString("ddd MMM d, yyyy h ") + oDate.toString("tt").toLowerCase();
	}
	// sStr = oDate.toString("ddd MMM d, yyyy h:mm ") + oDate.toString("tt").toLowerCase();
	return sStr;
}
//	if (sSqlDate == null  ||  sSqlDate.length != 19)
//		alert("getPrettyDate: sSqlDate=" + sSqlDate);
//	var sYear = sSqlDate.substring(0, 4);
//	var sMonth = sSqlDate.substring(5, 7);
//	var sDate = sSqlDate.substring(8, 10);
//	var sHour = sSqlDate.substring(11, 13);
//	var sMinute = sSqlDate.substring(14, 16);
//	var sSecond = sSqlDate.substring(17, 19);
//	
//	sStr = sMonth + '/' + sDate + '/' + sYear + ' ' + sHour + ':' + sMinute + ':' + sSecond;
//	// if (sSqlDate.length < 19) alert("Returning: " + sStr);


// this doesn't work
function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	alert("createCookie: " + name+"="+value+expires+"; path=/");
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

// this doesn't work
function eraseCookie(name) {
	// alert("eraseCookie: name=" + name);
	createCookie(name,"xxx",-1);
	alert("Cookie deleted: trying readCookie(" + name + ")=" + readCookie(name));
}

// deb is a Debug function
// It requires: <span id='DebugInfo'><span>
function deb(sStr) {
	var oObj = document.getElementById('DebugInfo');
	if (oObj == null) {
		return;
	}
	oObj.innerHTML += sStr + "<br />";
}

function replaceString(sSearch, sReplace, sString) {
	while (sString.indexOf(sSearch) >= 0) {
		// alert("replaceString: sString=" + sString);
		sString = sString.replace(sSearch, sReplace);
	}
	return sString;
}

/** 
*	encodeTextAreaToPhp
*		encodes a string from a TextArea so it can be sent over the network and returned to decodeTextAreaToPhp
*/
function encodeTextAreaToPhp(sStr) {
	// alert("Entering encodeTextAreaToPhp: sStr=" + sStr);
	sStr = encodeToPhp(sStr);
	// sStr = sStr.replace(/%0A/g, '<br />').replace(/%0D/g, '<br />');
	// alert("Leaving encodeTextAreaToPhp: sStr=" + sStr);
	return sStr;
}

/** 
*	decodeTextAreaFmPhp
*		decodes a string originally from a TextArea that was encoded with encodeTextAreaToPhp
*/
function decodeTextAreaFmPhp(sStr) {
	// alert("Entering decodeTextAreaFmPhp: sStr=" + sStr);
	// sStr = sStr.replace(/<br />/g, '\r\n');
	sStr = decodeFmPhp(sStr);
	// alert("Leaving decodeFmPhp: sStr=" + sStr);
	return sStr;
}

/** 
*	encodeToPhp
*		encodes a string so it can be sent over Ajax to a PHP program which performs: 'decodeFmJs($sStr)'
*		or the string can be put directly into a database without using 'mysql_real_escape_string()'
*/
function encodeToPhp(sStr) {
	// first do tabs, carriage returns, and line feeds
	sStr = sStr.replace(/\t/g, '%09').replace(/\r/g, '%0A').replace(/\n/g, '%0D');
	
	// now do all the other non-alphanumeric characters (other than percent) 
	sStr = sStr.replace(/ /g, '%20').replace(/\!/g, '%21').replace(/\"/g, '%22').replace(/\#/g, '%23').replace(/\$/g, '%24');	// not %
	sStr = sStr.replace(/\&/g, '%26').replace(/\'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29');
	sStr = sStr.replace(/\*/g, '%2A').replace(/\+/g, '%2B').replace(/\,/g, '%2C').replace(/\-/g, '%2D').replace(/\./g, '%2E').replace(/\//g, '%2F');
	sStr = sStr.replace(/:/g, '%3A').replace(/;/g, '%3B').replace(/\</g, '%3C').replace(/\=/g, '%3D').replace(/\>/g, '%3E').replace(/\?/g, '%3F');
	sStr = sStr.replace(/@/g, '%40');
	sStr = sStr.replace(/\[/g, '%5B').replace(/\\/g, '%5C').replace(/\]/g, '%5D').replace(/\^/g, '%5E').replace(/\_/g, '%5F');
	sStr = sStr.replace(/\{/g, '%7B').replace(/\|/g, '%7C').replace(/\}/g, '%7D').replace(/\~/g, '%7E');

	// now do the % which will replace all the above percents with ascii of their percents
	sStr = sStr.replace(/\%/g, '*');
	
	// alert("Leaving encodeToPhp(sStr): sStr=" + sStr);
	return sStr;
}
/** 
*	decodeToPhp
*		decodes a string so it can be received over Ajax from a PHP program which performed: 'encodeToJs($sStr)'
*		or can pull it directly from a database such that the javascript did all the work
*/
function decodeFmPhp(sStr) {
	// alert("decodeFmPhp: sStr=" + sStr);
	
	// first recover all of the percents
	sStr = sStr.replace(/\*/g, '%');
	
	// then do all the % characters other than the percent character and the tabs, carriage returns, and line feeds
	sStr = sStr.replace(/%20/g, ' ').replace(/%21/g, '!').replace(/%22/g, '"').replace(/%23/g, '#').replace(/%24/g, '$');	// not %
	sStr = sStr.replace(/%26/g, '&').replace(/%27/g, '\'').replace(/%28/g, '(').replace(/%29/g, ')');
	sStr = sStr.replace(/%2A/g, '*').replace(/%2B/g, '+').replace(/%2C/g, ',').replace(/%2D/g, '-').replace(/%2E/g, '.').replace(/%2F/g, '/');
	sStr = sStr.replace(/%3A/g, ':').replace(/%3B/g, ';').replace(/%3C/g, '<').replace(/%3D/g, '=').replace(/%3E/g, '>').replace(/%3F/g, '?');
	sStr = sStr.replace(/%40/g, '@');
	sStr = sStr.replace(/%5B/g, '[').replace(/%5C/g, '\\').replace(/%5D/g, ']').replace(/%5E/g, '^').replace(/%5F/g, '_');
	sStr = sStr.replace(/%7B/g, '{').replace(/%7C/g, '|').replace(/%7D/g, '}').replace(/%7E/g, '~');
	
	// finally do the tabs, carriage returns, and line feeds
	sStr = sStr.replace(/%09/g, '\t').replace(/%0A/g, '\r').replace(/%0D/g, '\n');
	
	return sStr;
}
//	function decodePhpRawUrlEncode(sStr) {
//		return (decodeURI(sStr)).replace(/%2C/g, ',').replace(/%3F/g, '?').replace(/%3B/g, ';').replace(/%3A/g, ':');
//	}

function setFocus(sId) {
	// alert("setFocus: sId=" + sId);
	var oId = document.getElementById(sId);
	if (oId == null) {
		alert("Element '" + sId + "' is null in setFocus(sId)");
		return;
	}
	oId.focus();
}

// isInteger(s)
function isInteger(sStr) {
	var s = trim(sStr);
	if ((s == null) || (s.length == 0))
		return false;
	
	for (var i = 0; i < s.length; i++) {
		var c = s.charAt(i);
		
		if (c < "0"  ||  c > "9") 
			return false;
	}
	return true;
}

// isFloat(sStr)
function isFloat(sStr) {
	var s = trim(sStr);
	var bDotFound = false;
	
	if ((s == null) || (s.length == 0))
		return false;
	
	for (var i = 0; i < s.length; i++) {
		var c = s.charAt(i);
		
		if (c == "-"  &&  i != 0) 
			return false;
		if (c == ".") {
			if (!bDotFound) 
				bDotFound = true;
			else
				return false;
			}
		if (c < "0"  ||  c > "9") 
			return false;
	}
	return true;
}


// to disable a button: document.forms[0].Button1.disabled=true
// enableButton(sId)
function enableButton(sId) {
	var oId = document.getElementById(sId);
	if (oId == null) {
		alert("Element '" + sId + "' is null in enableButton(sId)");
		throw Err;
		return;
	}
	else {
		oId.disabled=false;
	}
}

// disableButton(sId)
function disableButton(sId) {
	var oId = document.getElementById(sId);
	if (oId == null) {
		alert("Element '" + sId + "' is null in disableButton(sId)");
		throw Err;
		return;
	}
	else {
		oId.disabled=true;
	}
}

// basename(path, suffix)
function basename(path, suffix) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: Ash Searle (http://hexmen.com/blog/)
    // +   improved by: Lincoln Ramsay
    // +   improved by: djmix
    // *     example 1: basename('/www/site/home.htm', '.htm');
    // *     returns 1: 'home'
 
    var b = path.replace(/^.*[\/\\]/g, '');
    
    if (typeof(suffix) == 'string' && b.substr(b.length-suffix.length) == suffix) {
        b = b.substr(0, b.length-suffix.length);
    }
    
    return b;
}
