// This set of functions are general includes for use with HTML form validation.

// Adapted (and simplified/made non-browser specific by Simon Nix) from code outlined in an
// article by Carl Nolan in the January 1999 issue of Microsoft Interactive Developer.
// Refer to: http://www.microsoft.com/mind/0199/inthisissue0199.htm

// Last Updated by: 
//		K Kongshavn 14/4/1999.	Added test for zero length to IsNotValidACN().
//		K Kongshavn 22/4/1999.	Added IsLong(), SetInitialFocus().
//		K Kongshavn 22/5/1999.	Added DisplayState() to hide/display State when change Country.
//		K Kongshavn 26/5/1999.	Added SetRadioItem(), GetCheckedRadioValue(), SetMailingMethodForState(), 
//										SetMailingMethodForCountry(), IsNotValidMailingMethod().
//		K Kongshavn 25/6/1999.  Added IsNotValidUserId(), IsNotWithoutBlanks
//		S Nix			05/7/1999.  Added TitleCase().

function msieversion() {
	// This function returns Internet Explorer's major version number,
	// or 0 for other browsers. It works by finding the "MSIE " string and
	// extracting the version number following the space, up to the decimal
	// point, ignoring the minor version number.
	
	var ua = window.navigator.userAgent
	var msie = ua.indexOf ( "MSIE " )
	if ( msie > 0 )      // If IE, return version number
		return parseInt (ua.substring (msie+5, ua.indexOf (".", msie )))
	else                 // If another browser, return 0
		return 0
}


function display_name(item) {
	var strDisplay;
	var version = msieversion();
	// If using IE 4.0 or later, use the value of the TITLE tag as the error display name.
	if (version >= 4)
		strDisplay = item.getAttribute("TITLE", 0); 	
	if (strDisplay==null || strDisplay=="")
		strDisplay="Field";
	return strDisplay;
}


function default_value(item) {
	var strDefault = item.defaultValue;
	if (strDefault==null || strDefault=="")
		strDefault="";
	return strDefault;
}


function trim_string() {
	var ichar, icount;
	var strValue = this;
	ichar = strValue.length - 1;
	icount = -1;
	while (strValue.charAt(ichar)==' ' && ichar > icount)
		--ichar;
	if (ichar!=(strValue.length-1))
		strValue = strValue.slice(0,ichar+1);
	ichar = 0;
	icount = strValue.length - 1;
	while (strValue.charAt(ichar)==' ' && ichar < icount)
		++ichar;
	if (ichar!=0)
		strValue = strValue.slice(ichar,strValue.length);
	return strValue;
}


function date_toSimpleForm() {
	var toSimpleForm = new String;
	toSimpleForm = this.toLocaleString();
	toSimpleForm = toSimpleForm.substring(0,toSimpleForm.indexOf(' '));  // Remove time stamp.
	return toSimpleForm;
}


function IsBlank(item) {
	var strErrorMsg = display_name(item) + " cannot be blank.";
	item.value=item.value.Trim();
	if (item.value.length==0) {
		item.focus();
		alert(strErrorMsg);
		return true;
	}
	return false;
}


function IsNotInteger(item) {
	var strErrorMsg = display_name(item) + " must be a valid integer.";
	item.value=item.value.Trim();
	var intValue = parseInt(item.value,10);  //Convert to integer base 10.
	if (isNaN(intValue)) {
		item.focus();
		alert(strErrorMsg);
		return true;
		}
	else {
		item.value = intValue;		
	}
	return false;
}


function IsNotNumber(item) {
	var strErrorMsg = display_name(item) + " must be a valid number.";
	var intValue = parseInt(item.value);			// Convert to integer.
	var realValue = parseFloat(item.value);		// Convert to floating point.
	if (isNaN(intValue) || isNaN(realValue)) {
		item.focus();
		alert(strErrorMsg);
		return true;
	}
	return false;
}


function IsNotInRange(item, intLow, intHigh) {
	var strErrorMsg = display_name(item);
	if (IsNotNumber(item))
		return true;
	var itemValue = new Number(item.value);
	if ((itemValue < intLow || itemValue > intHigh)) {
		item.focus();
		alert(strErrorMsg + " can only have values between " + intLow + " and " + intHigh+ ".");
		return true;
	}
	return false;
}


function IsNotLength(item, intLength) {
	var strErrorMsg = display_name(item);
	if (item.value.length != intLength) {
		item.focus();
		alert(strErrorMsg + " must have exactly " + intLength + " characters.");
		return true;
	}
	return false;
}


function IsShort(item, intLength) {
	var strErrorMsg = display_name(item);
	if (item.value.length < intLength) {
		item.focus();
		alert(strErrorMsg + " must be at least " + intLength + " characters long.");
		return true;
	}
	return false;
}


function IsLong(item, intLength) {
	var strErrorMsg = display_name(item);
	if (item.value.length > intLength) {
		item.focus();
		alert(strErrorMsg + " must not be greater than " + intLength + " characters long.");
		return true;
	}
	return false;
}


function IsNotValidDate(item) {
	var strErrorMsg = display_name(item);
	if (isNaN(Date.parse(item.value))) {
		item.focus();
		alert(strErrorMsg + " must be a valid date (eg 29 Oct 1998).");
		return true;
	}
	var dtItem = new Date(Date.parse(item.value));
	item.value = dtItem.toSimpleForm();
	return false;
}


function ItemNotSelected(item) {
	var strErrorMsg = display_name(item) + " must be a valid selection.";
	if (item.selectedIndex==0) {
		item.focus();
		alert(strErrorMsg);
		return true;
	}
	return false;
}


function RadioNotSelected(item) {
	// returns false if at a radio item has been selected.
	var strErrorMsg = "Please select one of the " + display_name(item[0]) + " options.";
	for (var i=0; i < item.length; i++) {
		if (item[i].checked) {
			return false;
		}
	}
	item[0].focus();
	alert(strErrorMsg);
	return true;
}

function CheckBoxNotSelected(item) {
	// returns false if at least one CheckBox item has not been selected.
	var strErrorMsg = "Please select at least one of the " + display_name(item[0]) + " options.";
	for (var i=0; i < item.length; i++) {
		if (item[i].checked) {
			return false;
		}
	}
	item[0].focus();
	alert(strErrorMsg);
	return true;
}


function IsNotValidZip(item) {
	var strErrorMsg = display_name(item) + " must be of the form 99999-9999.";
	item.value=item.value.Trim();
	if (!(/^\d{5}$/.test(item.value) || /^\d{5}-\d{4}$/.test(item.value))) {
		item.focus();
		alert(strErrorMsg);
		return true;
	}
	return false;
}


function IsNotValidPostcode(item) {
	var strErrorMsg = display_name(item) + " must be between 0800 and 0899 or between 1000 and 7499 or between 8000 and 9729.";
	item.value=item.value.Trim();
	if (IsNotLength(item, 4))
		return true;
	if (!(/08[0-9][0-9]/.test(item.value) || /[1-7][0-9][0-9][0-9]/.test(item.value) || /[8-9][0-7][0-9][0-9]/.test(item.value))) {
		item.focus();
		alert(strErrorMsg);
		return true;
	}
	return false;
}


function IsNotValidPhone(item) {
	var strErrorMsg = display_name(item) + " must be of the form 9999-9999.";
	item.value=item.value.Trim();
	if (!(/^\d{4}-\d{4}$/.test(item.value))) {
		item.focus();
		alert(strErrorMsg);
		return true;
	}
	return false;
}


function IsNotValidACN(item) {
	var strErrorMsg = display_name(item) + " must be of the form 999-999-999.";
	item.value=item.value.Trim();
	if (item.value.length==0) return false;
	if (!(/^\d{3}-\d{3}-\d{3}$/.test(item.value))) {
		item.focus();
		alert(strErrorMsg);
		return true;
	}
	return false;
}


function IsNotValidEmail(item) {
	var strErrorMsg = display_name(item) + " is not a valid Email address.";
	item.value=item.value.Trim();
	if (item.value.length==0) return false;
	if (!(/^[\w\.]+@[0-9a-z\.]+$/.test(item.value))) {
		item.focus();
		alert(strErrorMsg);
		return true;
	}
	return false;
}

function IsNotValidUserId(item) {
	var strErrorMsg = display_name(item) + " cannot contain any of the following characters: colon, semi-colon, quote, double-quote, comma, period or blank.";
	item.value=item.value.Trim();	
	if (item.value.length==0) return false;	
    if(/[:;'",\.\ ]/.test(item.value)) {
        item.focus();
        alert(strErrorMsg);
        return true;
    }
    return false;
}

function IsNotWithoutBlanks(item) {
	var strErrorMsg = display_name(item) + " cannot contain any blank characters.";
	item.value=item.value.Trim();	
	if (item.value.length==0) return false;	
    if(/[\ ]/.test(item.value)) {
        item.focus();
        alert(strErrorMsg);
        return true;
    }
    return false;
}

function IsNotEqual(item1,item2) {
	var strErrorMsg = display_name(item1) + " is not equal to " + display_name(item2);
	item1.value=item1.value.Trim();
	item2.value=item2.value.Trim();
	if (item1.value != item2.value) {
		item1.focus();
		alert(strErrorMsg);
		return true;
	}
	return false;
}


/* Function to convert a string to Title Case (first
character upper-case - all the rest lower case */

function TitleCase(item) {
	var toconvert = item.value.Trim();
	if (toconvert.length >= 1) {
		var left = toconvert.charAt(0).toUpperCase();
		var right = toconvert.substr(1).toLowerCase();
		item.value = left + right;
	}
}

// Extend the string object to include a trim function
String.prototype.Trim = trim_string;
// Extend the date object to include a simple form string conversion
Date.prototype.toSimpleForm = date_toSimpleForm;

// This set of function are for processing the key press event
// Used to restrict input on numerics and pure textual fields

function kpIsInteger() {
	if ((event.keyCode < 48 || event.keyCode > 57))
		event.returnValue = false;
}


function kpIsNumeric() {
	if ((event.keyCode != 46) && (event.keyCode < 48 || event.keyCode > 57))
		event.returnValue = false;
	if (event.keyCode == 46) {
		if (event.srcElement.value.indexOf(".") > -1)
			event.returnValue = false;
	}
}


function kpIsCharacter() {
	if ((event.keyCode < 65 || event.keyCode > 90) && (event.keyCode < 97 || event.keyCode > 122))
		event.returnValue = false;
}


function kpConvertToUppercase() {
	if ((event.keyCode >= 97 && event.keyCode <= 122))
		event.keyCode -= 32;
}


function kpConvertToLowercase() {
	if ((event.keyCode >= 65 && event.keyCode <= 90))
		event.keyCode += 32;
}


function kpSetup() {
	this.Integer = kpIsInteger;
	this.Numeric = kpIsNumeric;
	this.Character = kpIsCharacter;
	this.ConvertToUpperCase = kpConvertToUppercase;
	this.ConvertLowerCase = kpConvertToLowercase;
	return this;
}

var keyPressInput = new Object;
keyPressInput = kpSetup();

function SetInitialFocus() {
	// Call WindowOnLoad event to set focus to first INPUT or SELECT field in a form.
	inpEl = document.forms(0).elements;
	if (inpEl.length > 0) {		// There is a form on the page
		for (var i = 0; i < inpEl.length; i++) {
			if ((inpEl(i).tagName == "INPUT" && inpEl(i).type != "hidden" 
				&& !inpEl(i).disabled) || inpEl(i).tagName == "SELECT")	{
				inpEl[i].focus();
				break;
			}
		}
	}
	window.scrollTo(0,0);
}

// function DisplayState:
//		Hide State listbox if Country listbox is set to an overseas country;
//		Display State listbox if Country listbox is set to Australia or blank.
//		Call in WindowOnLoad() and Country listbox's onchange() event.
// Parameters:	
//		lstCountry: Country listbox, eg document.forms(0).lstPostalCountry.
//		lstState: linked State listbox, eg document.forms(0).lstPostalState.
//		lblState: Label ("State/Territory") associated with State listbox, 
//			eg document.all.lblPostalState, where lblPostalState is the ID 
//			of the <TD> storing the label.
//		lblAustraliaOnly: Like lblState, the label "(Australia only)" associated 
//			with State listbox.
//		astrCountryLastSelected: name of a static single-element array declared in 
//			javascript on  calling ASP page and used to store last Country selected.  
//			Declare the array on the calling ASP page as an empty array as follows:
//			var astrCountryLastSelected = new Array(). It will be initialised when 
//			the browser first loads the page and its value will be maintained (and 
//			changed) during each call to DisplayState().
//		aintStateLastSelected: name of single-element array similar to 
//			astrCountryLastSelected, but used to store last State selected.  
//		conAustralia: value for "Australia" of the RefCountryId column in 
//			tblRefCountry (currently "0").
// Note: Arrays are used for CountryLastSelected and StateLastSelected because
//	they can be passed by reference and their new values are returned to the calling page.

function DisplayState(lstCountry, lstState, lblState, lblAustraliaOnly,
	astrCountryLastSelected, aintStateLastSelected, conAustralia) { 
	
	var strCurrentCountryId = lstCountry.value;									
	var blnSetStateAndShow = 
		(strCurrentCountryId == conAustralia || strCurrentCountryId == "")
		&&	((aintStateLastSelected.length == 0)
		|| (astrCountryLastSelected[0] != conAustralia && astrCountryLastSelected[0] != "")	);	
		// Set true if user changes Country from Overseas to Australia/blank
		// or if, during initial load of screen, country is Australia/Blank 

	var blnClearStateAndHide = 
		(strCurrentCountryId != conAustralia && strCurrentCountryId != "") 
		&& ((aintStateLastSelected.length == 0)
		|| (astrCountryLastSelected[0] == conAustralia || astrCountryLastSelected[0] == ""));
		// Set true if user changes Country from Australia/blank to Overseas 
		// or if, during initial load of screen, country is Overseas				

	if (aintStateLastSelected.length == 0 ) // first time through; store initial state
		aintStateLastSelected[0] = lstState.selectedIndex;
			
	if (blnSetStateAndShow) {
		lstState.selectedIndex = aintStateLastSelected[0];			
		lblState.style.display=""; //ie show
		lblAustraliaOnly.style.display="";							
		lstState.style.display="";							
		if (strCurrentCountryId == conAustralia && !lstState.disabled)
			lstState.focus();				
	} else if (blnClearStateAndHide){
		lblState.style.display="none";		
		lblAustraliaOnly.style.display="none";										
		lstState.style.display="none";				
		aintStateLastSelected[0] = lstState.selectedIndex;
		lstState.selectedIndex=0;			
	}
	// else leave as is.
	astrCountryLastSelected[0] = strCurrentCountryId;  

	return true;
}

function SetRadioItem(optCollection, strOptionToSet, blnChecked) {
	// Purpose:		Sets a specified radio button (in a group) ON (.checked=true) or OFF.
	// Parameters: 
	// - optCollection: the collection of radio buttons with same id.
	// - strOptionToSet: the value of the radio button that is to be set. 
	// - blnChecked: true if want to turn radio button ON (.checked=true), false if want OFF.
	for (var i=0; i<optCollection.length; i++) {		
		if (optCollection[i].value == strOptionToSet) {
			optCollection[i].checked = blnChecked;
			break;
		}
	}
	return true;
}

function GetCheckedRadioValue(optCollection) {
	// Purpose:	Retrieves value of currently checked radio button (in a group) 
	// Parameters: 
	// - optCollection: the collection of radio buttons with same id.
	// Returns:	Value of the radio button that is CHECKED (on).
	var strValue = "";
	for (var i=0; i<optCollection.length; i++) {
		if (optCollection[i].checked) {
			strValue = optCollection[i].value;
			break;
		}
	}
	return strValue;
}	

function SetMailingMethodForState(optsMailing, strStateId, conACT, conNSW, 
			conMailingMethodACTNSW, conMailingMethodOtherStates, 
			conMailingMethodInternal, conMailingMethodDipBag) {
	// Purpose:	Call from Onchange event for State list box. Sets Mailing Method to
	//	 'ACT/NSW' or 'Other States' as appropriate to new value of state, as long 
	//	 as Mailing Method is not already "Diplomatic Bag" or "Internal Mail".
	// Parameters: 
	// - optsMailingMethod: the collection of radio buttons with same id.
	// - strStateId: the current value of the State Listbox
	// - conACT, conNSW: values from common.asp for steACT and steNSW
	// - conMailingMethodACTNSW, etc.: values from common.asp for addMailingMethodACTNSW, etc.
	var strMailing = GetCheckedRadioValue(optsMailing);
	if (strMailing != conMailingMethodDipBag && strMailing != conMailingMethodInternal) {
		if (parseInt(strStateId) > 0) {
			if (strStateId == conACT || strStateId == conNSW)
				SetRadioItem(optsMailing, conMailingMethodACTNSW, true);
			else 
				SetRadioItem(optsMailing, conMailingMethodOtherStates, true);			
		}
		else  { //ensure a State-related mailing method not selected
			SetRadioItem(optsMailing, conMailingMethodACTNSW, false);
			SetRadioItem(optsMailing, conMailingMethodOtherStates, false);						
		}
	}
}	

function SetMailingMethodForCountry(optsMailing, strCountryId, 
			conAustralia, conMailingMethodOverseas, 
			conMailingMethodInternal, conMailingMethodDipBag) {
	// Purpose:	Call from Onchange event for Country list box. Sets or clears Mailing
	//	 Method 'Overseas' as appropriate to new value of country, as long as Mailing 
	//	 Method is not already "Diplomatic Bag" or "Internal Mail".
	// Parameters: 
	// - optsMailingMethod: the collection of radio buttons with same id.
	// - strCountryId: the current value of the Country Listbox
	// - conAustralia: value from common.asp for ctyAustralia
	// - conMailingMethodOverseas, etc.: values from common.asp for addMailingMethodOverseas, etc.
	if (strCountryId == conAustralia || strCountryId == "")  //clear Overseas Mailing Method, if set
		SetRadioItem(optsMailing, conMailingMethodOverseas, false);
	else { // Set Overseas Mailing Method, if not already Diplomatic Bag or Internal
		var strMailing = GetCheckedRadioValue(optsMailing);
		if (strMailing != conMailingMethodDipBag && strMailing != conMailingMethodInternal)
			SetRadioItem(optsMailing, conMailingMethodOverseas, true);
	}
}


function IsNotValidMailingMethod(optsMailing, strStateId, strCountryId, 
									conAustralia, conACT, conNSW, conMailingMethodACTNSW, 
									conMailingMethodOtherStates, conMailingMethodOverseas,
									conMailingMethodInternal, conMailingMethodDipBag) {
// Purpose: Call from FormValidator() to validate Mailing Method of an address
// Parameters: ref. SetMailingMethod functions above.
// Note: Assumes have already checked that rest of address fields are valid 
	var strErrMsg = ""; 
	var strMailing = "";
	var intMailing = -1;
	if (RadioNotSelected(optsMailing))
		return true;
	for (var i=0; i<optsMailing.length; i++) {
		if (optsMailing[i].checked) {
			strMailing = optsMailing[i].value;
			intMailing = i;
			break;
		}
	}
	if (strMailing != conMailingMethodDipBag && strMailing != conMailingMethodInternal) {
		if (strCountryId == conAustralia) {
			if (strStateId == conACT || strStateId == conNSW) {
				if (strMailing != conMailingMethodACTNSW)
					strErrMsg = display_name(optsMailing[0]) + " does not match selected State and Country.";
			}
			else {
				if (strMailing != conMailingMethodOtherStates)
					strErrMsg = display_name(optsMailing[0]) + " does not match selected State and Country.";
			}
		}
		else if (strMailing != conMailingMethodOverseas)
			strErrMsg = display_name(optsMailing[0]) + " does not match selected Country.";
	}
	if (strErrMsg.length > 0) {
		if (intMailing < 0)
			intMailing = 0;
		optsMailing[intMailing].focus();
		alert(strErrMsg);
		return true;
	}
	return false;
}
