//---------------------------------------------------------------

function OpenWindow
	(
	url, 
	windowWidth, 
	windowHeight, 
	feature, 
	windowName, 
	showStatusBar
	)
{
	var left;
	var top;
	var windowReference = null;

	if (windowWidth == 0 || windowHeight == 0)
	{	// This window to be opened in full screen
		left = 0;
		top = 0;
		windowWidth = screen.availWidth - 10;
		windowHeight = screen.availHeight - 60;
	}
	else
	{	// This window is to be opened in given size
		var chasm = screen.availWidth;
		var mount = screen.availHeight;
		left = ((chasm - windowWidth - 10) * .5);
		top = ((mount - windowHeight - 30) * .5);
	}

	// Concatenate window size and feature together
	var winFeature = "width=" + windowWidth + ",height=" + windowHeight + 
		",left=" + left + ",top=" + top + "," + feature ;

	if (showStatusBar)
	{
		winFeature += ",status=yes";
	}

	windowReference = window.open(url, windowName, winFeature, true);

	if ( typeof( windowReference ) == "object" )
	{
		windowReference.focus();
	}

	return windowReference;
}

//---------------------------------------------------------

function ValidatePassword( sender, msgInvalidPassword )
{
	if ( IsBlank( sender.value ) == false )
	{
		if ( IsValidPassword( sender.value ) == false )
		{
			window.alert( msgInvalidPassword );
			sender.value = "";
			sender.focus();
			return false;
		}
		else
		{
			return true;
		}
	}
	else
	{
		return true;
	}
}

//---------------------------------------------------------

function IsValidPassword( password )
{
	return (
			( password.search( /\d/         ) >= 0 ) && 
			( password.search( /[a-zA-Z]/   ) >= 0 ) &&
			( password.search( /^\w{6,30}$/ ) == 0 )
		   );
}

//---------------------------------------------------------

function IsValidEmailAddress( emailStr )
{
	var checkTLD=1;
	var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;
	var emailPat=/^(.+)@(.+)$/;
	var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
	var validChars="\[^\\s" + specialChars + "\]";
	var quotedUser="(\"[^\"]*\")";
	var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	var atom=validChars + '+';
	var word="(" + atom + "|" + quotedUser + ")";
	var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
	var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
	var matchArray=emailStr.match(emailPat);

	if (matchArray==null)
	{
		return false;
	}
	
	var user=matchArray[1];
	var domain=matchArray[2];

	for (i=0; i<user.length; i++)
	{
		if (user.charCodeAt(i)>127) 
		{
			return false;
		}
	}
	
	for (i=0; i<domain.length; i++)
	{
		if (domain.charCodeAt(i)>127) 
		{
			return false;
		}
	}

	if (user.match(userPat)==null)
	{
		return false;
	}

	var IPArray=domain.match(ipDomainPat);
	
	if (IPArray!=null)
	{
		for (var i=1;i<=4;i++)
		{
			if (IPArray[i]>255)
			{
				return false;
			}
		}
		return true;
	}

	var atomPat=new RegExp("^" + atom + "$");
	var domArr=domain.split(".");
	var len=domArr.length;
	
	for (i=0;i<len;i++)
	{
		if (domArr[i].search(atomPat)==-1)
		{
			return false;
		}
	}

	if (checkTLD && domArr[domArr.length-1].length!=2 && 
		domArr[domArr.length-1].search(knownDomsPat)==-1) 
	{
		return false;
	}

	if (len<2)
	{
		return false;
	}

	return true;
}

//---------------------------------------------------------

// Set focus to a control in a form whose name 
// matches controlName parameter
function SetFocus(formObject, controlName)
{
	if (controlName == "")
	{
		return false;
	}

	var currentControl;

	for (var i = 0; i <= formObject.length; i++)
	{
		currentControl = formObject.elements[i];
	
		if (currentControl.name == controlName && 
			currentControl.type != "hidden" && 
			currentControl.disabled == false &&
			currentControl.style.display != "none" )
		{
			currentControl.focus();
			break;
		}
	}
}
//---------------------------------------------------------

// Check if the value I am passed is empty
function IsBlank( value2Check, treatZeroAsEmpty )
{
	if ( ! treatZeroAsEmpty )
	{	
		// Treat zero as not empty
		for ( var i = 0; i < value2Check.length; i++ )
		{
			var c = value2Check.charAt( i );
			if ( " \n\t".indexOf( c ) == -1 )
			{
				return false;
			}
		}
	}
	else 
	{	
		// Treat zero as empty
		for ( var i = 0; i < value2Check.length; i ++ )
		{
			var c = value2Check.charAt( i );
			if ( "0, .-\n\t".indexOf( c ) == -1 )
			{
				return false;
			}
		}
	}
	return true;
}

//---------------------------------------------------------

/// Check if given value is of numeric
function IsNumeric(value2Check)
{
	// Trim empty space
	value2Check = value2Check.replace(/ /g, "");

	//Returns true if value is a number or is NULL
	//otherwise returns false	
	if (value2Check.length == 0)
	{
		return true;
	}

	//Returns true if value is a number defined as
	//   having an optional leading -.
	//   having at most 1 decimal point.
	//   otherwise containing only the characters 0-9.
	var start_format = " .,-0123456789";
	var number_format = " .,0123456789";
	var check_char;
	var useDecimal = false;
	var trailing_blank = false;
	var digits = false;

	// This is not a valid number if it contains only a . or , or -
	if ( value2Check.length = 1 )
	{
		if ( value2Check == "," ||
			 value2Check == "." ||
			 value2Check == "-" )
		{
			return false;
		}
	}
	
	//The first character can be - .  blank or a digit.
	check_char = start_format.indexOf(value2Check.charAt(0));
	//Was it a decimal?
	if (check_char == 1)
	{
		useDecimal = true;
	}
	else 
	{
		if (check_char < 1)
		{
			return false;
		}
	}
	    
	//Remaining characters can be only . or a digit, but only one decimal.
	for (var i = 1; i < value2Check.length; i++)
	{
		check_char = number_format.indexOf(value2Check.charAt(i));
		if (check_char < 0)
		{
			return false;
		}
		else if (check_char == 1)
		{	// Second decimal
			if (useDecimal)
			{		
				return false;
			}
			else
			{
				useDecimal = true;
			}
		}
		else if (check_char == 0)
		{
			if (useDecimal || digits)
			{
				trailing_blank = true;
			}
		}
		else if (trailing_blank)
		{	// ignore leading blanks
			return false;
		}
		else
		{
			digits = true;
		}
	}

	//All tests passed, so...
	return true
}
//---------------------------------------------------------

// Trim leading space
function LTrim(value2Trim)
{
	while('' + value2Trim.charAt(0) == ' ')
	{
		value2Trim = value2Trim.substring(1, value2Trim.length);
	}
	return value2Trim;
}
//---------------------------------------------------------

// Trim trailing space
function RTrim(value2Trim)
{
	while('' + value2Trim.charAt(value2Trim.length - 1) == ' ')
	{
		value2Trim = value2Trim.substring(0, value2Trim.length - 1);
	}
	return value2Trim;
}
//---------------------------------------------------------

// Trim both leading and trailing space
function AllTrim(value2Trim)
{
	value2Trim = LTrim(value2Trim);
	return RTrim(value2Trim);
}
//---------------------------------------------------------

// Validate if a given string is a valid date
// dateValue is the value to validate
// dateFormat is the date format code, supported formats are YMD, MDY & DMY
// separator is the date separator, i.e. /. Optional
// dateField is the object reference of the date textbox. Optional
// Dependance:
//  1. LeapYear()
//  2. AllTrim()
function DateValidator(dateValue, dateFormat, separator, dateField)
{
	// Valid Date Format for dateFormat variable
	// 1. YY MM DD
	// 2. MM DD YY
	// 3. DD MM YY
	//
	// Valid Date Separator
	// 1. Slash (/)
	// 2. Dot (.)
	// 3. Hyphen (-)
	// 4. Space ( )
	var dateSeparatorArray = new Array("-", " ", "/", ".");
	var dayPart, monthPart, yearPart;
	var intDay, intMonth, intYear;
	var dateArray;
	var hasDateValueParsed = false;
	
	var monthArray = new Array(12);
	monthArray[0] = "Jan";
	monthArray[1] = "Feb";
	monthArray[2] = "Mar";
	monthArray[3] = "Apr";
	monthArray[4] = "May";
	monthArray[5] = "Jun";
	monthArray[6] = "Jul";
	monthArray[7] = "Aug";
	monthArray[8] = "Sep";
	monthArray[9] = "Oct";
	monthArray[10] = "Nov";
	monthArray[11] = "Dec";

	// Decide if we need to write formatted date string
	// back to the caller upon sucessful date validation
	var writeFormattedDate = false;
	if (arguments.length == 4)
	{
		writeFormattedDate = true;
	}
	else
	{
		dateField = null;	
	}
	
	// No need to check if dateValue is valid date if it is empty
	dateValue = AllTrim(dateValue);
	if (dateValue.length < 1)
	{
		return true;
	}
	
	// Loop through each character in dateValue variable
	for (var i = 0; i < dateSeparatorArray.length; i++) 
	{	// Does dateValue contain any one of the date separator as defined 
		// in dateSeparatorArray?
		if (dateValue.indexOf(dateSeparatorArray[i]) != -1) 
		{	// Split dateValue into an array using the date separators
			// as defined in dateSeparatorArray
			dateArray = dateValue.split( dateSeparatorArray[i] );
			
			// dateArray should have at least 3 elements, i.e. month, day & year
			// It is not a valid date if not so.
			if (dateArray.length != 3)
			{
				return false;
			}
			else 
			{
				switch (dateFormat)
				{	// YMD format
					case "YMD" :
						yearPart = dateArray[0];
						monthPart = dateArray[1];
						dayPart = dateArray[2];
						break;
					// MDY format
					case "MDY" :
						monthPart = dateArray[0];
						dayPart = dateArray[1];
						yearPart = dateArray[2];
						break;
					// DMY format
					case "DMY" :
						dayPart = dateArray[0];
						monthPart = dateArray[1];
						yearPart = dateArray[2];
						break;
				}
				hasDateValueParsed = true;
			}
			break;
		}
	}
	
	// Return false if dateValue can not be parsed to
	// year, month and day part
	if (hasDateValueParsed == false)
	{
		return false;
	}
	
	switch (yearPart.length)
	{	
		// 2 digit year is entered, then assume it is 20XX.
		case 2:
			yearPart = '20' + yearPart;
			break;

		// 4 digit year is entered, then do nothing
		case 4:
			break;

		// 1 digit year is entered, then assume it is 200X.
		case 1:
			yearPart = '200' + yearPart;
			break;

		// 3 digit year is entered, then assume it is 2XXX.
		case 3:
			yearPart = '2' + yearPart;
			break;
		
		// If year digit is more than 4 character, then it is not a valid year
		default:
			return false;
	}

	// Check if the day part is valid by checking if it contains only digit
	intDay = parseInt(dayPart, 10);
	if (isNaN(intDay))
	{
		return false;
	}
	
	// Check if the month part is valid
	intMonth = parseInt(monthPart, 10);
	// The month part contains no digit but string, i.e. Jan - Dec
	if (isNaN(intMonth))
	{	
		for (var i = 0; i < 12; i++)
		{	// Does this month string match any one of the string as defined in monthArray?
			if (monthPart.toUpperCase() == monthArray[i].toUpperCase()) 
			{	// Save valid month digit to this variable so we can
				// pass the isNaN() test right after this block		
				intMonth = i + 1;
				monthPart = monthArray[i];
				// Month string is valid, i.e. Jan - Dec, then stop right here.
				break;
			}
		}
		// intMonth should contain a valid month, i.e. 1 - 12.
		// Return false if it is not so
		if (isNaN(intMonth))
		{
			return false;
		}
	} 

	// Check if the year part is valid by checking if it contains only digit
	intYear = parseInt(yearPart, 10);
	if (isNaN(intYear))
	{
		return false;
	}
	
	// Month must be between 1 to 12
	if (intMonth > 12 || intMonth < 1)
	{
		return false;
	}
	
	// Day for these months must be between 1 to 31
	if ((intMonth == 1 || intMonth == 3 || intMonth == 5 || intMonth == 7 || intMonth == 8 || intMonth == 10 || intMonth == 12) && (intDay > 31 || intDay < 1)) 
	{
		return false;
	}
	
	// Day for these months must be between 1 to 30
	if ((intMonth == 4 || intMonth == 6 || intMonth == 9 || intMonth == 11) && (intDay > 30 || intDay < 1)) 
	{
		return false;
	}
	
	// Day of Feburary calls for special handling
	if (intMonth == 2)
	{	// First of all day must not be less than 1
		if (intDay < 1) 
		{
			return false;
		}
		// Then if it is a leap year, day must not be greater than 29
		if (LeapYear(intYear))
		{
			if (intDay > 29) 
			{
				return false;
			}
		}
		// If it is not a leap year, day must not be greater than 28
		else 
		{
			if (intDay > 28) 
			{
				return false;
			}
		}
	}
	// If it makes it here dateValue is a valid date
	
	// Write formated date string to the date textbox
	if (writeFormattedDate)
	{
		switch (dateFormat)
		{	// YMD format
			case "YMD" :
				dateField.value = intYear + separator + intMonth + separator + intDay;
				break;
			// MDY format
			case "MDY" :
				dateField.value = intMonth + separator + intDay + separator + intYear;
				break;
			// DMY format
			case "DMY" :
				dateField.value = intDay + separator + intMonth + separator + intYear;
				break;
		}
	}
	
	return true;
}
//---------------------------------------------------------

// Supporting function for DateValidator()
// Can also be used independently
function LeapYear(intYear)
{
	if (intYear % 100 == 0)
	{
		if (intYear % 400 == 0) 
		{ 
			return true; 
		}
	}
	else
	{
		if ((intYear % 4) == 0) 
		{ 
			return true; 
		}
	}
	return false;
}
//---------------------------------------------------------

// Extract name=value pair from a given string, i.e. if I am passed
// this string: <input type=text id=myID name=myName>
// and asked to extract: name=
// and told to use: > as end at character
// I return: name=myName
// See also: ExtractUrlParam()
function ExtractAttribute(string2Extract, attributeName, endAtChar)
{
	string2Extract = string2Extract.toLowerCase();
	attributeName = attributeName.toLowerCase()
	// Get start index
	var startIndex = parseInt(string2Extract.indexOf(attributeName));
	// Get end index using the most common end at character, i.e. a space
	var endIndex = parseInt(string2Extract.indexOf(" ", startIndex)); 
	// name=value does not end at a space, then get end index using the
	// endAtChar parameter
	if (endIndex == -1)
	{
		endIndex = parseInt(string2Extract.indexOf(endAtChar, startIndex));
	}
	endIndex -= startIndex;
	return attributeValue = string2Extract.substr(startIndex, endIndex);
}

//---------------------------------------------------------
// Extract name or value from a given name and value pair, i.e. If I am passed
// this string: MyName=MyValue
// and asked to extract the name portion: true
// I return: MyName
// See also: ExtractUrlParam()
function ExtractNameValuePair(pair2Extract, extractName)
{
	if (extractName)
	{	
		// Extract the name portion
		return pair2Extract.substring(0, pair2Extract.indexOf("="));
	}
	else
	{	
		// Extract the value portion
		return pair2Extract.substr(pair2Extract.indexOf("=") + 1);
	}
}

//---------------------------------------------------------
// Check if all fields, except hidden system field 
// of a given form is empty. Return
// true if so, false if otherwise.
function IsFormBlank( sender )
{
	var isBlank = true;
	
	for ( var i = 0; i < sender.elements.length; i ++ )
	{
		var field = sender.elements[ i ];
		
		// Check only if this is not a hidden system field		
		if ( field.system != "yes" )
		{
			//window.alert( field.type );
			switch ( field.type )
			{
				case "text":
					isBlank = IsBlank( field.value, false );
					break;
					
				case "hidden":
					isBlank = IsBlank( field.value, false );
					break;

				case "select-one":
					if ( ! IsBlank( field.options[ field.selectedIndex ].value, false ) )
					{
						isBlank = false;
					}
					break;
					
				case "radio":
					if ( field.checked )
					{
						isBlank = false;
					}
					break;
					
				case "checkbox":
					if ( field.checked )
					{
						isBlank = false;
					}
					break;
			}
			
		}
		
		// Exit loop as soon as we found a non-empty field
		if ( ! isBlank )
		{
			break;
		}
	}

	return isBlank;
}

//---------------------------------------------------------
// Clear value of all fields, except hidden system field
// whose name begins with 2 underscore, of a given form.
function ClearFormValue(sender)
{
	for (var i = 0; i < sender.elements.length; i++)
	{
		var field = sender.elements[i];
		
		// Clear value only if it is not a hidden system fields
		if (field.name.substr(0, 2) != "__")
		{
			switch (field.type)
			{
				case "text":
					field.value = "";
					break;
					
				case "hidden":
					field.value = "";
					break;

				case "select-one":
					field.selectedIndex = 0;
					break;
			}
		}
	}
}

//---------------------------------------------------------

function GetElementType( element )
{
	var elementType = element.type;
	
	var textTypeElementList		= "text,hidden,password,textarea";
	var toggleTypeElementList	= "checkbox,radio";
	
	if ( textTypeElementList.indexOf( elementType ) != -1 && 
		 IsHiddenRemarksField( element) == false )
	{
		elementType = "genericText";
	}
	else if ( toggleTypeElementList.indexOf( elementType ) != -1 )
	{
		elementType = "genericToggle";
	}
	
	return elementType;
}

//---------------------------------------------------------

// Check if value of a given form has changed. Return true
// if so, false otherwise.
// Note that hidden memo field is excluded from this check
// because the expression myMemoField.value == myMemoField.defaultValue
// returns false if myMemoField contains more than 1 line of text
// even though myMemoField.value has not been changed at all. It's a bug.
function IsFormDirty( formToCheck )
{
	var isFormDirty		= false;
	var elementCount	= formToCheck.elements.length;

	for ( var i = 0; i < elementCount; i++ )
	{
		var currentElement = formToCheck.elements[ i ];
		isFormDirty = IsValueChanged( currentElement );

		if ( isFormDirty )
		{
			break;
		}
	}

	return isFormDirty;
}

//---------------------------------------------------------

// Returns trun if a given field has: memo="yes" attribute
// false if memo="no" or this attribute is not defined
function IsHiddenRemarksField( element )
{
	var memoAttribute = element.memo;
	if ( memoAttribute == "undefined" )
	{
		// This element has no memo attribute defined
		return false;
	}
	else
	{
		// This element has memo attribute defined, then check its value                              
		if ( memoAttribute == "yes" )
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}

//---------------------------------------------------------

// Return true if value of a form element has changed, false if otherwise.
function IsValueChanged( element )
{
	var valueChanged = false;
	var elementType = GetElementType( element );
	
	switch ( elementType )
	{
		case "genericText":
			
			if ( element.value != element.defaultValue )
			{
				valueChanged = true;
			}
			break;

		case "genericToggle":
			if ( element.checked != element.defaultChecked )
			{
				valueChanged = true;
			}
			break;

		case "select-one":
			var optionToCheck = element.options;
			var optionCount = optionToCheck.length;
			
			for ( var j = 0; j < optionCount; j++ )
			{
				var currentOption = optionToCheck[ j ];
				if ( currentOption.selected != currentOption.defaultSelected ) 
				{
					valueChanged = true;
					break;
				}
			}
			break;
	}

	return valueChanged;
}

//---------------------------------------------------------

// Take this list: "productID,productName,unitName"
// And return this list: "productID_2,productName_2,unitName_2"
function AppendRowIDSuffix( fieldList, rowID )
{
	var fieldListBuffer = "";
	var fieldArray = fieldList.split( "," );
	
	for ( var i = 0; i < fieldArray.length; i ++ )
	{
		fieldListBuffer += "," + fieldArray[ i ] + "_" + rowID;
	}
	// Get rid of the first ","
	fieldListBuffer = fieldListBuffer.substr( 1 );
		
	return fieldListBuffer;
}

//---------------------------------------------------------

function Navigator( sender, url )
{
	sender.action = url;
	sender.submit();
	return false;
}

//---------------------------------------------------------

function SetActiveWindow( callingWindow, calledType )
{
	parent.activeWindow = callingWindow;
	if ( parent.activeWindow != null )
	{
		parent.activeWindow.calledBy = calledType;
	}
}

//---------------------------------------------------------

function GetPopUpFormUrl( formID, mode, dataID )
{
	return "showPopUpForm.aspx?formID=" + formID + "&t=off&do=" +
		mode + "&pkValue=" + dataID;
}

//---------------------------------------------------------

function PopUpFormHandler( activeDocument, fieldName, formID, callingWindow, calledType, pkValue )
{
	var fld = null;
	var val = "";
	
	if ( fieldName != null )
	{
		fld = activeDocument.getElementById( fieldName );
		
		if ( typeof( fld ) == "object" )
		{
			val = fld.value;
		}
	}
	else if ( pkValue != null )
	{
		val = pkValue;
	}
	
	if ( val != "" )
	{	// Remove "," if any.
		val = ParseNumericValue( val );
		// Debug window.open( GetPopUpFormUrl( formID, "u", val ) );
		parent.frames[ 3 ].location.replace( GetPopUpFormUrl( formID, "u", val ) );
		
		// Save reference of the window that opens this form.
		// GoBackHandler() of form.js uses this reference
		// to refresh the window that opens this form
		SetActiveWindow( callingWindow, calledType );
	}
	
	return false;
} 

//---------------------------------------------------------------

// Show a given form in a given mode in a pop-up window
function ShowPopUpForm( formID, mode, dataID, handlerFrameIndex )
{	// Do not use IsBlank() which strangely treats
	// numeric value as blank
	//var url = dataID > 0 ? GetPopUpFormUrl( formID, mode, dataID ) : GetPopUpFormUrl( formID, mode, "" );
	dataID = ( dataID == undefined ? "" : dataID );
	var url = dataID != "" ? GetPopUpFormUrl( formID, mode, dataID ) : GetPopUpFormUrl( formID, mode, "" );
	handlerFrameIndex = handlerFrameIndex == undefined ? 3 : handlerFrameIndex;
	parent.frames[ handlerFrameIndex ].location.replace( url );
	return false;
}

//------------------------------------------------------------------

// Popup a data maintenance form in insert mode
function ShowDataFormHandler( formID, callingWindow, calledType )
{
	parent.frames[ 3 ].location.replace( GetPopUpFormUrl( formID, "i", "" ) );
	// Save reference of the window that opens this form.
	// GoBackHandler() of form.js uses this reference
	// to refresh the window that opens this form
	SetActiveWindow( callingWindow, calledType );
}

//---------------------------------------------------------------

function ShowMemoForm( callingWindow, memoField )
{
	var windowFeature =	"scroll:off;dialogHeight:" + 
						memoField.winH + 
						"px;dialogWidth:" + 
						memoField.winW + 
						"px;resizable:yes;help:off;status:on;";
	
	var paramObject = new Object();
	paramObject.win = callingWindow;
	paramObject.fld = memoField;
	
	window.showModalDialog
		(
		"memoForm.aspx",
		paramObject,
		windowFeature
		);
}

//---------------------------------------------------------------

function LogOut()
{
	if ( window.confirm( parent.msgLogoutPrompt ) )
	{
		SaveWinPos( "SysMenu" );
		// End classic ASP session
		parent.frames[ 3 ].location.replace( "../report/end_session.asp" );
		var url = "logOut.aspx?";
		//window.open( url );
		parent.frames[ 4 ].location.replace( url );
	}
	return false;
}

//---------------------------------------------------------------

function ShowCalendar( targetField, formLocation )
{
	var winFeature = "";
	var fld = targetField.name;
	var val = escape( targetField.value );
	var url = "calendar.aspx?loc=" + formLocation + "&fld=" + fld + "&val=" + val;
	
	OpenWindow
		(
		url, 
		170, 
		170,
		winFeature,
		"calendar", 
		false
		)
}

//---------------------------------------------------------------

function TogglePanelBar( cols )
{
	// No need to show panel bar frame if panel bar is not loaded
	if ( parent.frames[ 0 ].location.href.indexOf( "dummy.htm" ) != -1 )
	{
		return false;
	}
	
	if ( cols == null || cols == "" )
	{
		var defaultCols = parent.TogglePanelBar_defaultCols == undefined ? "100,*" : parent.TogglePanelBar_defaultCols;
		cols = parent.stageFrameSet.cols.substring( 0, 1 ) == "0" ? defaultCols : "0,*";
	}
	
	parent.stageFrameSet.cols = cols;
	return false;
}

//---------------------------------------------------------------

function ToggleFrame( frameRows )
{
	parent.contentFrameSet.rows = frameRows;
}

//---------------------------------------------------------------

function SaveFrameHeight()
{
	parent.frameHeight = parent.contentFrameSet.rows;
}
//---------------------------------------------------------------

function RestoreFrameHeight()
{
	parent.contentFrameSet.rows = parent.frameHeight;
}

//---------------------------------------------------------------

function GetFrameHeight( frameIndex )
{
	var retValue = "";
	var rowArray = parent.contentFrameSet.rows.split( "," );
	
	for ( var i = 0; i < rowArray.length; i ++ )
	{
		if ( i == frameIndex - 1 )
		{
			retValue = rowArray[ i ];
		}
	}
	return retValue;
}

//---------------------------------------------------

// Return true if a given frame is loaded with a given URL
function IsLoadedWith( frameIndex, url )
{
	if ( parent.frames[ frameIndex ].location.href.indexOf( url ) != -1 )
	{
		return true;
	}
	else
	{
		return false;
	}
}

//---------------------------------------------------------------

function ShowNavigationFrame( callback )
{
	callback = ( callback == null ? true : callback );
	
	var dataNavFrame = parent.frames[ 5 ];

	if ( parent.reloadNavigationFrame )
	{
		if ( callback && typeof( dataNavFrame.Grid1 ) == "object" )
		{
			dataNavFrame.Grid1.Callback( 0, null, dataNavFrame.Grid1.GetEventList() );
		}
		else
		{	
			dataNavFrame.stateForm.target = "dataNavigation";
			Navigator( dataNavFrame.stateForm, dataNavFrame.location.href );
			dataNavFrame.stateForm.submit();
		}

		// Set reloadNavigation flag back to false
		parent.SetReloadNavigationFrameFlag( false );
	}
	
	// Set title of parent frame to the title of navigation list page
	parent.document.title = dataNavFrame.document.title;
	dataNavFrame.focus();
	
	ToggleFrame( "0,0,0,0,*" );
}

//---------------------------------------------------------------

function ShowMasterFrame()
{
	parent.document.title = parent.frames[ 1 ].document.title;
	ToggleFrame( "*,0,0,0,0" );
}

//---------------------------------------------------------------

// Wrapper for IsValidEmailAddress()
function CheckEmailField( fld, msg )
{
	if ( ! IsBlank( fld.value, false ) )
	{
		if ( ! IsValidEmailAddress( fld.value ) )
		{
			fld.focus();
			alert( msg );
		}
	}
}

//---------------------------------------------------------------

function GetPopupWindowFeature()
{
	return "resizable=yes";
}

//---------------------------------------------------------------

function ShowFormValue( sender )
{
	var msg = "";
	
	for ( var i = 0; i < sender.length; i ++ )
	{
		if ( sender.elements[ i ].type == "checkbox" )
		{
			msg += sender.elements[ i ].name + " = " + sender.elements[ i ].checked + "\n" ;
		}
		else
		{
			msg += sender.elements[ i ].name + " = " + sender.elements[ i ].value + "\n" ;
		}
	}
	
	window.alert( msg );
}

//----------------------------------------------------------

// Calling Sample: parent.RemoveToolbarIcon( document, document.all.celCopyRow )
function RemoveToolbarIcon( objDoc, objIconCell )
{
	if ( objIconCell == null )
	{
		return;
	}
	
	// Get index of the cell that holds the icon we going to delete
	var cellIndex = objIconCell.cellIndex;

	// First delete the cell that holds the icon
	objDoc.all.PageTitleBar.rows[ 0 ].deleteCell( cellIndex );
	// Then delete the cell that holds the vertical seperator
	// Note that the cell index is shifted after we remove
	// the one that holds the icon
	objDoc.all.PageTitleBar.rows[ 0 ].deleteCell( cellIndex );
}

//----------------------------------------------------------

function RetrieveMail()
{
	// Must load this page into frame[3]. See progressPage.aspx for reason
	parent.frames[ 3 ].location.href = parent.progressPage;
	//window.open( "mailDownload.aspx" );
	parent.frames[ 4 ].location.href = "mailDownload.aspx";
}

//----------------------------------------------------------

function ComposeMail()
{
	ToggleFrame( "*,0,0,0,0" );
	parent.frames[ 1 ].location.href = "mailCompose.aspx?mode=blank";
}

//----------------------------------------------------------

function ChopOffDecimal( stringToChop )
{
	var returnValue = stringToChop;
	var endAt = returnValue.indexOf( "." );
	
	if ( endAt > 0 )
	{
		returnValue = returnValue.substring( 0, endAt );
	}
	
	return returnValue;
}

//----------------------------------------------------------

function RangeValidator( startVal, endVal, sender, msg )
{
	startVal	 = parseFloat( startVal );
	endVal		 = parseFloat( endVal );
	var val2Validate = parseFloat( sender.value );
	
	if ( val2Validate < startVal || val2Validate > endVal )
	{
		window.alert( msg );
		sender.value = "";
		sender.focus();
		return false;
	}
	else
	{
		return true;
	}
}

//----------------------------------------------------------

function ParseNumericValue( val2Parse )
{
	var re = /,/gi;
	var val = 0;
	if ( IsBlank( val2Parse, true ) == false )
	{
		// Remove all commas, i.e. 1,500.00 to 1500.00
		val = parseFloat( val2Parse.replace( re, "" ) );
		val = isNaN( val ) ? 0 : val;
	}
	return val;
}

//----------------------------------------------------------

function Today( separater )
{
	if ( arguments.length == 0 )
	{
		separater = "/";
	}

	var today = new Date();
	var yy = today.getFullYear();
	// getMonth() returns 0 - 11, Jan - Dec
	var mm = today.getMonth() + 1;
	var dd = today.getDate();
	
	return yy.toString() + separater + mm.toString() + separater + dd.toString();
}

//----------------------------------------------------------

function DisableFormControl( frm, fldList )
{
	var excludeFieldArray = fldList.split( ";" );

	for ( var i = 0; i < frm.length; i ++ )
	{
		var ctrl = frm.elements[ i ];

		if ( ctrl.type != "hidden" ) // ingore hidden field
		{
			if ( ! IsInList( excludeFieldArray, ctrl.name ) )
			{
				switch ( ctrl.type )
				{
					case "button":
					ctrl.disabled = true;
					break;
					
					default:
					ctrl.readOnly = true;
					ctrl.runtimeStyle.backgroundColor = "gainsboro";
					break;
				}
			}
		}
	}
}

//------------------------------------------------------------------

function IsInList( listArray, item )
{
	var found = false;
	
	for ( var row in listArray )
	{
		if ( listArray[ row ] == item )
		{
			found = true;
			break;
		}
	}
	
	return found;
}

//------------------------------------------------------------------

function ToDecimal( x )
{
	// Remove all commas, i.e. 1,500.00 to 1500.00
	var re = /,/gi;
	x = parseFloat( x.replace( re, "" ) );
	x = isNaN( x ) ? 0 : x;
	return x;
}

//------------------------------------------------------------------

function IsXGreaterThanY( x, y )
{
	return ( ToDecimal( x ) > ToDecimal( y ) ? true : false );
}

//------------------------------------------------------------------

// Clear value of field listed in comma-spearated list in a give document
function ClearFieldValue( targetDoc, fieldList )
{
	var fieldArray = fieldList.split( "," );
	
	for ( var fieldIndex in fieldArray )
	{
		var fld =  targetDoc.getElementById( fieldArray[ fieldIndex ] );
		
		if ( fld != null )
		{
			fld.value = "";
		}
	}
}

//------------------------------------------------------------------

function PushFileToClient( param )
{
	var url = "downloadFile.aspx?" + param;
	OpenWindow( url, 280, 180, "resizable=yes,scrollbars=yes",  "winDownload", true );
	return false;
}

//------------------------------------------------------------------

function SetTabIndex( index )
{
	parent.selectedTabID = index;
}

//------------------------------------------------------------------

function SetDetailTabIndex( index )
{
	parent.selectedDetailTabID = index;
}

//------------------------------------------------------------------

function GetTabControl( doc, tabIndex )
{
	return doc.getElementById( "TabItem_" + tabIndex );
}

//---------------------------------------------------------

function GetWindowFeature( height, width, type )
{
	var windowFeature =	"";
	switch ( type )
	{
		case 1: // Feature for modal window
		windowFeature =	"scroll:off;dialogHeight:" + height + "px;" + 
			"dialogWidth:" + width + "px;" + 
			"resizable:no;help:off;status:on;";
		break;
		
		case 2: // Feature for normal window
		windowFeature =	"scroll:on;height:" + height + "px;" + 
			"width:" + width + "px;" + 
			"resizable:yes;status:on;";
		break;
	}

	return windowFeature;
}

//---------------------------------------------------------

// Convert a date string to date object
function StringToDate( str )
{	// Source date must be in YMD format
	// Replace date separator of source date from "-" to "/"
	str = str.replace( /-/g, "/" );
	// Split year, month and day into array
	var dateParts = str.split( "/" );
	// Create a new date object and set its year, month and day
	// property according to source date	
	var objDate = new Date();
	// Note that we need to subtract month by 1 because month part is 0 base
	objDate.setFullYear(dateParts[ 0 ], dateParts[ 1 ] - 1, dateParts[ 2 ] );
	/*switch ( dateFormat )
	{
		case "YMD":
		// Note that we need to subtract month by 1 because month part is 0 base
		objDate = new Date( dateParts[ 0 ], ( dateParts[ 1 ] - 1 ), dateParts[ 2 ] );
		break;

		case "MDY":
		objDate = new Date( dateParts[ 2 ], ( dateParts[ 0 ] - 1 ), dateParts[ 1 ] );
		break;

		case "DMY":
		objDate = new Date( dateParts[ 2 ], ( dateParts[ 1 ] - 1 ), dateParts[ 0 ] );
		break;
	}*/
	return objDate;
}

//---------------------------------------------------------

function OnCalendarChange( calendar )
{
	var objDate = calendar.GetSelectedDate();
	var yr = objDate.getYear();
	var mo = objDate.getMonth() + 1; // add 1 because month is 0 base
	var dy = objDate.getDate();

	var strDate;
	switch ( dateFormat )
	{
		case "YMD":
		strDate = yr + dateSeparator + mo + dateSeparator + dy;
		break;

		case "MDY":
		strDate = mo + dateSeparator + dy + dateSeparator + yr;
		break;

		case "DMY":
		strDate = dy + dateSeparator + mo + dateSeparator + yr;
		break;
	}
	
	parent.currentObject.value = strDate;
}

//---------------------------------------------------------

// Returns a one dimension array from a two 
// dimension one for a given row ID.
function GetArrayRow( sourceArray, targetID )
{	
	var retVal = new Array();
	var quit = false;
	
	for ( var rowIdx in sourceArray )
	{	
		for ( var colIdx in sourceArray[rowIdx] )
		{	// Assuming the first column as row ID
			if ( sourceArray[rowIdx][0] == targetID )
			{
				retVal = sourceArray[rowIdx];
				quit = true;	
			}
		}
		if ( quit )
		{
			break;
		}	
	}
	
	return retVal;
}

//----------------------------------------------------------

function ExtractUrlParam( url, param )
{
	// Extract everything after the ? mark.
	url = url.substring( url.indexOf( "?" ) + 1 );
	var paramList = url.split( "&" );
	
	var paramValue = null;
	
	for ( var i in paramList )
	{	// Extract parameter name
		var n = paramList[ i ].substring( 0, paramList[ i ].indexOf( "=" ) );
		if ( n == param )
		{	// Extract parameter value
			paramValue = paramList[ i ].substring( paramList[ i ].indexOf( "=" ) + 1 );
			break;
		}
	}
	
	return paramValue;
}

//---------------------------------------------------------------

// Append or modify value of a given parameter of a given url
function SetUrlParamValue( url, param, val )
{
	var v = ExtractUrlParam( url, param );
	
	if ( v == null )
	{
		url = url + "&" + param + "=" + val;
	}
	else
	{
		url = url.replace( param + "=" + v, param + "=" + val );
	}
	return url;
}

//---------------------------------------------------------------

// pickListInfo is in appStage.aspx
function GetPickListInfo( pickListID )
{	
	return GetArrayRow( pickListInfo, pickListID );
}

//---------------------------------------------------------------

function ExtractQueryString( win )
{
	return win.location.href.replace( win.location.protocol + "//" +
		win.location.hostname +
		win.location.pathname + "?", "" );
}

//---------------------------------------------------------------

function DisplayImage()
{
	var fieldArray = ExtractQueryString( window ).split( "&" );
	
	for ( var fieldIndex in fieldArray )
	{
		var src = unescape( ExtractNameValuePair(fieldArray[ fieldIndex ], false ) );
		if ( src.length != 0 )
		{
			document.writeln( "<li><img src='" + src + "'></li>" );
		}
	}
}

//---------------------------------------------------------------

// Extract numeric suffix from a given string,
// i.e. extract 2 from string myControl_2
function ExtractNumericSuffix( x, y )
{
	return parseInt( x.substr( x.lastIndexOf( y ) + 1 ) );
}

//---------------------------------------------------------------

function SetCookie( name, value, expiryDay, path, domain, secure )
{
	// set time, it's in milliseconds
	var today = new Date();
	today.setTime( today.getTime() );
	// if the expiryDay variable is set, make the correct expiryDay time, the
	// current script below will set it for x number of days, to make it
	// for hours, delete * 24, for minutes, delete * 60 * 24
	if ( expiryDay )
	{
		expiryDay = expiryDay * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expiryDay) );

	document.cookie = name + "=" +escape( value ) +
		( ( expiryDay ) ? ";expires=" + expires_date.toGMTString() : "" ) +
		( ( path ) ? ";path=" + path : "" ) + 
		( ( domain ) ? ";domain=" + domain : "" ) +
		( ( secure ) ? ";secure" : "" );
}

//--------------------------------------------------

function GetCookie( name )
{
	var start = document.cookie.indexOf( name + "=" );
	var len = start + name.length + 1;
	if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) )
	{
		return null;
	}
	if ( start == -1 ) return null;
	var end = document.cookie.indexOf( ";", len );
	if ( end == -1 ) end = document.cookie.length;
	return unescape( document.cookie.substring( len, end ) );
}

//--------------------------------------------------

function DeleteCookie( name, path, domain ) 
{
	if ( GetCookie( name ) ) document.cookie = name + "=" +
			( ( path ) ? ";path=" + path : "") +
			( ( domain ) ? ";domain=" + domain : "" ) +
			";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}

//--------------------------------------------------

function SaveWinPos( windowID )
{
	var top = window.screenTop - 30;
	var left = window.screenLeft - 4;
	var width = document.body.clientWidth;
	var height = document.body.clientHeight;

	// window is maximized
	if ( top < 0 || left < 0 )
	{
		top = 0;
		left = 0;
		width = width - 8;
		height = height - 8;
	}
	
	var winPos = "top=" + top + ",left=" + left + 
		",width=" + width + ",height=" + height;
	
	SetCookie( windowID + "_WinPos", winPos, 365, "/", null, null );
}

//--------------------------------------------------

function GetSysMenuWinFeature()
{
	var winPos = GetCookie( "SysMenu_WinPos" );
	if ( winPos == null )
	{	// Default system window position
		winPos = "top=0,left=0,width=800,height=600";
	}

	var retVal = "resizable=yes,status=yes,scrollbars=no," + winPos;

	return retVal;
}

//--------------------------------------------------

function SaveDataFormWinPos( formID )
{
	SaveWinPos( "DataForm_" + formID );
}

//--------------------------------------------------

// Show menu that is linked to an item of the toolbar
function ShowLinkedMenu( menu, srcCtrl )
{
	var ICON_PIXEL = 16;
	var TOOLBAR_HEIGHT = 21
	
	var imageOffset = 0;
	if ( srcCtrl.offsetParent.offsetLeft >= ICON_PIXEL )
	{
		imageOffset = 17;
	}

	var x = 0;
	var thisOffsetParent = srcCtrl;
	
	while ( thisOffsetParent != null )
	{
		x += thisOffsetParent.offsetLeft;
		thisOffsetParent = thisOffsetParent.offsetParent;
	}
	
	menu.ShowContextMenu( x - imageOffset + 1, TOOLBAR_HEIGHT );
}

//---------------------------------------------------------------

// Used by formDetail.aspx
function ShowMenu( menu, srcCtrl )
{
	var x   = 0;
	var y	= srcCtrl.offsetHeight;
	var thisOffsetParent = srcCtrl;
	
	while ( thisOffsetParent != null )
	{
		x += thisOffsetParent.offsetLeft;
		y += thisOffsetParent.offsetTop;
		thisOffsetParent = thisOffsetParent.offsetParent;
	}

	menu.ShowContextMenu( x, y );
}

//---------------------------------------------------------------

function FormatNumber(amount)
{
	var delimiter = ",";
	var a = amount.split('.',2);
	var d = a[1];
	var i = parseInt(a[0]);
	
	if(isNaN(i)) { return ''; }
	
	var minus = '';
	
	if(i < 0) { minus = '-'; }
	i = Math.abs(i);
	var n = new String(i);
	var a = [];
	while(n.length > 3)
	{
		var nn = n.substr(n.length-3);
		a.unshift(nn);
		n = n.substr(0,n.length-3);
	}
	
	if(n.length > 0) { a.unshift(n); }
	n = a.join(delimiter);
	if(d.length < 1) { amount = n; }
	else { amount = n + '.' + d; }
	
	amount = minus + amount;
	return amount;
}

//---------------------------------------------------------------

function ManageWinPosition( cmd )
{
	if ( cmd == "save" )
	{
		parent.thisTop = parent.window.screenTop - 30;
		parent.thisLeft = parent.window.screenLeft - 4;
		parent.thisWidth = parent.window.document.body.clientWidth + 12;
		parent.thisHeight = parent.window.document.body.clientHeight + 60;	
	}
	else if ( cmd == "restore" )
	{
		parent.window.moveTo(parent.thisLeft, parent.thisTop);
		parent.window.resizeTo(parent.thisWidth, parent.thisHeight);
	}
}

//---------------------------------------------------------------

function ShowPickList( sender, pickListID, params, trgFld, srcFld, rowID )
{	
	// Get metadata of this lookup control
	var pickListMetadata = parent.GetPickListInfo( pickListID );
	
	//var pickListInfo = parent.GetPickListInfo( 60 );
	//window.alert( pickListInfo[ 1 ] );
	//window.alert( pickListInfo[ 2 ] );
	
	// Sample: ctrlInfo[0] = new Array('2','1','LookupCompany','companyID','companyNamePrimary','2',params,'False');
	//var pickListID = ctrlInfo[5]; // 5 is index of pickListFK column

	trgFld = ( rowID == null ? trgFld : parent.AppendRowIDSuffix( trgFld, rowID ) );

	var url = "pickList.aspx?firstLoad=yes&pickListID=" + pickListID + 
		"&trgFrmIdx=" + ( rowID == null ? 1 : 2 ) +
		"&target=" + trgFld + "&source=" + srcFld;
	
	//parent.targetForm = targetLocation; // master or detail
	//parent.activeDocument = ( rowID == null ? MasterFrame.document : DetailFrame.document ); 
	parent.OpenWindow( url + "&" + params, pickListMetadata[1], pickListMetadata[2], "resizable=yes,alwaysRaised=yes,scrollbars=yes", "pickList_" + pickListID, true ); 
}

//---------------------------------------------------------
// Add an item to a comma-separated list. Initial value
// of the list must have a comma.
function AddItemToList( list, item )
{
	var isInList = false;

	if ( list.indexOf( "," + item + "," ) != -1 )
	{
		isInList = true;
	}
	
	if ( ! isInList )
	{
		list += item + ",";
	}
	
	return list;
}

//---------------------------------------------------------
// Remove an item from a comma-separated list. Initial value
// of the list must have a comma.
function RemoveItemFromList( list, item )
{
	return list.replace( "," + item + ",", "," );
}

//---------------------------------------------------------

function ManagePhotoGeneric( topSrc )
{
	var url = "appStage.aspx?hidePanelBar=yes&topSrc={" + topSrc + "}";

	OpenWindow
		(
		url, 
		800, 
		600, 
		"resizable=yes", 
		"winManagePhoto", 
		true
		)
}

//---------------------------------------------------------