//**********************************************************************
// Page:	form_lib.js
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Library of Form manipulation functions
//**********************************************************************

//**********************************************************************
// Name:	toUpperCase
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Convert the value attribute of an element object to upper case
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		02-NOV-2001		MEM			Initial Version
//**********************************************************************
function toUpperCase( objElement )
{
//	Set the value string property of an object to upper case
	var strElement = objElement.value ;
	strElement = strElement.toUpperCase() ;
	objElement.value = strElement ;
}

//**********************************************************************
// Name:	goUrl
// Author:	Andre M. Czausov (andrec@oakton.com.au)
// Purpose:	Go to new URL via JS (used when browser bugs block <A href>)
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		31-MAY-2005		MEM			Initial Version
//**********************************************************************
function goUrl(url) {
   window.location=url;
}

//**********************************************************************
// Name:	toLowerCase
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Convert the value attribute of an element object to lower case
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		02-NOV-2001		MEM			Initial Version
//**********************************************************************
function toLowerCase( objElement )
{
//	Set the value string property of an object to lower case
	var strElement = objElement.value ;
	strElement = strElement.toLowerCase() ;
	objElement.value = strElement ;
}

//**********************************************************************
// Name:	enforceNumeric
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Allow only numeric values in the field (call from onKeyUp)
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		02-NOV-2001		MEM			Initial Version
//**********************************************************************
function enforceNumeric( objElement )
{
	var varElement = objElement.value ;
	if( varElement.length > 0 )
	{
		if( isNaN(varElement) )
		{
			alert("Only numbers are permitted in this field.") ;
			varElement = varElement.slice(0,varElement.length-1) ;
			objElement.value = varElement ;
		}
	}
}

//**********************************************************************
// Name:	enforceInteger
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Only allow integers in the field (call from onKeyUp)
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		02-NOV-2001		MEM			Initial Version
//**********************************************************************
function enforceInteger( objElement )
{ 
	var varElement = objElement.value ;
	if( varElement.length > 0 )
	{
		var varChar = varElement.slice( varElement.length - 1, varElement.length ) ;
		if( isNaN(parseInt(varChar)) )
		{
			alert("Only numerals (0-9) are permitted in this field.") ;
			varElement = varElement.slice(0,varElement.length-1) ;
			objElement.value = varElement ;
		}
	}
}

//**********************************************************************
// Name:	enforceTelephone
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Allows space, open bracket, close bracket and digits only to maximum length
//			(call from onKeyUp)
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		11-DEC-2001		MEM			Initial Version
//**********************************************************************
function enforceTelephone( objElement )
{	
	var intChar ;
	var strVal = objElement.value ;
	for( var intPos = 0 ; intPos < strVal.length ; intPos ++ )
	{
		intChar = strVal.charCodeAt( intPos ) ;
		if( !( intChar == 32 || intChar == 40 || intChar == 41 || ( intChar >= 48 && intChar <= 57 ) ) )
		{
			alert("Only brackets, spaces or digits are permitted in telephone number fields.\n\nEG: \"(03) 9876 5432\" is a valid telephone number.") ;
			var strPre = strVal.slice( 0, intPos ) ;
			var strPst = strVal.slice( intPos + 1, strVal.length + 1 ) ;
			strVal = strPre + strPst ;
			objElement.value = strVal ;
		}
	}
}

//**********************************************************************
// Name:	isTelephone
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Returns true if the string is a valid telephone number
//			May contains normal brackets, spaces and digits
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		11-DEC-2001		MEM			Initial Version
//**********************************************************************
function isTelephone( strTelephone )
{
	var intChar ;
	if( strTelephone.length == 0 ) { return false ; }
	for( var intPos = 0 ; intPos < strTelephone.length ; intPos ++ )
	{
		intChar = strTelephone.charCodeAt( intPos ) ;
		if( !( intChar == 32 || intChar == 40 || intChar == 41 || ( intChar >= 48 && intChar <= 57 ) ) )
		{
			return false ;
		}
	}
	return true ;
}
		
//**********************************************************************
// Name:	getChecked
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Return the index of the checked radio button in the radio group
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		02-NOV-2001		MEM			Initial Version
//**********************************************************************
function getChecked( objElementArray )
{
	for( var intOpt = 0 ; intOpt < objElementArray.length ; intOpt ++ ) 
	{ 
		if( objElementArray[intOpt].checked ) { return intOpt ; } 
	} 
	return -1 ; 
}

//**********************************************************************
// Name:	getCheckedValue
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Return the value of the checked radio button in the radio group
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		02-NOV-2001		MEM			Initial Version
//**********************************************************************
function getCheckedValue( objElementArray )
{
	for( var intOpt = 0 ; intOpt < objElementArray.length ; intOpt ++ ) 
	{ 
		if( objElementArray[intOpt].checked )
		{
			return objElementArray[intOpt].value ;
		}
	} 
	return "" ; 
}

//**********************************************************************
// Name:	uncheckRadioGroup
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Uncheck all radio objects in the group
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		02-NOV-2001		MEM			Initial Version
//**********************************************************************
function uncheckRadioGroup( objElementArray )
{
	for( var intObject = 0 ; intObject < objElementArray.length ; intObject ++ )
	{
		objElementArray[intObject].checked = false ;
	}
}

//**********************************************************************
// Name:	clearElementValue
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Clear the value property of an element (eg, text box)
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		02-NOV-2001		MEM			Initial Version
//**********************************************************************
function clearElementValue( objElement )
{
	objElement.value = "" ;
}

//**********************************************************************
// Name:	enforceAlpha
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Enfores only aphabetic characters and spaces in the value attribute of the object
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		08-NOV-2001		MEM			Initial Version
//**********************************************************************
function enforceAlpha( objElement )
{
	var intChar ;
	var strElement = objElement.value ;
	for( var intPos = 0 ; intPos < strElement.length ; intPos ++ )
	{
		intChar = strElement.charCodeAt( intPos ) ;
		if( !(( intChar >= 65 && intChar <= 90 ) || ( intChar >= 97 && intChar <= 122 ) || intChar == 32) )
		{
			alert("Please enter only alphabetic characters (A-Z and a-z) or spaces in this field.") ;
			var strPre = strElement.slice( 0, intPos ) ;
			var strPst = strElement.slice( intPos + 1, strElement.length + 1 ) ;
			strElement = strPre + strPst ;
			objElement.value = strElement ;
		}
	}
}

//**********************************************************************
// Name:	enforceAlphaForNames
// Author:	Jeremy Hooi (Oakton)
// Purpose:	Enfores alphabetical characters, spaces, as well as hyphens
//			and single quotes in the value attribute of the object
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		30-MAR-2004		JH			Initial Version
//**********************************************************************
function enforceAlphaForNames( objElement )
{
	var intChar ;
	var strElement = objElement.value ;
	for( var intPos = 0 ; intPos < strElement.length ; intPos ++ )
	{
		intChar = strElement.charCodeAt( intPos ) ;
		if( !(( intChar >= 65 && intChar <= 90 ) || ( intChar >= 97 && intChar <= 122 ) || intChar == 32 || intChar == 45 || intChar == 39 ))
		{
			alert("Please enter only alphabetic characters (A-Z and a-z), spaces, hyphens (-) or apostrophes (') in this field.") ;
			var strPre = strElement.slice( 0, intPos ) ;
			var strPst = strElement.slice( intPos + 1, strElement.length + 1 ) ;
			strElement = strPre + strPst ;
			objElement.value = strElement ;
		}
	}
}

//**********************************************************************
// Name:	enforceAlphaNumeric
// Author:	James Carvosso (Oakton Computing)
// Purpose:	Enfores only alphanumeric characters and spaces in the value attribute of the object
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		08-NOV-2001		MEM			Initial Version
//**********************************************************************
function enforceAlphaNumeric( objElement )
{
	var intChar ;
	var strElement = objElement.value ;
	for( var intPos = 0 ; intPos < strElement.length ; intPos ++ )
	{
		intChar = strElement.charCodeAt( intPos ) ;
		if( !(( intChar >= 65 && intChar <= 90 ) || ( intChar >= 97 && intChar <= 122 ) || ( intChar >= 48 && intChar <= 57 ) || intChar == 32) )
		{
			alert("Please enter only alphnumeric characters (A-Z, a-z and 0-9) or spaces in this field.") ;
			var strPre = strElement.slice( 0, intPos ) ;
			var strPst = strElement.slice( intPos + 1, strElement.length + 1 ) ;
			strElement = strPre + strPst ;
			objElement.value = strElement ;
		}
	}
}

//**********************************************************************
// Name:	isNumeric
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Returns true if varValue only contains numerals (no radix permitted)
// 0-9, - , . & space are valid
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		08-NOV-2001		MEM			Initial Version
//**********************************************************************
function isNumeric( varValue )
{

	var intChar ;
	var intLen = varValue.length ;
	for( var intPos = 0 ; intPos < intLen ; intPos ++ )
	{
		intChar = varValue.charCodeAt( intPos ) ;
		if( !( ( intChar >= 48 && intChar <= 57 ) || intChar == 45 || intChar == 46 || intChar == 32 ))
		{
			return false ;
		}
	}
	return true ;
}

//**********************************************************************
// Name:	isAlpha
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Return true if the string contains only letter and spaces
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		08-NOV-2001		MEM			Initial Version
//**********************************************************************
function isAlpha( varString )
{
	var intChar ;
	var intLen = varString.length ;
	for( var intPos = 0 ; intPos < intLen ; intPos ++ )
	{
		intChar = varString.charCodeAt( intPos ) ;
		if( !( ( intChar >= 65 && intChar <= 90 ) || ( intChar >= 97 && intChar <= 122 ) || intChar == 32 ) )
		{
			return false ;
		}
	}
	return true ;
}

//**********************************************************************
// Name:	isAlphaForNames
// Author:	Jeremy Hooi (Oakton)
// Purpose:	Return true if the string contains only letter, spaces, hyphens
//			or apostrophes
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		30-MAR-2004		JH			Initial Version
//**********************************************************************
function isAlphaForNames( varString )
{
	var intChar ;
	var intLen = varString.length ;
	for( var intPos = 0 ; intPos < intLen ; intPos ++ )
	{
		intChar = varString.charCodeAt( intPos ) ;
		if( !( ( intChar >= 65 && intChar <= 90 ) || ( intChar >= 97 && intChar <= 122 ) || intChar == 32 || intChar == 45 || intChar == 39 ) )
		{
			return false ;
		}
	}
	return true ;
}


//**********************************************************************
// Name:	isAlphaNumeric
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Return true if contains number and letters only
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		13-DEC-2001		MEM			Initial Version
//**********************************************************************
function isAlphaNumeric( varVal )
{ 
	var intChar ;
	var intLen = varVal.length ;
	for( var intPos = 0 ; intPos < intLen ; intPos ++ )
	{
		if(isNaN(varVal.charAt(intPos)))
		{
			intChar = varVal.charCodeAt( intPos ) ;
			if( !( (intChar >= 65 && intChar <= 90) || (intChar >= 97 && intChar <= 122) ) )
			{
				return false ;
			}
		}
	}
	return true ;
} 

//**********************************************************************
// Name:	getSniffer
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Return a browser sniffer object with the following attributes:
//			Version			- the browser major version number
//			VersionIE		- IE internal version number
//			isWindows		- true if the underlying platform is Windows
//			isLinux			- true if the underlying platform is Linux
//			isUNIX			- true if the underlying platform is UNIX
//			isMacintosh		- true if the underlying platform is Mac
//			isIE			- true if this is a Microsoft browser
//			isNS			- true if this is a Netscape browser
//			isOP			- true if this is a Opera browser
//			isLX			- true if this is a Lynx browser
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		07-NOV-2001		MEM			Initial Version
// 1.1		15-NOV-2001		MEM			Bug fix
// 1.2		13-JAN-2002		MEM			Added VersionIE
//**********************************************************************
function getSniffer()
{
	var objBrowser = new Object() ;
	objBrowser.Version = parseInt(navigator.appVersion) ;
	if( navigator.userAgent.indexOf("Windows") == -1 )
	{
		objBrowser.isWindows = false ;
	} else {
		objBrowser.isWindows = true ;
	}
	if( navigator.userAgent.indexOf("Linux") == -1 )
	{
		objBrowser.isLinux = false ;
	} else {
		objBrowser.isLinux = true ;
	}
	if( navigator.userAgent.indexOf("UNIX") == -1 )
	{
		objBrowser.isUNIX = false ;
	} else {
		objBrowser.isUNIX = true ;
	}
	if( navigator.userAgent.indexOf("Mac") == -1 )
	{
		objBrowser.isMacintosh = false ;
	} else {
		objBrowser.isMacintosh = true ;
	}
	objBrowser.isIE = false ;
	objBrowser.isNS = false ;
	objBrowser.isOP = false ;
	objBrowser.isLX = false ;
	if( navigator.appName.indexOf("Netscape") != -1 )
	{
		objBrowser.isNS = true ;
	}
	if( navigator.appName.indexOf("Microsoft") != -1 )
	{
		objBrowser.isIE = true ;
		var strVersionIE = Field( navigator.appVersion, ";", 2 ) ;
		objBrowser.VersionIE = parseInt( strVersionIE.slice(5) ) ;
	}
	if( navigator.appName.indexOf("Opera") != -1 )
	{
		objBrowser.isOP = true ;
	}
	if( navigator.appName.indexOf("Lynx") != -1 )
	{
		objBrowser.isLX = true ;
	}
	return objBrowser ;
}

//**********************************************************************
// Name:	RegulateTextArea
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Constrain the length of a text area
// Params:	objTextArea		- the <textarea> object
//			objTarget		- the <input> object which displays characters remaining
//			intMaxLength	- the maximum number of characters
//			blnTruncate		- true will remove portion of value beyond maxlength
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		12-NOV-2001		MEM			Initial Version
// 1.1		13-NOV-2001		MEM			Added blnTruncate option
//**********************************************************************
function RegulateTextArea( objTextArea, objTarget, intMaxLength, blnTruncate )
{
	var strText = objTextArea.value ;
	var intLen = strText.length ;
	if( blnTruncate != true && blnTruncate != false ) { blnTruncate = false ; }
	if( intLen > intMaxLength )
	{
		alert("Maximum of " + intMaxLength + " characters reached.") ;
		if( blnTruncate )
		{
			strText = strText.slice( 0, intMaxLength ) ;
			objTextArea.value = strText ;
		}
		objTarget.value = 0 ;
	}
	else
	{
		objTarget.value = intMaxLength - intLen ;
	}
}

//**********************************************************************
// Name:	OrderUp
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Move the selected option up in a select list
// Params:	objSelect		- the <select> object
//			blnAlert		- alerts will be displayed if true
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		15-NOV-2001		MEM			Initial Version
//**********************************************************************
function OrderUp( objSelect, blnAlert )
{
//	Simple validation
	if( blnAlert != true && blnAlert != false ) { blnAlert = false ; }
//	Get select info
	var intSelected = objSelect.selectedIndex ;
	var intOptions = objSelect.options.length ;
//	Is there a select option and is there more than one option?
	if( intSelected != -1 && intOptions > 1 )
	{
	//	Only proceed if the select option is not already at the top
		if( intSelected != 0 )
		{
		//	Get the values of the two options to be swapped
			var varValue_This = objSelect.options[intSelected].value ;
			var varText_This = objSelect.options[intSelected].text ;
			var varValue_Next = objSelect.options[intSelected-1].value ;
			var varText_Next = objSelect.options[intSelected-1].text ;
		//	Now swap the value and text properties of the options around
			objSelect.options[intSelected].value = varValue_Next ;
			objSelect.options[intSelected].text = varText_Next ;
			objSelect.options[intSelected-1].value = varValue_This ;
			objSelect.options[intSelected-1].text = varText_This ;
		//	Set the new selected index
			objSelect.selectedIndex = intSelected - 1 ;
		}
		else
		{
			if( blnAlert )
			{
				alert("The selected option is already at the top of the list and cannot be moved higher.") ;
			}
		}
	}
	else
	{
		if( blnAlert )
		{
			if( intOptions <= 1 )
			{
				alert("There must be a minimum of two options to use ordering features.") ;
			}
			if( intSelected == -1 )
			{
				alert("You must select an option to reorder.") ;
			}		
		}
	}
}

//**********************************************************************
// Name:	OrderDown
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Move the selected option down in a select list
// Params:	objSelect		- the <select> object
//			blnAlert		- alerts will be displayed if true
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		15-NOV-2001		MEM			Initial Version
//**********************************************************************
function OrderDown( objSelect, blnAlert )
{
//	Simple validation
	if( blnAlert != true && blnAlert != false ) { blnAlert = false ; }
//	Get select info
	var intSelected = objSelect.selectedIndex ;
	var intOptions = objSelect.options.length ;
//	Is there a select option and is there more than one option?
	if( intSelected != -1 && intOptions > 1 )
	{
	//	Only proceed if the select option is not already at the bottom
		if( intSelected != intOptions - 1 )
		{
		//	Get the values of the two options to be swapped
			var varValue_This = objSelect.options[intSelected].value ;
			var varText_This = objSelect.options[intSelected].text ;
			var varValue_Next = objSelect.options[intSelected+1].value ;
			var varText_Next = objSelect.options[intSelected+1].text ;
		//	Now swap the value and text properties of the options around
			objSelect.options[intSelected].value = varValue_Next ;
			objSelect.options[intSelected].text = varText_Next ;
			objSelect.options[intSelected+1].value = varValue_This ;
			objSelect.options[intSelected+1].text = varText_This ;
		//	Set the new selected index
			objSelect.selectedIndex = intSelected + 1 ;
		}
		else
		{
			if( blnAlert )
			{
				alert("The selected option is already at the bottom of the list and cannot be moved lower.") ;
			}
		}
	}
	else
	{
		if( blnAlert )
		{
			if( intOptions <= 1 )
			{
				alert("There must be a minimum of two options to use ordering features.") ;
			}
			if( intSelected == -1 )
			{
				alert("You must select an option to reorder.") ;
			}		
		}
	}
}

//**********************************************************************
// Name:	getSelectValue
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Return the selected value in a select list
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		29-NOV-2001		MEM			Initial Version
//**********************************************************************
function getSelectValue( objSelect )
{
	var varValue = objSelect.options[objSelect.selectedIndex].value ;
	return varValue ;
}

//**********************************************************************
// Name:	Count
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Count the number of times strDel appears in strString
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		05-DEC-2001		MEM			Initial Version
//**********************************************************************
function Count( strString, strDel )
{
	var intStringLen = strString.length ;
	var intDelLen = strDel.length ;
	var strSample ;
	var intCount = 0 ;
	if( intStringLen == 0 || intDelLen == 0 ) { return 0 ; }
	for( var intPos = 0 ; intPos < (intStringLen - intDelLen) ; intPos ++ )
	{
		strSample = strString.slice( intPos, intPos + intDelLen ) ;
		if( strSample == strDel ) { intCount ++ ; }
	}
	return intCount ;
}

//**********************************************************************
// Name:	DCount
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Count the number of members in a strDel delimited strString string array
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		05-DEC-2001		MEM			Initial Version
//**********************************************************************
function DCount( strString, strDel )
{
	var intDCount = Count( strString, strDel ) + 1 ;
	return intDCount ;
}

//**********************************************************************
// Name:	Field
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Extra member intMember from strDel delimited strString
// Notes:	strDel MUST be extact ONE character in length
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		05-DEC-2001		MEM			Initial Version
//**********************************************************************
function Field( strString, strDel, intMember )
{
//	Initialise
	var intStringLen = strString.length ;
	var intDelLen = strDel.length ;
//	Perform input validation
	if( intStringLen == 0 || intDelLen != 1 || isNaN(intMember) || intMember == 0 )
	{
		return ;
	}
//	Locate member
	var strExtract = "" ;
	var intCount = 0 ;
	var strSample ;
	var intStart = 0 ;
	var intEnd ;
//	Loop through source string looking for start position of desired member
	for( var intPos = 0 ; intPos < intStringLen ; intPos ++ )
	{
		strSample = strString.slice( intPos, intPos + 1 ) ;	// extract character
		if( strSample == strDel ) { intCount ++ ; }			// compare (increment counter)
		if( intCount == intMember - 1 )						// detect desired member
		{
		//	Perform extraction
			intPos ++ ;										// nudge position index
			while( intCount < intMember && intPos < intStringLen )
			{
				strSample = strString.slice( intPos, intPos + 1 ) ;
				if( strSample == strDel || intPos >= (intStringLen - 1) )
				{
					intEnd = intPos ; // get member end position
					if( intPos >= (intStringLen - 1) ) { intEnd ++ ; }
					strExtract = strString.slice( intStart, intEnd ) ; // extract member
					intPos = intStringLen ;	// force loop exit
					//alert(intStart + ":" + intEnd);
				}
				else
				{
					intPos ++ ; // increment counter
				}
			}
		}
		else
		{	
			intStart = intPos + 2 ; //	set starting position of this member
		}
	}
	return strExtract ;
}

//**********************************************************************
// Name:	isBlank
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Return true if strText is empty or contains only spaces
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		11-DEC-2001		MEM			Initial Version
//**********************************************************************
function isBlank( strText )
{ 
	if( strText.length == 0 ) { return true ; }
	for( var intPos = 0 ; intPos < strText.length ; intPos ++ )
	{
		if( strText.charCodeAt(intPos) != 32 ) { return false ; }
	}
	return true ;
}

//**********************************************************************
// Name:	getFormIndex
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Return the document form index of the named form
// Args:	string	strFormName		- name of the form to look for
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		27-DEC-2001		MEM			Initial Version
//**********************************************************************
function getFormIndex( strFormName )
{
	var colForms = window.document.forms ;
	for( var intForm = 0 ; intForm < colForms.length ; intForm ++ )
	{
		if( colForms[intForm].name == strFormName )
		{
			return intForm ;
		}
	}
	return -1 ;
}
			
//**********************************************************************
// Name:	getElementIndex
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Return the form element index of the named element
// Args:	object	objForm			- reference to a form object
//			string	strElementName	- name of the element to look for
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		27-DEC-2001		MEM			Initial Version
//**********************************************************************
function getElementIndex( objForm, strElementName )
{
	for( var intElement = 0 ; intElement < objForm.length ; intElement ++ )
	{
		if( objForm.elements[intElement].name == strElementName )
		{
			return intElement ;
		}
	}
	return -1 ;	
}

//**********************************************************************
// Name:	enforceLicense
// Author:	Mark Micallef (mmicallef@powerserve.com.au)
// Purpose:	Force only valid license field characters in an element field
// Notes:	Call from onKeyUp event and pass "this" (object self-reference)
// Args:	object	objElement		- reference to a field element object
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		01-DEC-2001		MEM			Initial Version
//**********************************************************************
function enforceLicence( objElement )
{
	//	Make sure only letters, dashes or numbers get entered
	//	Make sure only letters or numbers get entered
	var intChar ;
	var strElement = objElement.value ;
	for( var intPos = 0 ; intPos < strElement.length ; intPos ++ )
	{
		intChar = strElement.charCodeAt( intPos ) ;
//		if( !(( intChar >= 48 && intChar <= 57 ) || ( intChar >= 65 && intChar <= 90 ) || ( intChar >= 97 && intChar <= 122 ) || intChar == 45) )
		if( !(( intChar >= 48 && intChar <= 57 ) || ( intChar >= 65 && intChar <= 90 ) || ( intChar >= 97 && intChar <= 122 )) )
		{
			alert("Please enter only letters or numbers in the license field.") ;
			var strPre = strElement.slice( 0, intPos ) ;
			var strPst = strElement.slice( intPos + 1, strElement.length + 1 ) ;
			strElement = strPre + strPst ;
			objElement.value = strElement ;
		}
	}
}

//**********************************************************************
// Name:	trim
// Author:	Brandon Chan
// Purpose:	Removes leading and trailing spaces from the passed string. Also removes
//			consecutive spaces and replaces it with one space. If something besides
//			a string is passed in (null, custom object, etc.) then return the input.
// Notes:	none
// Args:	string	inputString		- string to trim
//**********************************************************************
// VERSION HISTORY 
// Ver		Date			Init		Description
// 1.0		17-JUL-2002		BC			Initial Version
//**********************************************************************

function trim (inputString) 
	{  
	if (typeof inputString != "string") 
		{ 
		return inputString; 
		}
   
	var retValue = inputString;
	var ch = retValue.substring(0, 1);
	while (ch == " ") 
		{ 
		// Check for spaces at the beginning of the string
		retValue = retValue.substring(1, retValue.length);
		ch = retValue.substring(0, 1);
		}
	ch = retValue.substring(retValue.length-1, retValue.length);
	while (ch == " ") 
		{ // Check for spaces at the end of the string
		retValue = retValue.substring(0, retValue.length-1);
		ch = retValue.substring(retValue.length-1, retValue.length);
		}
	while (retValue.indexOf("  ") != -1) 
		{ 
		// Note that there are two spaces in the string - look for multiple spaces within the string
		retValue = retValue.substring(0, retValue.indexOf("  ")) + retValue.substring(retValue.indexOf("  ")+1, retValue.length); 
		// Again, there are two spaces in each of the strings
		}
	
	// Return the trimmed string back to the user
	return retValue; 
	}
