/************************************************************************************
 * Common Functions
 *
 * Subsetted and Expanded from generalFunctions.js
 * Written 12/06/2006 by DF Denes for acmeX.com
 ************************************************************************************/


/************************************************************************************
 * Window constants for WScript.Run
 ************************************************************************************/
var wsHide 					= 0;		// Hidden
var wsNormalFocus 			= 1;		// Restored to its previous state (neither minimized nor maximized)
var wsMinimizedFocus 		= 2;		// Make visible and minimized
var wsMaximizedFocus 		= 3;		// Make visible and maximized
var wsNormalNoFocus 		= 4;		// Displayed, but doesn't get the input focus
var wsMinimizedNoFocus 		= 6;		// Minimized (as an icon) when started


/************************************************************************************
 * Save data when leaving a page variables
 ************************************************************************************/
var _strSaveFlag				= '';
var _saveFunction;


/************************************************************************************
 * setSaveEvent		This function sets the save event for a page. This will enable
 *					prompting the user if there are unsaved changes when they try
 *					to leave the page.
 ************************************************************************************/
function setSaveEvent(strSave, vSave)
{
	_strSaveFlag			= strSave;
	_saveFunction			= getFunction(vSave);
	if (_saveFunction != null)
	{
		_saveFunction	   += '()';
		addEvent(window, "beforeunload", _savePage);
	}
}

/************************************************************************************
 * savePage			This function will prompt the user if there are unsaved changes
 *					when they try to leave the page. If there are unsaved changes and
 *					the users wants them saved, it will save them.
 ************************************************************************************/
function _savePage()
{
	if (eval(_strSaveFlag))
	{
		var strMsg		= '';
		strMsg		   += 'You have unsaved changes on this page.';
		strMsg		   += '\r\n';
		strMsg		   += 'Do you want to save your changes before exiting?';
		strMsg		   += '\r\n';
		strMsg		   += '———————————————————————————';
		strMsg		   += '\r\n';
		strMsg		   += 'OK\tSave the changes and exit the page';
		strMsg		   += '\r\n';
		strMsg		   += 'Cancel\tExit the page only';

		var bConfirm	= confirm(strMsg);
		if (bConfirm)
			eval(_saveFunction);
	}
}


/************************************************************************************
 ************************************************************************************
 * Date and Date Arithmetic Functions
 ************************************************************************************
 ************************************************************************************/

/************************************************************************************
 * Edit a date: either return the requested date, or if it is invalid, the default.
 ************************************************************************************/
function _editDate(vRequestDate, vDefaultDate) { return ((!isNaN(Date.parse(vRequestDate))) ? (new Date(vRequestDate)) : (new Date(vDefaultDate))); }

/************************************************************************************
 * Perform date arithmetic
 ************************************************************************************/
function _dateAdd(dtmDate, nDays)
{
	var conDayMillis	= 24 * 60 * 60 * 1000;							// milliseconds per day
	var nMillis			= nDays * conDayMillis;							// number of days' worth of milliseconds
	var dtmOutput		= new Date(dtmDate.valueOf() + nMillis);		// get new date
	return dtmOutput;
}

/************************************************************************************
 * Is the requested date in the current month?
 ************************************************************************************/
function _isCurrMonth(dtmRequest)
{
	var dtmNow			= new Date();									// get today
	var dtmDate			= new Date(dtmRequest);							// get requested date
	return (dtmDate.getFullYear() == dtmNow.getFullYear() && dtmDate.getMonth() == dtmNow.getMonth());
}

/************************************************************************************
 * Is the requested date today?
 ************************************************************************************/
function _isToday(dtmRequest)
{
	var dtmNow			= new Date();									// get today
	var dtmDate			= new Date(dtmRequest);							// get requested date
	return (dtmDate.getFullYear() == dtmNow.getFullYear() && dtmDate.getMonth() == dtmNow.getMonth() && dtmDate.getDate() == dtmNow.getDate());
}


/************************************************************************************
 * Get start of year
 ************************************************************************************/
function _dateSOY(dtmDate)
{
	var dtmOutput		= new Date(dtmDate.valueOf());
	dtmOutput			= new Date(dtmOutput.getFullYear(), 0, 1);
	return getDateTime(dtmOutput, null, false, true);
}

/************************************************************************************
 * Get end of year
 ************************************************************************************/
function _dateEOY(dtmDate)
{
	var dtmOutput		= new Date(dtmDate.valueOf());
	dtmOutput			= new Date(dtmOutput.getFullYear(), 11, 31);
	return getDateTime(dtmOutput, null, false, true);
}

/************************************************************************************
 * Get start of month
 ************************************************************************************/
function _dateSOM(dtmDate)
{
	var dtmOutput		= new Date(dtmDate.valueOf());
	dtmOutput			= new Date(dtmOutput.getFullYear(), dtmOutput.getMonth(), 1);
	return getDateTime(dtmOutput, null, false, true);
}


/************************************************************************************
 * Get end of month
 ************************************************************************************/
function _dateEOM(dtmDate)
{
	var dtmOutput		= new Date(dtmDate.valueOf());
	dtmOutput			= new Date(dtmOutput.getFullYear(), dtmOutput.getMonth()+1, 0);
	return getDateTime(dtmOutput, null, false, true);
}

/************************************************************************************
 * Get end of month
 ************************************************************************************/
function vbDateEOM(dtmDate)
{
	return _dateEOM(dtmDate);
}

/************************************************************************************
 * Get start of week
 ************************************************************************************/
function _dateSOW(dtmDate)
{
	var dtmOutput		= new Date(dtmDate.valueOf());
	dtmOutput			= new Date(dtmOutput.getFullYear(), dtmOutput.getMonth(), dtmOutput.getDate()-dtmOutput.getDay());
	return getDateTime(dtmOutput, null, false, true);
}

/************************************************************************************
 * Get end of week
 ************************************************************************************/
function _dateEOW(dtmDate)
{
	var dtmOutput		= new Date(dtmDate.valueOf());
	dtmOutput			= new Date(dtmOutput.getFullYear(), dtmOutput.getMonth(), dtmOutput.getDate()-dtmOutput.getDay()+6);
	return getDateTime(dtmOutput, null, false, true);
}

/************************************************************************************
 * Is the date in range?
 ************************************************************************************/
function _dateInRange(dtmDate, dtmFrom, dtmTo)
{
	var	dtDate		= new Date(dtmDate.valueOf());
	var	dtFrom		= new Date(dtmFrom.valueOf());
	var	dtTo		= new Date(dtmTo.valueOf());

	if (isNaN(dtDate) || isNaN(dtFrom) || isNaN(dtTo))
		return false;

	dtFrom			= dtFrom.setHours(0,0,0);				// clear the from time (start at midnight)
	dtTo			= dtTo.setHours(23,59,59);				// set the to time (end at nearly midnight)

	return (dtDate >= dtFrom && dtTo >= dtDate);
}

/************************************************************************************
 *	getDateTime
 *	Formats the date time
 *	 Inputs
 *		date/time
 *		date/time (for year comparison)
 *	Output
 *		string
 ************************************************************************************/
function getDateTime(dtmDate, dtmYear, bOutputTime, bOutputDate, bEndOfDay, bPadded, b24Hour, bSecond)
{
	var strOutput	= '';
	var strTemp		= '';
	var strDate		= '';
	var strTime		= '';
	var vHour		= '';
	var vMinute		= '';
	var strAmPm		= '';


	if (dtmDate == null || dtmDate == '')
		return '';

	var nDate		= Date.parse(dtmDate);
	if (isNaN(nDate))
		return '';
	var vDate		= new Date(nDate);

	bOutputTime		= getBoolean(bOutputTime);
	bOutputDate		= getBoolean(bOutputDate);
	bEndOfDay		= getBoolean(bEndOfDay);
	bPadded			= getBoolean(bPadded);
	b24Hour			= getBoolean(b24Hour);
	bSecond			= getBoolean(bSecond);

	var nYear		= Date.parse(dtmYear);
	if (isNaN(nYear))
		nYear		= Date.parse('1/1/1970');
	var vYear		= new Date(nYear);

	if (bPadded)
	{
		strTemp		= '00' + (vDate.getMonth() + 1);
		strDate	   += strTemp.substr(strTemp.length-2);
	}
	else
		strDate	   += vDate.getMonth() + 1;

	strDate		   += '/';

	if (bPadded)
	{
		strTemp		= '00' + (vDate.getDate());
		strDate	   += strTemp.substr(strTemp.length-2);
	}
	else
		strDate	   += vDate.getDate();

	if (vDate.getFullYear() != vYear.getFullYear())
	{
		strDate    += '/';
		strDate	   += vDate.getFullYear();
	}

	if (strDate.substr(strDate.length-4) == '1899')
		strDate		= '';
	if (strDate.substr(strDate.length-4) == '1900')
		strDate		= '';


	vHour				= vDate.getHours();
	vMinute				= vDate.getMinutes();
	vSecond				= vDate.getSeconds();
	strTime				= '';

	if (!b24Hour)
	{
		strAmPm			= 'am';
		if (vHour > 11)
			strAmPm		= 'pm';

		if (vHour > 12)
			vHour	   -= 12;
		if (vHour == 0)
			vHour		= 12;

		strTime		   += vHour;
		strTime		   += ':';

		if (vMinute < 10)
			strTime	   += '0';
		strTime		   += vMinute;

		if (bSecond)
		{
			strTime		   += ':';
			if (vSecond < 10)
				strTime	   += '0';
			strTime		   += vSecond;
		}

		strTime		   += strAmPm;
	}
	else
	{
		if (vHour < 10)
			strTime	   += "0";
		strTime		   += vHour;
		strTime		   += ":";

		if (vMinute < 10)
			strTime	   += "0";
		strTime		   += vMinute;
		strTime		   += ":";

		if (vSecond < 10)
			strTime	   += "0";
		strTime		   += vSecond;
	}

	if (bOutputTime && bOutputDate)
	{
		if (!b24Hour)
		{
			strOutput		= strDate;
			if (strTime != '12:00am' && strTime != '12:00:00am')
			{
				if (strOutput.length > 0)
					strOutput  += '&nbsp;';
				strOutput	   += strTime;
			}
		}
		else
		{
			strOutput		= strDate + ' ' + strTime;
		}
	}
	else if (bOutputTime && !bOutputDate)
		strOutput			= strTime;

	else if (bOutputDate && !bOutputTime && !bEndOfDay)
		strOutput			= strDate

	else if (bOutputDate && !bOutputTime && bEndOfDay)
		strOutput			= strDate + ' 23:59:59';

	else
		strOutput			= '';				// return nothing?

	return strOutput;
}

/************************************************************************************
 * Get the date only (no time)
 ************************************************************************************/
function getDateOnly(dtmDate) { return getDateTime(dtmDate, null, false, true, false, false); }

/************************************************************************************
 * Get the end of a day (m/d/yyyy 23:59:59)
 ************************************************************************************/
function getEndOfDay(dtmDate) { return getDateTime(dtmDate, null, false, true, true, false); }

/************************************************************************************
 * Get the time only (no date)
 ************************************************************************************/
function getTimeOnly(dtmDate) { return getDateTime(dtmDate, null, true, false, false, false); }


/************************************************************************************
 * Get the log date in ISO format (full date, full time)
 ************************************************************************************/
function getLogDate()
{
	var dtmNow				= new Date();
	var strTemp				= '';

	var strOutput			= '';
	strOutput			   += new String(dtmNow.getFullYear());
	strOutput			   += '-';
	strTemp					= '00' + new String(dtmNow.getMonth() + 1);
	strOutput			   += strTemp.substr(strTemp.length-2);
	strOutput			   += '-';
	strTemp					= '00' + new String(dtmNow.getDate());
	strOutput			   += strTemp.substr(strTemp.length-2);
	strOutput			   += ' ';
	strTemp					= '00' + new String(dtmNow.getHours());
	strOutput			   += strTemp.substr(strTemp.length-2);
	strOutput			   += ':';
	strTemp					= '00' + new String(dtmNow.getMinutes());
	strOutput			   += strTemp.substr(strTemp.length-2);
	strOutput			   += ':';
	strTemp					= '00' + new String(dtmNow.getSeconds());
	strOutput			   += strTemp.substr(strTemp.length-2);
	strOutput			   += '.';
	strTemp					= '000' + new String(dtmNow.getMilliseconds());
	strOutput			   += strTemp.substr(strTemp.length-3);

	return strOutput;
}

/************************************************************************************
 * Get the date string
 ************************************************************************************/
function getDateString(strDate, strDefault, bString)
{
	var nTest			= Date.parse(strDate);
	var dtmDate			= '';
	if (!isNaN(nTest))
		dtmDate			= new Date(strDate);
	else
	{
		if (typeof(strDefault) != 'undefined')
		{
			if (strDefault != null)
				dtmDate	= new Date(strDefault);
		}
	}
	if (dtmDate != '')
	{
		if (typeof(bString) != 'undefined')
		{
			if (bString == true)
				dtmDate	= getDateTime(dtmDate, null, false, true);
		}
	}
	return dtmDate;
}

/************************************************************************************
 * Get the date requested by the date code.
 ************************************************************************************/
function _getDateFromCode(strDateCode)
{
	var strCode									= strDateCode.toLowerCase();
	var dtmDate									= null;
	var dtmNow									= new Date();
	var nMonth;

	if (strCode == 'now' || strCode == 'date' || strCode == 'today')
	{
		dtmDate									= dtmNow;
	}
	if (strCode == 'tomorrow')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), dtmNow.getMonth(), dtmNow.getDate()+1);
	}
	if (strCode == 'yesterday')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), dtmNow.getMonth(), dtmNow.getDate()-1);
	}

	else if (strCode == 'cursow' || strCode == 'currsow' || strCode == 'sow')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), dtmNow.getMonth(), dtmNow.getDate()-dtmNow.getDay());
	}
	else if (strCode == 'cureow' || strCode == 'curreow' || strCode == 'eow')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), dtmNow.getMonth(), dtmNow.getDate()-dtmNow.getDay()+6);
	}

	else if (strCode == 'nextsow')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), dtmNow.getMonth(), dtmNow.getDate()-dtmNow.getDay()+7);
	}
	else if (strCode == 'nexteow')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), dtmNow.getMonth(), dtmNow.getDate()-dtmNow.getDay()+6+7);
	}

	else if (strCode == 'cursom' || strCode == 'currsom' || strCode == 'som')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), dtmNow.getMonth(), 1);
	}
	else if (strCode == 'cureom' || strCode == 'curreom' || strCode == 'eom')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), dtmNow.getMonth()+1, 0);
	}

	else if (strCode == 'nextsom')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), dtmNow.getMonth()+1, 1);
	}
	else if (strCode == 'nexteom')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), dtmNow.getMonth()+2, 0);
	}

	else if (strCode == 'cursoy' || strCode == 'currsoy' || strCode == 'soy')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), 0, 1);
	}
	else if (strCode == 'cureoy' || strCode == 'curreoy' || strCode == 'eoy')
	{
		dtmDate									= new Date(dtmNow.getFullYear(), 11, 31);
	}

	else if (strCode == 'nextsoy')
	{
		dtmDate									= new Date(dtmNow.getFullYear()+1, 0, 1);
	}
	else if (strCode == 'nexteoy')
	{
		dtmDate									= new Date(dtmNow.getFullYear()+1, 11, 31);
	}

	if (dtmDate != null)
		return getDateTime(dtmDate, null, false, true);			// eliminate time
	else
		return null;
}


/************************************************************************************
 * Validate the requested (string) time
 ************************************************************************************/
function validateTime(timeStr)
{
	var timePat = /^(\d{1,2}):(\d{2})(:(\d{2}))?(\s?(AM|am|PM|pm))?$/;

	var matchArray = timeStr.match(timePat);
	if (matchArray == null)
	{
		return false;
	}

	hour = matchArray[1];
	minute = matchArray[2];
	second = matchArray[4];
	ampm = matchArray[6];

	if (second=="") { second = null; }
	if (ampm=="")
	{
		return false;
	}

	if (hour < 0  || hour > 12)
	{
		return false;
	}
	if (minute < 0 || minute > 59)
	{
		return false;
	}
	if (second != null && (second < 0 || second > 59))
	{
		return false;
	}
	return true;
}




/************************************************************************************
 ************************************************************************************
 * HTML Browser-Independent Event Handling and Processing
 ************************************************************************************
 ************************************************************************************/

/************************************************************************************
 * addEvent		This function adds an event handler to the requested element.
 ************************************************************************************/
function addEvent(objElement, strEvt, vFunction)
{
	var bReturn					= false;
	var strEvent				= strEvt;
	if (strEvent.substr(0,2) == 'on')
		strEvent				= strEvent.substr(strEvent, 2);				// remove "on" prefix

	if (objElement.addEventListener)
	{
		objElement.addEventListener(strEvent, vFunction, false);
		bReturn					= true;;
	}
	else if (objElement.attachEvent)
	{
		bReturn					= objElement.attachEvent("on" + strEvent, vFunction);
	}
	return bReturn;
}

/************************************************************************************
 * getEvent				Get the event object
 ************************************************************************************/
function getEvent(objEvent)
{
	if (window.event)
		return window.event;
	else
		return objEvent;
}

/************************************************************************************
 * getEventElement		Get the HTML element that raised the event
 ************************************************************************************/
function getEventElement(objEvent)
{
	var objElement;
	if (window.event)
		objElement		= window.event.srcElement;
	else
		objElement		= objEvent.target;

	if (objElement.tagName == 'OPTION')
		return objElement.parentNode;
	else
		return objElement;
}

/************************************************************************************
 * getEventType			Get the event type currently raised
 ************************************************************************************/
function getEventType(objEvent)
{
	if (window.event)
		return window.event.type;
	else
		return objEvent.type;
}

/************************************************************************************
 * getEventButton		Get the mouse button that triggered the event.
 * 						If no button was involved (e.g., mouseover),
 *						return -1.
 ************************************************************************************/
function getEventButton(objEvt)
{
	var objEvent				= getEvent(objEvt);
	var nButton					= objEvent.button;
	if (isNaN(nButton))
		nButton					= -1;
	if (nButton == 0)
		nButton					= 1;
	return nButton;
}

/************************************************************************************
 * setWindowEventHandler	Set an event handler for the window object.
 ************************************************************************************/
function setWindowEventHandler(strEvent, objHandler)
{
	var strEventName							= strEvent.toLowerCase();

	if (typeof(window.attachEvent) != 'undefined')	// IE
	{
		if (strEventName.substr(0, 2) != 'on')
			strEventName						= 'on' + strEventName;
		window.attachEvent(strEventName, objHandler);
	}
	else if (typeof(window.addEventListener) != 'undefined')	// FireFox
	{
		if (strEventName.substr(0, 2) == 'on')
			strEventName						= strEventName.substr(2);
		window.addEventListener(strEventName, objHandler, false);
	}
}

/************************************************************************************
 * isLeftClick			Did the user press the left mouse button?
 ************************************************************************************/
function isLeftClick(objEvt) { return (getEventButton(objEvt) == 1); }

/************************************************************************************
 * isRightClick			Did the user press the right mouse button?
 ************************************************************************************/
function isRightClick(objEvt) { return (getEventButton(objEvt) == 2); }


/************************************************************************************
 * getMouseKey			Get the keyboard key held down while the mouse was pressed.
 ************************************************************************************/
function getMouseKey(objEvt)
{
	var strKey					= '';
	var objEvent				= getEvent(objEvt);
	if (!objEvent.modifiers)
	{
		if (objEvent.altKey)
			strKey			   += 'A';
		if (objEvent.ctrlKey)
			strKey			   += 'C';
		if (objEvent.shiftKey)
			strKey			   += 'S';
	}
	else
	{
		if (objEvent.modifiers & Event.ALT_MASK)
			strKey			   += 'A';
		if (objEvent.modifiers & Event.CONTROL_MASK)
			strKey			   += 'C';
		if (objEvent.modifiers & Event.SHIFT_MASK)
			strKey			   += 'S';
	}
	return strKey;
}

/************************************************************************************
 * isAltKey				Did the user press the ALT key while clicking the mouse?
 ************************************************************************************/
function isAltKey(objEvt) { return (getMouseKey(objEvt).indexOf('A') > -1); }

/************************************************************************************
 * isCtrlKey			Did the user press the CTRL key while clicking the mouse?
 ************************************************************************************/
function isCtrlKey(objEvt) { return (getMouseKey(objEvt).indexOf('C') > -1); }

/************************************************************************************
 * isShiftKey			Did the user press the SHIFT key while clicking the mouse?
 ************************************************************************************/
function isShiftKey(objEvt) { return (getMouseKey(objEvt).indexOf('S') > -1); }



/************************************************************************************
 ************************************************************************************
 * HTML URL Handling
 ************************************************************************************
 ************************************************************************************/


/************************************************************************************
 * axURLEncode			Returns an encoded URL to be passed as a query string value
 ************************************************************************************/
function axURLEncode(strURL) { return escape(strURL); }

/************************************************************************************
 * axURLDecode			Decodes a query string value back to a value URL
 ************************************************************************************/
function axURLDecode(strQueryStringValue) { return unescape(strQueryStringValue); }



/************************************************************************************
 ************************************************************************************
 * HTML Selection list handling
 ************************************************************************************
 ************************************************************************************/

/************************************************************************************
 * getSelected			Returns a delimited list of select options from the requested
 *						SELECT element.
 ************************************************************************************/
function getSelected(objSelect, strDelimiter, vCountOnly)
{
	var strOutput						= '';
	var nCount							= 0;
	if (objSelect)
	{
		if (objSelect.tagName == 'SELECT')
		{
			for (var i = 0; i < objSelect.length; i++)
			{
				var objOption			= objSelect.options[i];
				if (objOption.selected)
				{
					if (strOutput.length > 0)
						strOutput	   += strDelimiter;
					strOutput		   += objOption.value;
					nCount++;
				}
			}
		}
		if (getBoolean(vCountOnly))
			strOutput					= nCount;
		return strOutput;
	}
}


/************************************************************************************
 * isFound				Return true if the requested value is found in the
 *						selection string.
 ************************************************************************************/
function isFound(strSelectionList, strValue, strDelimiter)
{
	var strSelectionEdit	= strDelimiter + getString(strSelectionList) + strDelimiter;
	strSelectionEdit		= strSelectionEdit.toLowerCase();

	var strValueEdit		= strDelimiter + getString(strValue) + strDelimiter;
	strValueEdit			= strValueEdit.toLowerCase();

	return (strSelectionEdit.indexOf(strValueEdit) > -1);
}


/************************************************************************************
 * hasSelection			Returns a boolean whether this SELECT element has a selection.
 ************************************************************************************/
function hasSelection(objSelect)
{
	var bSelection						= false;
	if (objSelect)
	{
		if (objSelect.tagName == 'SELECT')
			bSelection					= (objSelect.selectedIndex > -1);
	}
	return bSelection;
}


/************************************************************************************
 * isOptionSelected			Return true if the requested option is selected.
 ************************************************************************************/
function isOptionSelected(objSelect, strValue)
{
	var strOutput				= '';
	if (objSelect)
	{
		if (objSelect.tagName == 'SELECT')
		{
			for (var i = 0; i < objSelect.length; i++)
			{
				var objOption	= objSelect.options[i];
				if (objOption.selected)
				{
					if (objOption.value.toLowerCase() == strValue.toLowerCase())
						return true;
				}
			}
		}
	}
	return false;
}


/************************************************************************************
 * hasOption				Return true if the requested option exists.
 ************************************************************************************/
function hasOption(objSelect, strValue)
{
	var strOutput				= '';
	if (objSelect)
	{
		if (objSelect.tagName == 'SELECT')
		{
			for (var i = 0; i < objSelect.length; i++)
			{
				var objOption	= objSelect.options[i];
				if (objOption.value.toLowerCase() == strValue.toLowerCase())
					return true;
			}
		}
	}
	return false;
}



/************************************************************************************
 ************************************************************************************
 * HTML General Functions
 ************************************************************************************
 ************************************************************************************/


/************************************************************************************
 * setError			This function sets the requested input element for an error.
 ************************************************************************************/
function setError(objElement)
{
	_setError(objElement, true);
}

/************************************************************************************
 * clearError		This function clears the requested input element's error.
 ************************************************************************************/
function clearError(objElement)
{
	_setError(objElement, false);
}

/************************************************************************************
 * _setError		This function sets or clears the requested input element's error.
 ************************************************************************************/
function _setError(objElement, bSet)
{
	if (bSet)
	{
		objElement.style.color					= 'red';
		objElement.style.borderColor			= 'red';
	}
	else
	{
		objElement.style.color					= '';
		objElement.style.borderColor			= '';
	}
}

/************************************************************************************
 * getReferer		This function gets the page's referer.
 ************************************************************************************/
function getReferer()
{
	// is this a client-side request?
	if (typeof(Request) == 'undefined')
		return;

	var strReferer					= Request.ServerVariables('HTTP_REFERER') + '';

	var i							= strReferer.indexOf('/', 9);					// (bypass the protocol prefix)
	if (i > -1)
		strReferer					= strReferer.substr(i);
	i								= strReferer.indexOf('?');						// check for query string
	if (i > -1)
		strReferer					= strReferer.substr(0, i);

	return strReferer;
}

/************************************************************************************
 * getMatchingURL		This function reformats the requested URL to match the
 *						the current site.
 ************************************************************************************/
function getMatchingURL(strURL)
{
	strCurrentURL				= '';
	strOutput					= '';
	strTemp						= strURL;

	if (typeof(Request) != 'undefined')			// server-side request?
	{
		strCurrentURL			= Request.ServerVariables("SERVER_NAME") + '';
	}
	else										// client-side request
	{
		strCurrentURL			= document.url + '';
	}

	strOutput				   += 'http://';

	if (strCurrentURL.toLowerCase().indexOf('int.') > -1)
		strOutput			   += 'int.';

	if (strCurrentURL.toLowerCase().indexOf('test.') > -1)
		strOutput			   += 'test.';

	strTemp						= strTemp.replace('http://', '');
	strTemp						= strTemp.replace('https://', '');

	if (strTemp.toLowerCase().substr(0, 4) == 'int.')
		strTemp					= strTemp.substr(4);

	if (strTemp.toLowerCase().substr(0, 5) == 'test.')
		strTemp					= strTemp.substr(5);

	strOutput				   += strTemp;

	return strOutput;
}

/*******************************************************************************
 * getChecked		This function takes a boolean and returns the checked value
 *					for a radio button or checkbox.
 *******************************************************************************/
function getChecked(bChecked) { return ((bChecked) ? ' checked' : ''); }

/*******************************************************************************
 * getSelect		This function takes a boolean and returns the selected value
 *					for a list box.
 *******************************************************************************/
function getSelect(bSelected) { return ((bSelected) ? ' selected' : ''); }

/*******************************************************************************
 * getStyle			This function takes a boolean and returns the "true" or
 *					"false" style
 *******************************************************************************/
function getStyle(bCondition, strTrueStyle, strFalseStyle)  { return ((bCondition) ? getString(strTrueStyle) : getString(strFalseStyle) ); }

/************************************************************************************
* getGradientLine		Get the HTML output of a gradient line
 ************************************************************************************/
function getGradientLine(strBaseColor, strGradiantColor, nLength, nHeight)
{
 	var i;
	var strOutput				= '';
	var strHex					= '';

	// split base color
	var aBaseColor			 	= new Array();
	aBaseColor[0]				= strBaseColor.substr(0, 2);
	aBaseColor[1]				= strBaseColor.substr(2, 2);
	aBaseColor[2]				= strBaseColor.substr(4, 2);

	// convert to decimal
	for (i=0; i < aBaseColor.length; i++)
	{
		aBaseColor[i]			= parseInt(aBaseColor[i], 16);
		if (isNaN(aBaseColor[i]))
			aBaseColor[i]		= 0;
	}

	// split gradiant color
	var aGradientColor			= new Array();
	aGradientColor[0]			= strGradiantColor.substr(0, 2);
	aGradientColor[1]			= strGradiantColor.substr(2, 2);
	aGradientColor[2]			= strGradiantColor.substr(4, 2);

	// convert to decimal
	for (i=0; i < aGradientColor.length; i++)
	{
		aGradientColor[i]		= parseInt(aGradientColor[i], 16);
		if (isNaN(aGradientColor[i]))
			aGradientColor[i]	= 0;
	}

	// calculate color variances
	var aVariance				= new Array();
	for (i=0; i < aBaseColor.length; i++)
		aVariance[i]			= aGradientColor[i] - aBaseColor[i];

	var nStart					= 0;
	var nWidth					= 4;
	var nEnd					= parseInt(nLength / (2 * nWidth));

	strOutput				   += "\n<table cellspacing='0' cellpadding='0' border='0'>\n\t<tr>\n";
	for (var nLine=0; nLine < 2; nLine++)
	{
		for (var nCell=0; nCell < nEnd; nCell++)
		{
			var nPct			= nCell / nEnd;
			if (nLine==1) nPct	= 1 - nPct;												// reverse direction

			if (nLine==1 && nCell == (nEnd -1))
				nWidth		   += nLength - (nEnd * 2 * nWidth);						// add "slop"

			var strColor		= '';
			var nColor			= 0;
			for (i = 0; i < aVariance.length; i++)
			{
				nColor			= Math.round((aVariance[i] * nPct) + aBaseColor[i]);
				strHex			= '00' + nColor.toString(16);
				strColor	   += strHex.substr(strHex.length-2, 2);
			}
				strOutput	   += "\t\t<td";												//> (shut up NoteTab Pro)
				strOutput	   += " style='width:" + nWidth + "px; height:" + nHeight + "px;";
				strOutput	   += " background-color:#" + strColor + "; font-size:1px; color:#" + strColor + "'>";
				strOutput	   += "&nbsp;";
				strOutput	   += "\t</td>\n";
		}
	}
	strOutput				   += "\t</tr>\n</table>\n";
	return strOutput;
 }

/*******************************************************************************
 * getInputElement	This function creates a new input element of the type
 *					requested.
 *******************************************************************************/
function getInputElement(strType, vID, vName, vValue, vChecked)
{
	var strTemp					= '';
	var objElement				= document.createElement('INPUT');
	objElement.type				= strType;

	strTemp						= getString(vID);
	if (strTemp.length > 0)
		objElement.id			= strTemp;

	strTemp						= getString(vName);
	if (strTemp.length > 0)
		objElement.name			= strTemp;

	strTemp						= getString(vValue);
	if (strTemp.length > 0)
		objElement.value		= strTemp;

	strTemp						= getString(vChecked);
	if (strTemp.length > 0 && (strType == 'radio' || strType == 'checkbox'))
		objElement.checked		= getBoolean(strTemp);

	return objElement;
}


/*******************************************************************************
 * encodeData		This function encodes a string in the data format
 *					(e.g., cookie).
 *******************************************************************************/
function encodeData(strValue) { return escape(strValue).replace(/\ /g, '+'); }

/*******************************************************************************
 * decodeData		This function decodes a string from the data format
 *					(e.g., cookie).
 *******************************************************************************/
function decodeData(strValue) { return unescape(strValue).replace(/\+/g, ' '); }


/************************************************************************************
 ************************************************************************************
 * FileSystem Operations
 ************************************************************************************
 ************************************************************************************/

/*******************************************************************************
 * fileExists		This function takes a file string and return whether it
 *					exists or not (server-side only).
 *******************************************************************************/
function fileExists(FileName)
{
	if (typeof(Request) != 'undefined')
	{
		var strFile		= Server.MapPath(getString(FileName))
		var objFSO		= new ActiveXObject('Scripting.FileSystemObject')
		return objFSO.FileExists(strFile);
	}
	else
		return false;
}

/*******************************************************************************
 * fileSize			This function takes a file string and returns the
 *					file's size (server-side only).
 *******************************************************************************/
function fileSize(FileName)
{
	var i, j;

	if (typeof(Request) != 'undefined')
	{
		var strFile		= Server.MapPath(getString(FileName))
		var objFSO		= new ActiveXObject('Scripting.FileSystemObject')
		if (objFSO.FileExists(strFile))
		{
			var objFile		= objFSO.GetFile(strFile);
			var nSize		= objFile.Size;
			if (nSize > 1048576)
			{
				nSize		= (nSize / 1048576);
				nSize		= Math.round(nSize * 10);
				nSize		= nSize / 10;
				nSize		= nSize + " MB";
			}
			else
			{
				if (nSize > 1024)
				{
					nSize	= Math.round((nSize / 1024));
					nSize	= nSize + " KB";
				}
			}
			return nSize;
		}
		else
			return -1;
	}
	else
		return -1;
}



/************************************************************************************
 ************************************************************************************
 * GUID Functions
 ************************************************************************************
 ************************************************************************************/

/************************************************************************************
 *	isGUID				Is the input value a GUID?
 ************************************************************************************/
function isGUID(strValue) {	return ((strValue.length == 38) && (strValue.substr(0,1) == '{') && (strValue.substr(strValue.length-1, 1) == '}')); }

/************************************************************************************
 *	matchingGUID		Are these matching GUIDs?
 ************************************************************************************/
function matchingGUID(vGUID1, vGUID2)
{
	var strGUID1				= new String(getString(vGUID1));
	var strGUID2				= new String(getString(vGUID2));

	strGUID1					= strGUID1.replace(/\{/g, '');
	strGUID1					= strGUID1.replace(/\}/g, '');
	strGUID1			 		= strGUID1.replace(/\-/g, '');

	strGUID2					= strGUID2.replace(/\{/g, '');
	strGUID2					= strGUID2.replace(/\}/g, '');
	strGUID2			 		= strGUID2.replace(/\-/g, '');

	return (strGUID1.toLowerCase() == strGUID2.toLowerCase());
}

/************************************************************************************
 * getNullGUID
 ************************************************************************************/
function getNullGUID() {return '{00000000-0000-0000-0000-000000000000}';}


/*****************************************************************
 * getMyGUID		This function returns the current users's GUID.
 *****************************************************************/
function getMyGUID()
{
	var vUserID		= getCookie('userID');
	if (vUserID != '')
		return vUserID;
	else
		return getNullGUID();
}


/*****************************************************************
 * getGUIDString	This function returns the GUID's string
 *****************************************************************/
function getGUIDString(strGUID)
{
	var strTemp				= strGUID;
	strTemp					= strTemp.replace(/\{/g, '');
	strTemp					= strTemp.replace(/\}/g, '');
	return strTemp.toUpperCase();
}

/*****************************************************************
 * getGUIDFormatted	This function returns the formatted GUID
 *****************************************************************/
function getGUIDFormatted(strGUID)
{
	var strTemp				= strGUID;
	strTemp					= strTemp.replace(/\{/g, '');
	strTemp					= strTemp.replace(/\}/g, '');
	strTemp					= strTemp.toUpperCase();
	return '{' + strTemp + '}';
}


/************************************************************************************
 ************************************************************************************
 * Cookie Functions
 ************************************************************************************
 ************************************************************************************/

/************************************************************************************
 * getCookie		This function returns the requested cookie
 ************************************************************************************/
function getCookie(strName)
{
	// is this a client-side request?
	if (typeof(Request) == 'undefined')
	{
		var strCookies						= document.cookie;
		var aCookie 						= strCookies.split('; ');			// split cookies
		for (var i = 0; i < aCookie.length; i++)
		{
			var re 							= /.*\=.*\=/;						// regular expresession to find two equal signs
			if (re.exec(aCookie[i]) != null)									// multi-valued cookie?
			{
				var j						= aCookie[i].indexOf('=');			// find 1st equal sign (separates name from multi-valued pairs)
				var strMultiValue			= aCookie[i].substr(j+1);			// remove name
				var aMultiValue				= strMultiValue.split('&');			// split multi-valued pairs

				for (var k = 0; k < aMultiValue.length; k++)
				{
					var aMultiCrumb			= aMultiValue[k].split('=');		// split individual multi-value crumb
					if (decodeData(aMultiCrumb[0]).toLowerCase() == strName.toLowerCase())	// requested item?
						return decodeData(aMultiCrumb[1]);
				}
			}
			else
			{
				var aCrumb 					= aCookie[i].split('=');			// split crumb
				if (decodeData(aCrumb[0]).toLowerCase() == strName.toLowerCase())
					return decodeData(aCrumb[1]);
			}
		}
		return '';																// the requested cookie does not exist
	}
	else
	{
		var strCookie 				= Request.Cookies('ax') + '';
		var aCookie					= strCookie.split('&');
		for (var i = 0; i < aCookie.length; i++)
		{
			var aCrumb	= aCookie[i].split('=');
			if (decodeData(aCrumb[0]).toLowerCase() == strName.toLowerCase())
			{
				return decodeData(aCrumb[1]);
			}
		}
		return decodeData(Request.Cookies(encodeData(strName)));
	}
}


/************************************************************************************
 * putCookie		This function writes the requested cookie
 ************************************************************************************/
function putCookie(strName, strValue, vSingleValue)
{
	var strBoolean							= "|true|false|on|off|yes|no|"

	strName									= getString(strName);
	strValue								= getString(strValue);

	var dtmNow								= new Date();
	var dtmExpire							= new Date(dtmNow.getFullYear(), dtmNow.getMonth(), dtmNow.getDate()+180);

	// if this is a boolean, convert it to "0" or "1"
	if (strBoolean.indexOf("|" + strValue.toLowerCase() + "|") > -1)
		strValue							= getBoolean(strValue.toLowerCase(), true);

	// if this is a date/time, convert it to the format "mm/dd/yy hh:mm:ss" (omit the time if it's midnight)
	var nValue								= Date.parse(strValue);
	if (!isNaN(nValue))
	{
		var dtmValue						= new Date(nValue);
		if ((dtmValue.getHours() + dtmValue.getMinutes() + dtmValue.getSeconds()) > 0)
			strValue						= getDateTime(dtmValue, null, true, true, false, true, true);
		else
			strValue						= getDateTime(dtmValue, null, false, true, false, true);
	}

	// is this a client-side request?
	if (typeof(Request) == 'undefined')
	{
		var bFound							= false;
		var strNameOut						= '';
		var strValueOut						= '';
		var strMultiValueName				= '';
		var strCookie						= document.cookie;
		var aMultiValueIn					= new Array();
		var aMultiValueOut					= new Array();
		var aCookie							= strCookie.split('; ');				// split cookies
		var m								= -1;

		for (var c = 0; c < aCookie.length; c++)
		{
			var re 								= /.*\=.*\=/;						// regular expresession to find two equal signs
			if (re.exec(aCookie[c]) != null)										// multi-valued cookie?
			{
				bFound							= true;
				var j							= aCookie[c].indexOf('=');			// find 1st equal sign (separates name from multi-valued pairs)
				strMultiValueName				= aCookie[c].substr(0, j);			// save multi-value name
				var aMultiValueIn				= aCookie[c].substr(j+1).split('&');// split multi-valued pairs

				if (getString(strValue).length > 0)
				{
					m							= aMultiValueOut.length;
					aMultiValueOut[m]			= encodeData(strName) + '=' + encodeData(strValue); //.replace(/\,/g, "_");	// encoded multi-valued cookie
				}

				for (var k = 0; k < aMultiValueIn.length; k++)
				{
					var aMultiCrumb				= aMultiValueIn[k].split('=');				// split individual multi-value crumb
					if (decodeData(aMultiCrumb[0]).toLowerCase() != strName.toLowerCase())	// not the requested item?
					{
						m						= aMultiValueOut.length;
						aMultiValueOut[m]		= aMultiValueIn[k];							// load encoded multi-valued cookie
					}
				}
			}
			if (bFound)
				break;
		}

		if (bFound)
		{
			strNameOut						= encodeData(strMultiValueName);
			strValueOut						= aMultiValueOut.join('&');
			document.cookie					= strNameOut + '=' + strValueOut + '; Expires=' + dtmExpire.toGMTString() + '; path=/;';
		}
		else
		{
			strNameOut						= encodeData(strName);							// force a new multi-valued cookie
			strValueOut						= encodeData(strValue);
			document.cookie					= 'ax=' + strNameOut + '=' + strValueOut + '; Expires=' + dtmExpire.toGMTString() + '; path=/;';
		}
	}
	else
	{
		Response.Cookies('ax')(strName)		= strValue;
		Response.Cookies('ax').Expires		= getDateTime(dtmExpire, false, false, true);
		Response.Cookies('ax').Path			= '/';
	}
}


/*****************************************************************
 * amLoggedIn		This returns a boolean whether or not I am
 *					logged in.
 *****************************************************************/
function amLoggedIn() { return (getBoolean(getCookie('userID') != '')); }



/************************************************************************************
 ************************************************************************************
 * SQL Functions
 ************************************************************************************
 ************************************************************************************/

/*****************************************************************
 * runQuery			Process the requested query.
 *****************************************************************/
function runQuery(cnnADO, SQL, vDebug)
{
	var nRecordsAffected		= 0;

	if (SQL.length > 0)
	{
		if (getBoolean(vDebug))
		{
			Response.Write('<pre>' + SQL + '</pre>\r\n');
			Response.Write('<hr>\r\n');
		}
		else
		{
			try
			{
				cnnADO.Execute(SQL, nRecordsAffected, adCmdText + adExecuteNoRecords);
			}
			catch(e)
			{
				Response.Write('<fieldset><pre>' + SQL + '</pre></fieldset>\r\n');
				throw e;
			}
		}
	}
	return nRecordsAffected;
}



/*****************************************************************
 * getNetConnection		Convert the ASP to .NET Connection String
 *****************************************************************/
function getNetConnection(strConn)
{
	var aConnOut							= new Array();
	if (strConn.length > 0)
	{
		var aConn							= strConn.split(';');
		for (var i = 0; i < aConn.length; i++)
		{
			if (aConn[i].substr(0,8).toLowerCase() != 'provider')
				aConnOut[aConnOut.length]	= aConn[i];
		}
	}
	return aConnOut.join(';');
}


/************************************************************************************
 ************************************************************************************
 * Query String Functions
 ************************************************************************************
 ************************************************************************************/

/************************************************************************************
 * getQuery		This function returns the requested query string parameter
 ************************************************************************************/
function getQuery(strName)
{
	var strQuery			= '';
	var strValue			= '';

	if (typeof(Request) == 'undefined')					// client-side request?
		strQuery			= document.location.search + '';
	else
		strQuery			=  '?' + Request.QueryString + '';

	var q					= strQuery.indexOf('?');
	if (q > -1)
		strQuery			= strQuery.substr(q+1);
	else
		strQuery			= '';

	var aQuery 				= strQuery.split('&');		// querystring items are separated by ampersands
	for (var i=0; i < aQuery.length; i++)
	{
		var aCrumb 			= aQuery[i].split('=');		// get a name/value pair
		if (strName.toLowerCase() == aCrumb[0].toLowerCase())
		{
			if (strValue.length > 0)
				strValue   += ', ';
			strValue	   += unescape(aCrumb[1]);
		}
	}
	return strValue;								// return the query string value
}




/************************************************************************************
 ************************************************************************************
 * General JavaScript Functions
 ************************************************************************************
 ************************************************************************************/

/************************************************************************************
 * getFunction			Return the function name of the input function.
 ************************************************************************************/
function getFunction(vFunction)
{
	if (vFunction != null)
	{
		var strFunction		= vFunction.toString();
		var i				= strFunction.indexOf('function');
		if (i > -1)
		{
			strFunction		= strFunction.substr(i+9);
			i				= strFunction.indexOf('(');
			if (i > -1)
			{
				strFunction	= strFunction.substr(0, i);
				return strFunction;
			}
		}
		return null;
	}
	return null;
}

/************************************************************************************
 * getCaller			Return the function name of the caller.
 ************************************************************************************/
function getCaller(strFunction)
{
	var vCaller				= eval(strFunction + '.caller');
	if (vCaller != null)
	{
		var strCaller		= vCaller.toString();
		var i				= strCaller.indexOf('function');
		if (i > -1)
		{
			strCaller		= strCaller.substr(i+9);
			i				= strCaller.indexOf('(');
			if (i > -1)
			{
				strCaller	= strCaller.substr(0, i);
				return strCaller;
			}
		}
		return '(unknown caller)';
	}
	return '(no caller)';
}

/************************************************************************************
 * getCallerFormatted		Return the formatted function name of the caller.
 ************************************************************************************/
function getCallerFormatted(strFunction)
{
	return "[" + getCaller(strFunction) + "] " + strFunction + ": ";
}

/************************************************************************************
 * getConstructor		Return the constructor of a variable.
 ************************************************************************************/
function getConstructor(vInput)
{
	if ((typeof(vInput) != 'undefined') && (vInput != null))
	{
		var strConstructor	= vInput.constructor.toString();
		var i				= strConstructor.indexOf('function');
		if (i > -1)
		{
			strConstructor	= strConstructor.substr(i+9);
			i				= strConstructor.indexOf('(');
			if (i > -1)
			{
				strConstructor	= strConstructor.substr(0, i);
				return strConstructor.toLowerCase();
			}
		}
	}
	return 'undefined';
}

/************************************************************************************
 * getMax					This function returns the maximum value of a pair of
 *							numbers.
 ************************************************************************************/
function getMax(Value1, Value2)
{
	var nValue1				= parseInt(Value1);
	if (isNaN(nValue1))
		nValue1				= 0;
	var nValue2				= parseInt(Value2);
	if (isNaN(nValue2))
		nValue2				= 0;
	return Math.max(nValue1, nValue2);
}

/************************************************************************************
 * getMin					This function returns the minimum value of a pair of
 *							numbers.
 ************************************************************************************/
function getMin(Value1, Value2)
{
	var nValue1				= parseInt(Value1);
	if (isNaN(nValue1))
		nValue1				= 0;
	var nValue2				= parseInt(Value2);
	if (isNaN(nValue2))
		nValue2				= 0;
	return Math.min(nValue1, nValue2);
}

/************************************************************************************
 * getRounded				This function returns the rounded value of a number.
 ************************************************************************************/
function getRounded(InputValue, DecimalPositions)
{
	var nValue				= parseFloat(InputValue);
	if (isNaN(nValue))
		nValue				= 0;

	var nDecimal			= parseInt(DecimalPositions);
	if (isNaN(nDecimal))
		nDecimal			= 0;

	var nPower				= Math.pow(10, nDecimal);
	return (Math.round(nValue * nPower) / nPower);
}

/************************************************************************************
 * getBoolean			Get the boolean value of a string.
 *						The return value is either a boolean (true, false), or a
 *						bit (1, 0).
 ************************************************************************************/
function getBoolean(Value, vReturnBit)
{
	var strBoolean							= "|true|on|yes|1|-1|"
	var bReturnBit	= (typeof(vReturnBit) != 'undefined');
 	var strValue	= getString(Value) + '';
	strValue		= strValue.toLowerCase();

	if (strBoolean.indexOf("|" + strValue + "|") > -1)
		return ((bReturnBit) ? '1' : true);
	else
		return ((bReturnBit) ? '0' : false);
}



/************************************************************************************
 ************************************************************************************
 * String Functions
 ************************************************************************************
 ************************************************************************************/

/************************************************************************************
 *	getString			Get the string value of the input.
 ************************************************************************************/
function getString(strInput)
{
	if ( (typeof(strInput) == 'number') || (typeof(strInput) == 'string') || (typeof(strInput) == 'boolean') || (typeof(strInput) == 'object') )
	{
		if (strInput == null)
			return '';
		else
			return strInput + '';
	}
	return '';
}

/************************************************************************************
 *	getSQLValue			Get a valid string for a SQL query
 ************************************************************************************/
function getSQLValue(inputString)
{
	var strValue		= getString(inputString)
	return strValue.replace(/\'/g, "''");
}

/************************************************************************************
 *	getOutputString			Get a valid string for HTML output
 ************************************************************************************/
function getOutputString(inputString, vNBSP)
{
	var strValue		= getString(inputString);

	strValue			= strValue.replace(/\"/g, "&quot;");
	strValue	 		= strValue.replace(/\'/g, "&#39;");
	strValue	 		= strValue.replace(/\,/g, "&#44;");
	if (getBoolean(vNBSP))
		strValue		= strValue.replace(/ /g, "&nbsp;");
	return strValue;
}

/************************************************************************************
 *	getHTMLString			Get a valid string for HTML output
 ************************************************************************************/
function getHTMLString(inputString)
{
	var strValue		= getString(inputString);
	strValue	 		= strValue.replace(/\</g, "&lt;");									//> (shut up NoteTab Pro)
	strValue	 		= strValue.replace(/\>/g, "&gt;");
	return strValue;
}

/************************************************************************************
 * appendDelimitedList
 ************************************************************************************/
function appendDelimitedList(List, NewValue, Delimiter, vIncludeBlank)
{
	var strList			= getString(List);
	var strValue		= getString(NewValue);
	var bIncludeBlank	= getBoolean(vIncludeBlank);

	var strDelimiter	= ',';
	if (typeof(Delimiter) != 'undefined')
		strDelimiter	= getString(Delimiter);

	if (strValue.length > 0 || bIncludeBlank)
	{
		if (strList.length > 0)
			strList	   += strDelimiter;
		strList		   += strValue;
	}
	return strList;
}

/************************************************************************************
 * getStringDefault		Return the string, or the default value if the string is empty.
 ************************************************************************************/
function getStringDefault(vString, vDefault) { return (getString(vString).length > 0) ? vString : vDefault; }

/************************************************************************************
 * getStringIf			Return the string if the input condition is true
 ************************************************************************************/
function getStringIf(bCondition, vString) { return (bCondition) ? vString : ''; }

/************************************************************************************
 *	choosePlural		Choose the plural word, based on the input number
 ************************************************************************************/
function choosePlural(nNumber, strSingular, strPlural)
{
	var nCounter				= parseInt(nNumber);
	if (!isNaN(nCounter))
	{
		if (nCounter >= 0)
			return ((nCounter == 1) ? strSingular : strPlural);
	}
	return '';
}

/************************************************************************************
 * Process string like the VB "LEFT" function
 ************************************************************************************/
function Left(str, n)
{
	if (n <= 0)																			//> (shut up NoteTab Pro)
	    return "";
	else if (n > String(str).length)
	    return str;
	else
	    return String(str).substring(0, n);
}

/************************************************************************************
 * Process string like the VB "RIGHT" function
 ************************************************************************************/
function Right(str, n)
{
    if (n <= 0)																			//> (shut up NoteTab Pro)
       return "";
    else if (n > String(str).length)
       return str;
    else {
       var iLen = String(str).length;
       return String(str).substring(iLen, iLen - n);
    }
}




/************************************************************************************
 ************************************************************************************
 * IE-Specific Functions
 ************************************************************************************
 ************************************************************************************/



/*****************************************************************
 * getDialogFeatures	Get the dialog feature string for the
 *						requested dialog box size and placement.
 *****************************************************************/
function getDialogFeatures(vWidth, vHeight, vCenter)
{
	if (typeof(Request) == 'undefined')
	{
		var strFeatures = '';

		strFeatures += 'dialogWidth:' 			+ vWidth	+ 'px;';
		strFeatures += 'dialogHeight:' 			+ vHeight	+ 'px;';

		if (window.event != null && !getBoolean(vCenter))
		{
			var vLeft		= window.event.screenX - window.event.offsetX + 6;
			var vTop		= window.event.screenY - window.event.offsetY + 6;

			if (((vLeft + vWidth) > window.screen.availWidth) || ((vTop + vHeight) > window.screen.availHeight))
				strFeatures	+= 'center:yes;';
			else
			{
				strFeatures	   += 'dialogLeft:' + vLeft	+ 'px;';
				strFeatures    += 'dialogTop:'	+ vTop	+ 'px;';
			}
		}
		else
			strFeatures	+= 'center:yes;';


		strFeatures	+= 'help:no;';
		strFeatures	+= 'resizable:no;';
		strFeatures	+= 'scrolling:no;';
		strFeatures	+= 'status:no;';

		return strFeatures;
	}
	return 'This function cannot be used server-side.';
}

/*****************************************************************
 * Retrieve the requested elements's bounds: x, y, width, height
 *****************************************************************/
function getElementBounds(objElement)
{
	if (typeof (objElement) == 'string')
	{
		var strID = objElement;
		objElement = document.getElementById(strID);
	}
	return Sys.UI.DomElement.getBounds(objElement);
}
