var REQUIRED_MSG = 'Required';
var METHOD_RESULT_PASS = 'P';
var METHOD_RESULT_FAIL = 'F';
var SELECT_EMPTY_VALUE = '-1';
function validate(theForm) {
	// break out of script if browser doesn't understand how to get a form's elements
	if(!theForm.elements) {
		return false;
	}
	var formValid = true;
	var vr = null; // vr = validation result
	var inputs = theForm.elements;
	var knownElement = true;
	for (var i = 0; i < inputs.length; i++) {
		knownElement = true;
		switch (inputs[i].type) {
			case 'text': vr = validateTextField(inputs[i]); break;
			case 'password': vr = validatePasswordField(inputs[i]); break;
			case 'select-one': vr = validateSelectOne(inputs[i]); break;
			case 'checkbox': vr = validateCheckbox(inputs[i]); break;
			case 'radio': vr = validateRadio(inputs[i]); break;
			case 'textarea': vr = validateTextArea(inputs[i]); break;;
			case 'hidden': vr = validateHidden(inputs[i]); break;
			case 'file': vr = validateFile(inputs[i]); break;
			default : knownElement = false;
		}
		if (knownElement) {
			if (!processValidationResult(vr, inputs[i])) {
				formValid = false;
			}
		}
	}
	return formValid;
}

function validatePasswordField(field) {
	var result = new Array(METHOD_RESULT_PASS, null);
	if (field.value != null) {
		field.value = trim(field.value);
	}
	var emptyValue = isEmpty(field.value);
	var classes = field.className.split(' ');
	for (var i = 0; (i < classes.length && (result[0] == METHOD_RESULT_PASS)); i++) {
		if (classes[i] == 'required') {
			result = validateRequiredTextFieldValue(field.value);
		} else if (classes[i] == 'password') {
			result = validatePassword(field.value);
		} else if (classes[i] == 'userPassword') {
			result = validateUserPassword(field.value);
		}
	}
	return result;
}
function validateTextField(field) {
	var result = new Array(METHOD_RESULT_PASS, null);
	if (field.value != null) {
		field.value = trim(field.value);
	}
	var emptyValue = isEmpty(field.value);
	var classes = field.className.split(' ');
	for (var i = 0; (i < classes.length && (result[0] == METHOD_RESULT_PASS)); i++) {
		if (classes[i] == 'required') {
			result = validateRequiredTextFieldValue(field.value);
		}
		if (classes[i] == 'auRegistrantId') {
			result = validateAuRegistrantId(field);
		} else if (classes[i] == 'auEligibilityId') {
			result = validateAuEligibilityId(field);
		} else if (!emptyValue) {
			if (classes[i] == 'contactId') {
				result = validateContactId(field.value);
			} else if (classes[i] == 'password') {
				result = validatePassword(field.value);
			} else if (classes[i] == 'email') {
				if (!validateEmail(field.value)) {
					result[0] = METHOD_RESULT_FAIL;
					result[1] = field.value + ' is an invalid e-mail address';
				}
			} else if (classes[i] == 'hostName') {
				result = validateHostName(field.value);
			} else if (classes[i] == 'ipv4Address') {
				result = validateIpv4Address(field.value);
			} else if (classes[i] == 'ipv6Address') {
				result = validateIpv6Address(field.value);
//			} else if (classes[i] == 'domainName') {
//				result = validateDomainName(field.value);
			} else if (classes[i] == 'telephone') {
				result = validateTelephone(field.value);
			} else if (classes[i] == 'normalised') {
				result = validateNormalised(field.value);
			} else if (classes[i] == 'usascii') {
				result = validateUSASCII(field.value);
			} else if (classes[i] == 'date_ar') {
				result = validateDate(field.value);
			} else if (classes[i] == 'domainLabel') {
				result = validateDomainLabel(field.value);
			} else if (classes[i] == 'reservedName') {
                result = validateReservedName(field.value);
            } else if (classes[i] == 'amount') {
                result = validateAmount(field.value);
            } else if (classes[i] == 'amount_no_limit') {
                result = validateAmountNoLimit(field.value);
            } else if (classes[i] == 'amount_negative_no_limit') {
                result = validateNegativeAmountNoLimit(field.value);
            } else if (classes[i] == 'integer') {
                result = validateInteger(field.value);
            } else if (classes[i] == 'registryPortalUsername') {
                result = validateRegistryPortalUsername(field.value);
            }
		}
	}
	return result;
}

function validateSelectOne(field) {
	var result = new Array(METHOD_RESULT_PASS, null);
	var selectValue = getSelectOneValue(field);
	var emptyValue = isEmptySelectValue(field.value);
	var classes = field.className.split(' ');
	for (var i = 0; (i < classes.length && (result[0] == METHOD_RESULT_PASS)); i++) {
		if (classes[i] == 'required') {
			result = validateRequiredSelectOneValue(selectValue);
		}
		if (!emptyValue) {
			// add other validation methods here
		}
	}
	return result;
}

function validateCheckbox(field) {
	var result = new Array(METHOD_RESULT_PASS, null);
	return result;
}

function validateTextArea(field) {
	var result = new Array(METHOD_RESULT_PASS, null);
	if (field.value != null) {
		field.value = trim(field.value);
	}
	var emptyValue = isEmpty(field.value);
	var classes = field.className.split(' ');
	for (var i = 0; (i < classes.length && (result[0] == METHOD_RESULT_PASS)); i++) {
		if (classes[i] == 'required') {
			result = validateRequiredTextFieldValue(field.value);
		} else if (/^range-text_[\d]+_[\d]+$/.test(classes[i])) {
			result = validateTextRange(field.value,
				parseInt(classes[i].substring(11), 10),
				parseInt(classes[i].substring(classes[i].lastIndexOf('_') + 1)), 10);
		}
		if (!emptyValue) {
			// add other validation methods here
		}
	}
	return result;
}
function validateRadio () {
	var result = new Array(METHOD_RESULT_PASS, null);
	return result;
}
function validateHidden () {
	var result = new Array(METHOD_RESULT_PASS, null);
	return result;
}
function validateFile(field) {
	var result = new Array(METHOD_RESULT_PASS, null);
	var value = ""; // seperate var as security violation to set value attribute
	if (field.value != null) {
		value = trim(field.value);
	}
	var classes = field.className.split(' ');
	for (var i = 0; (i < classes.length && (result[0] == METHOD_RESULT_PASS)); i++) {
		if (classes[i] == 'required') {
			result = validateRequiredTextFieldValue(value);
		}
	}
	return result;
}



function setFieldError(field, msg) {
	setFieldMessageByFieldName(field.name, msg);
}
function resetFieldError(field) {
	resetFieldMessageByFieldName(field.name);
}
function setFieldMessageByFieldName(fieldName, msg) {
	var fieldMessageSpan = document.getElementById(fieldName + '_m');
	var fieldLabel = document.getElementById(fieldName + '_l');
	if (fieldMessageSpan != null) {
        fieldMessageSpan.innerHTML = '<br />' + msg;
    }
	if (fieldLabel != null) {
        fieldLabel.className = 'vffl';
    }
}
function appendFieldMessageByFieldName(fieldName, msg) {
	var fieldMessageSpan = document.getElementById(fieldName + '_m');
	var fieldLabel = document.getElementById(fieldName + '_l');
	if (fieldMessageSpan != null) {
		if (fieldMessageSpan.innerHTML == null) {
			fieldMessageSpan.innerHTML = '';
		}
        fieldMessageSpan.innerHTML += '<br />' + msg;
    }
	if (fieldLabel != null) {
        fieldLabel.className = 'vffl';
    }
}
function resetFieldMessageByFieldName(fieldName) {
	var fieldMessageSpan = document.getElementById(fieldName + '_m');
	var fieldLabel = document.getElementById(fieldName + '_l');
	if (fieldMessageSpan != null) {
        fieldMessageSpan.innerHTML = '';
    }
	if (fieldLabel != null) {
        fieldLabel.className = 'fl';
    }
}

function validateTextRange(value, min, max) {
	var result = new Array(METHOD_RESULT_PASS, null);
	if (value.length < min) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "field length must be longer than " + min + ", current length " + value.length;
	} else if (value.length > max) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "field length must be shorter than " + max + ", current length " + value.length;
	}
	return result;
}

function validateDate (value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	var resultCode = isDate(value);
	if (resultCode > 0) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = IS_DATE_RESPONSE_CODES[resultCode];
	}
	return result;
}
function validateUSASCII(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	if (!value.match(/^[\x00-\x7F]*$/)) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "7-bit US-ASCII only";
	}
	return result;
}
function validateNormalised(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	// see XML Schema Part 2: Datatypes Second Edition, Section 3.3.1 normalizedString
	// cannot contain the carriage return (#xD), line feed (#xA) nor tab (#x9) characters
	if (value != null && !value.match(/^[^\x0D\x0A\x09]*$/)) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "Cannot contain carriage return, line feed nor tab characters";
	}
	return result;
}
function validateTelephone(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	// validate phone number is E164
	if (!value.match(/^\+[0-9]{1,3}\.[0-9]{1,14}$/)) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "Invalid Number";
	}
	return result;
}

function validateAuEligibilityId(field) {
	var result = new Array(METHOD_RESULT_PASS, null);
	var value = field.value; // trimmed already
	var typeField = document.getElementById(field.name + "Type");
	var typeValue = getSelectOneValue(typeField);
	// error if only one of Registrant ID and Registrant ID Type is defined
	if ((value != null && value != "") && (typeValue == null || typeValue == "")) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "Eligibility ID Type must be defined if you enter a Eligibility ID";
	} else if ((value == null || value == "") && (typeValue != null && typeValue != "")) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "Eligibility ID must be defined if you select a type";
	}
	return result;
}
function validateAuRegistrantId(field) {
	var result = new Array(METHOD_RESULT_PASS, null);
	var value = field.value; // trimmed already
	var typeField = document.getElementById(field.name + "Type");
	var typeValue = getSelectOneValue(typeField);
	// error if only one of Registrant ID and Registrant ID Type is defined
	if ((value != null && value != "") && (typeValue == null || typeValue == "")) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "Registrant ID Type must be defined if you enter a Registrant ID";
	} else if ((value == null || value == "") && (typeValue != null && typeValue != "")) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "Registrant ID must be defined if you select a type";
	}
	return result;
}
function validateIpv4Address(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	// <ipv4> ::= <decimal> ( "." <decimal> ){3}
	// <decimal> is an integer in the set {0,1,2,...,255}
	if (!value.match(/^(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\x2E(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$/)) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "Invalid IPv4 Address";
	}
	return result;
}
function validateIpv6Address(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	// <ipv6> = <hex>{1,4} ( ":" <hex>{1,4} ){7}
	if (!value.match(/^(?:[0-9a-fA-F]{1,4})(?::[0-9a-fA-F]{1,4}){7}$/)) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "Invalid IPv6 Address";
	}
	return result;
}
function validateHostName (value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	// <hostname> ::= <label> ( "." <label> )*
	// <label> ::= <letter-digit> ( ( <letter-digit-hyphen> )* <letter-digit> )? // <label> is 63 characters maximum length 
	//if (!value.match(/^[a-zA-Z\d](?:[a-zA-Z\d\-]{0,61}[a-zA-Z\d])?(?:\x2E[a-zA-Z\d](?:[a-zA-Z\d\-]{0,61}[a-zA-Z\d])?)+$/)) {
	//	result[0] = METHOD_RESULT_FAIL;
	//	result[1] = "Invalid Host Name";
	//}
	return result;
}
function validateDomainName (value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	// <hostname> ::= <label> ( "." <label> )*
	// <label> ::= <letter-digit> ( ( <letter-digit-hyphen> )* <letter-digit> )? // <label> is 63 characters maximum length 
	if (!value.match(/^[a-zA-Z\d](?:[a-zA-Z\d\-]{0,61}[a-zA-Z\d])?(?:\x2E[a-zA-Z\d](?:[a-zA-Z\d\-]{0,61}[a-zA-Z\d])?)+$/)) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = "Invalid Domain Name";
	}
	return result;
}

function validateDomainLabel(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	// <label> ::= <letter-digit> ( ( <letter-digit-hyphen> )* <letter-digit> )? // <label> is 63 characters maximum length 
	//if (!value.match(/^[a-zA-Z\d](?:[a-zA-Z\d\-]{0,61}[a-zA-Z\d])?$/)) {
	//	result[0] = METHOD_RESULT_FAIL;
	//	result[1] = "Invalid Domain Label";
	//}
	return result;
}

function validateReservedName(value) {
    var result = new Array(METHOD_RESULT_PASS, null);
    //if (!value.match(/^[a-zA-Z\d\-\*]{1,63}$/)) {
    //    result[0] = METHOD_RESULT_FAIL;
    //    result[1] = "Invalid Reserved Name";
    //}
    return result;
}

function validateAmount(value) {
    var result = validateAmountNoLimit(value);
    if (result[0] != METHOD_RESULT_FAIL) {
        var asFloat = parseFloat(value);
        if (asFloat >= 1000000) {
            result[0] = METHOD_RESULT_FAIL;
            result[1] = "Amount too large";
        }
    }
    return result;
}
function validateAmountNoLimit(value) {
    var result = new Array(METHOD_RESULT_PASS, null);
    if (/[^\d.]/.test(value)) {
        result[0] = METHOD_RESULT_FAIL;
        result[1] = "Invalid Amount";
        if (value.indexOf(',') != -1) {
            result[1] = result[1] + ". Do not include comma [ , ]"
        }
    }
    return result;
}

function validateNegativeAmountNoLimit(value) {
    var result = new Array(METHOD_RESULT_PASS, null);
    if (/^-?\d+(\.\d+)?$/.test(value) != true) {
        result[0] = METHOD_RESULT_FAIL;
        result[1] = "Invalid Amount";
        if (value.indexOf(',') != -1) {
            result[1] = result[1] + ". Do not include comma [ , ]"
        }
    }
    return result;
}

function validateInteger(value) {
    var result = new Array(METHOD_RESULT_PASS, null);
    if (!isInteger(value)) {
        result[0] = METHOD_RESULT_FAIL;
        result[1] = "Must be a whole number (integer)";
    }
    return result;
}

function validateRegistryPortalUsername(value) {
    var result = validateUSASCII(value);
    if (result[0] == METHOD_RESULT_PASS) {
    	if (value.indexOf("'") != -1) {
        	result[0] = METHOD_RESULT_FAIL;
        	result[1] = "Username can't have a single quote character";
    	}
    }
    return result;
}

function validateContactId(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	if (value.length < 3 || value.length > 16) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = 'Invalid Contact Identifier';
	}
	return result;
}
function validateRequiredSelectOneValue(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	if (isEmptySelectValue(value)) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = REQUIRED_MSG;
	}
	return result;
}
function validateRequiredTextFieldValue(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	if (isEmpty(value)) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = REQUIRED_MSG;
	}
	return result;
}
function isEmptySelectValue(value) {
	if (value == null || value == '' || value == SELECT_EMPTY_VALUE) {
		return true;
	} else {
		return false;
	}
}
function isEmpty(value) {
	if (value == null || value == '') {
		return true;
	} else {
		return false;
	}
}



// ***************** POSTAL INFORMATION FUNCTIONS START ***********************
function isPostalInformationEmpty(pi) {
	return isEmpty(pi.name)
		&& isEmpty(pi.organisation)
		&& isEmpty(pi.street1)
		&& isEmpty(pi.street2)
		&& isEmpty(pi.street3)
		&& isEmpty(pi.city)
		&& isEmpty(pi.state)
		&& isEmpty(pi.postcode)
		&& isEmpty(pi.country);
}
function resetPostalInformationFieldErrors(fieldPrefix) {
	document.getElementById('postalInformation_m').innerHTML = '';
	resetFieldError(document.getElementById(fieldPrefix + 'Name'));
	resetFieldError(document.getElementById(fieldPrefix + 'City'));
	resetFieldError(document.getElementById(fieldPrefix + 'Country'));
}
function validatePostalInformation(pi) {
	var result = true;
	resetPostalInformationFieldErrors(pi.fieldPrefix);
	if (isEmpty(pi.name)) {
		setFieldError(document.getElementById(pi.fieldPrefix + 'Name'), 'required');
		result = false;
	}
	if (isEmpty(pi.city)) {
		setFieldError(document.getElementById(pi.fieldPrefix + 'City'), 'required');
		result = false;
	}
	if (isEmpty(pi.country)) {
		setFieldError(document.getElementById(pi.fieldPrefix + 'Country'), 'required');
		result = false;
	}
	return result;
}
function setPostalInformationFieldError(msg) {
	document.getElementById('postalInformation_m').innerHTML = '<br/>' + msg;
}
function makePostalInformationObject(fieldPrefix) {
	return {
		'name' : trim(document.getElementById(fieldPrefix + 'Name').value),
		'organisation' : trim(document.getElementById(fieldPrefix + 'Organisation').value),
		'street1' : trim(document.getElementById(fieldPrefix + 'Street1').value),
		'street2' : trim(document.getElementById(fieldPrefix + 'Street2').value),
		'street3' : trim(document.getElementById(fieldPrefix + 'Street3').value),
		'city' : trim(document.getElementById(fieldPrefix + 'City').value),
		'state' : trim(document.getElementById(fieldPrefix + 'State').value),
		'postcode' : trim(document.getElementById(fieldPrefix + 'Postcode').value),
		'country' : trim(getSelectOneValue(document.getElementById(fieldPrefix + 'Country'))),
		'fieldPrefix' : fieldPrefix
	};
}
function isContactPostalInformationValid(intlPIPrefix, loclPIPrefix) {
	var result = true;
	var intlPI = makePostalInformationObject(intlPIPrefix);
	var loclPI = makePostalInformationObject(loclPIPrefix);
	var intlPIEmpty = isPostalInformationEmpty(intlPI);
	var loclPIEmpty = isPostalInformationEmpty(loclPI);
	if (intlPIEmpty && loclPIEmpty) {
		result = false;
		setPostalInformationFieldError('require one of internationalised or localised');
	}
	if (!intlPIEmpty) {
		result = validatePostalInformation(intlPI) && result;
	}
	if (!loclPIEmpty) {
		result = validatePostalInformation(loclPI) && result;
	}
	return result;
}
// ***************** POSTAL INFORMATION FUNCTIONS END *************************

// ***************** SET UPDATED FIELD FUNCTIONS START ************************

// susf = set updated select one field
function susf(field, originalValue, ignoreIfLabelClassVFFL) {
	if (field != null) {
		setUpdatedField(field.name, (!ufEqualsCheck(getSelectOneValue(field), originalValue)), ignoreIfLabelClassVFFL);
	}
}
// sutf = set updated text field
function sutf(field, originalValue, ignoreIfLabelClassVFFL) {
	if (field != null) {
		setUpdatedField(field.name, (!ufEqualsCheck(field.value, originalValue)), ignoreIfLabelClassVFFL);
	}
}
function suTelField(numberFieldId, extFieldId,
		originalNumber, originalExt, ignoreIfLabelClassVFFL) {
	if (ufEqualsCheck(document.getElementById(numberFieldId).value, originalNumber)
			&& 	ufEqualsCheck(document.getElementById(extFieldId).value, originalExt)) {
		setUpdatedField(numberFieldId, false, ignoreIfLabelClassVFFL);
	} else {
		setUpdatedField(numberFieldId, true, ignoreIfLabelClassVFFL);
	}
}
function suStreetField(fieldPrefix, originalPostalInfo, ignoreIfLabelClassVFFL) {
	if (originalPostalInfo != null) {
		if (ufEqualsCheck(originalPostalInfo.street1, document.getElementById(fieldPrefix + 'Street1').value)
				&& ufEqualsCheck(originalPostalInfo.street2, document.getElementById(fieldPrefix + 'Street2').value)
				&& ufEqualsCheck(originalPostalInfo.street3, document.getElementById(fieldPrefix + 'Street3').value)) {
			setUpdatedField(fieldPrefix + 'Street1', false, ignoreIfLabelClassVFFL);
		} else {
			setUpdatedField(fieldPrefix + 'Street1', true, ignoreIfLabelClassVFFL);
		}
	} else {
		setUpdatedField(fieldPrefix + 'Street1', true, ignoreIfLabelClassVFFL);
	}
}
function setUpdatedField(fieldName, fieldValueUpdated, ignoreIfLabelClassVFFL) {
	var fieldLabel = document.getElementById(fieldName + '_l');
	var fieldMessageSpan = document.getElementById(fieldName + '_m');
	if (fieldLabel != null) {
		if (fieldValueUpdated) {
			if (ignoreIfLabelClassVFFL) {
				if (fieldLabel.className != 'vffl') {
					fieldLabel.className = 'ufl';
					fieldMessageSpan.innerHTML = '';
				}
			} else {
				fieldLabel.className = 'ufl';
				fieldMessageSpan.innerHTML = '';
			}
		} else {
			if (!ignoreIfLabelClassVFFL) {
				fieldLabel.className = 'fl';
				fieldMessageSpan.innerHTML = '';
			}
		}
	}
}
function suEligibilityIdField(eligibilityIdTypeSelectId, eligibilityIdFieldId, originalDomain, ignoreIfLabelClassVFFL) {
	if (ufEqualsCheck(getSelectOneValue(document.getElementById(eligibilityIdTypeSelectId)), originalDomain.eligibilityIdType)
			&& 	ufEqualsCheck(document.getElementById(eligibilityIdFieldId).value, originalDomain.eligibilityId)) {
		setUpdatedField(eligibilityIdFieldId, false, ignoreIfLabelClassVFFL);
	} else {
		setUpdatedField(eligibilityIdFieldId, true, ignoreIfLabelClassVFFL);
	}
}
function suRegistrantIdField(registrantIdTypeSelectId, registrantIdFieldId, originalDomain, ignoreIfLabelClassVFFL) {
	if (ufEqualsCheck(getSelectOneValue(document.getElementById(registrantIdTypeSelectId)), originalDomain.registrantIdType)
			&& 	ufEqualsCheck(document.getElementById(registrantIdFieldId).value, originalDomain.registrantId)) {
		setUpdatedField(registrantIdFieldId, false, ignoreIfLabelClassVFFL);
	} else {
		setUpdatedField(registrantIdFieldId, true, ignoreIfLabelClassVFFL);
	}
}
//ufEqualsCheck = Updated Field Equals Check
function ufEqualsCheck(arg1, arg2) {
	if (arg1 == null) {
		arg1 = '';
	}
	if (arg2 == null) {
		arg2 = '';
	}
	arg1 = trim(arg1);
	arg2 = trim(arg2);
	return arg1 == arg2;
}
// ***************** SET UPDATED FIELD FUNCTIONS END **************************



function getSelectOneValue(theSelect) {
	if (theSelect.selectedIndex == null || theSelect.selectedIndex == -1) {
		return '';
	} else {
		return theSelect[theSelect.selectedIndex].value;
	}
}
function getSelectOneLabel(theSelect) {
	if (theSelect.selectedIndex == null || theSelect.selectedIndex == -1) {
		return '';
	} else {
		return theSelect[theSelect.selectedIndex].text;
	}
}

function validatePassword(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	var digit = /[0-9]/;		// contains digit
	var alpha = /[a-z]/i;		// contains alpha
	var length = /^[^\s]{6,32}$/;	// 6-32 non-blank characters
	if (!digit.test(value) || !alpha.test(value) || !length.test(value)) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = 'Invalid password';
	}
  	return result;
}

function validateUserPassword(value) {
	var result = new Array(METHOD_RESULT_PASS, null);
	var digit = /[0-9].*[0-9]/; // digit constraint
	var lower = /[a-z].*[a-z]/; // lower case constraint
	var upper = /[A-Z].*[A-Z]/; // upper case constraint
	var other = /[^0-9a-z].*[^0-9a-z]/i; // non-digit, non-alpha constraint
	if (!digit.test(value) || !lower.test(value) || !upper.test(value) || !other.test(value)) {
		result[0] = METHOD_RESULT_FAIL;
		result[1] = 'Invalid password';
	}
  	return result;
}

function validateEmail(emailStr) {
	if (emailStr.length < 3) {
		return false;
	}
	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];
	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 domainArray=domain.match(domainPat);
	if (domainArray == null) {
		return false;
	}
	var atomPat=new RegExp(atom,"g");
	var domArr=domain.match(atomPat);
	var len=domArr.length;
	if ((domArr[domArr.length-1].length < 2) || (domArr[domArr.length-1].length > 63)) {
		return false;
	}
	if (len < 2) {
		return false;
	}
	return true;
}
function validateDomainAuExtension() {
	var result = true;
	var theFieldValue = null;
	var theField = document.getElementById('registrantName');
	if (!processValidationResult(validateRequiredTextFieldValue(theField.value), theField)) {
		result = false;
	}
	theField = document.getElementById('eligibilityType');
	theFieldValue = getSelectOneValue(theField);
	if (!processValidationResult(validateRequiredSelectOneValue(theFieldValue), theField)) {
		result = false;
	}
	theField = document.getElementById('policyReason');
	theFieldValue = getSelectOneValue(theField);
	if (!processValidationResult(validateRequiredSelectOneValue(theFieldValue), theField)) {
		result = false;
	}
	theField = document.getElementById('registrantId');
	if (!processValidationResult(validateAuRegistrantId(theField), theField)) {
		result = false;
	}
	theField = document.getElementById('eligibilityId');
	if (!processValidationResult(validateAuEligibilityId(theField), theField)) {
		result = false;
	}
	return result;
}
function processValidationResult(validationResult, theField) {
	var result = true;
	if (validationResult[0] == METHOD_RESULT_PASS) {
		resetFieldError(theField);
	} else {
		result = false;
		setFieldError(theField, validationResult[1]);
	}
	return result;
}
function trim(value) {
	return value.replace(/^\s*|\s*$/g,"");
}
function normalise(field) {
	if (field.value) {
		field.value = field.value.replace(/\s+/g," ");
	}
}

// ***************** DATE VALIDATION FUNCTIONS START **************************
var dtCh = "/";
var minYear = 1900;
var maxYear = 2100;
var IS_DATE_RESPONSE_CODES = new Array(6);
IS_DATE_RESPONSE_CODES[0] = 'OK';
IS_DATE_RESPONSE_CODES[1] = 'The date format should be : dd/mm/yyyy';
IS_DATE_RESPONSE_CODES[2] = 'Please enter a valid month';
IS_DATE_RESPONSE_CODES[3] = 'Please enter a valid day';
IS_DATE_RESPONSE_CODES[4] = 'Please enter a valid 4 digit year between ' + minYear + ' and ' + maxYear;
IS_DATE_RESPONSE_CODES[5] = 'Please enter a valid date';
function isDate(dtStr){
	var daysInMonth = DaysArray(12);
	var pos1 = dtStr.indexOf(dtCh);
	var pos2 = dtStr.indexOf(dtCh, pos1+1);
	var strDay = dtStr.substring(0, pos1);
	var strMonth = dtStr.substring(pos1+1, pos2);
	var strYear = dtStr.substring(pos2+1);
	if (strDay.charAt(0) == "0" && strDay.length>1) {
		 strDay = strDay.substring(1);
	}
	if (strMonth.charAt(0) == "0" && strMonth.length>1) {
		strMonth = strMonth.substring(1);
	}
	for (var i = 1; i <= 3; i++) {
		if (strYear.charAt(0) == "0" && strYear.length>1){
			strYear = strYear.substring(1);
		}
	}
	month = parseInt(strMonth);
	day = parseInt(strDay);
	year = parseInt(strYear);
	if (pos1==-1 || pos2==-1){
		return 1
	}
	if (strMonth.length<1 || month<1 || month>12){
		return 2
	}
	if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
		return 3
	}
	if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
		return 4
	}
	if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
		return 5
	}
	return 0
}
// converts DD*MM*YYYY string to date, * can be any char
function stringToDateDDMMYYYY(theDate) {
	var pos1 = theDate.indexOf('/');
	var pos2 = theDate.indexOf(dtCh, pos1 + 1);
	var strDay = theDate.substring(0, pos1);
	var strMonth = theDate.substring(pos1 + 1, pos2);
	var strYear = theDate.substring(pos2 + 1);
	if (strDay.charAt(0) == "0" && strDay.length > 1) {
		 strDay = strDay.substring(1);
	}
	if (strMonth.charAt(0) == "0" && strMonth.length > 1) {
		strMonth = strMonth.substring(1);
	}
	for (var i = 1; i <= 3; i++) {
		if (strYear.charAt(0) == "0" && strYear.length>1){
			strYear = strYear.substring(1);
		}
	}
	month = parseInt(strMonth);
	day = parseInt(strDay);
	year = parseInt(strYear);

	return new Date(year, month - 1, day);
}
function isInteger(s){
	var i;
    for (i = 0; i < s.length; i++){   
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}
function stripCharsInBag(s, bag){
	var i;
    var returnString = "";
    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.
    for (i = 0; i < s.length; i++){   
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function daysInFebruary (year){
	// February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
	for (var i = 1; i <= n; i++) {
		this[i] = 31
		if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
		if (i==2) {this[i] = 29}
   } 
   return this
}

// Checks if time is in hh:mm:ss format. The seconds are optional.
function validateTimeString(fieldName, timeFieldId) {
	var result = new Array(METHOD_RESULT_PASS, null);
	var timeField = document.getElementById(timeFieldId);
	var hours = '';
	var minutes = '';
	var seconds = '';
	if (timeField != null) {
		var timeString = trim(timeField.value);
		var timeRegExp = /^(\d{1,2}):(\d{1,2})(:(\d{1,2}))?$/;
		if (timeRegExp.test(timeString)) {
			var timeArray = timeString.split(':');
			var hours = timeArray[0];
			var minutes = timeArray[1];
			if (timeArray.length > 2) {
				seconds = timeArray[2];
			} else {
				seconds = 0;
			}
			if (hours < 0  || hours > 23) {
				result[0] = METHOD_RESULT_FAIL;
				result[1] = 'Invalid time - Hour must be between 0 and 23.';
			} else if (minutes < 0 || minutes > 59) {
				result[0] = METHOD_RESULT_FAIL;
				result[1] = 'Invalid time - Minute must be between 0 and 59.';
			} else if (seconds < 0 || seconds > 59) {
				result[0] = METHOD_RESULT_FAIL;
				result[1] = 'Invalid time - Second must be between 0 and 59.';
			}
		} else {
			result[0] = METHOD_RESULT_FAIL;
			result[1] = 'Invalid time - Time must be in hh:mm:ss format.';
		}
		if (result[0] == METHOD_RESULT_FAIL) {
			appendFieldMessageByFieldName(fieldName, result[1]);
		} else {
			timeField.value = hours + ':' + minutes + ':' + seconds;
		}
	}
	return result[0] == METHOD_RESULT_PASS;
}
function validateDateRange(startDateFieldId, endDateFieldId, fieldName, startDateRequired, endDateRequired) {
	var result = new Array(METHOD_RESULT_PASS, null);
	var startDateField = document.getElementById(startDateFieldId);
	var endDateField = document.getElementById(endDateFieldId);
	var startDate = null;
	var endDate = null;
	var temp = 0;
	if (startDateField != null && endDateField != null) {
		startDateField.value = trim(startDateField.value);
		if (startDateField.value) {
			temp = isDate(startDateField.value);
			if (temp == 0) {
				startDate = stringToDateDDMMYYYY(startDateField.value);
			} else {
				result[0] = METHOD_RESULT_FAIL;
				result[1] = 'Invalid Start Date - ' + IS_DATE_RESPONSE_CODES[temp];
			}
		} else if (startDateRequired){
				result[0] = METHOD_RESULT_FAIL;
				result[1] = 'Start date is required';
		}
		endDateField.value = trim(endDateField.value);
		if (endDateField.value) {
			temp = isDate(endDateField.value);
			if (temp == 0) {
				endDate = stringToDateDDMMYYYY(endDateField.value);
			} else {
				if (result[0] == METHOD_RESULT_FAIL) {
					result[1] += '<br/>Invalid End Date - ' + IS_DATE_RESPONSE_CODES[temp];
				} else {
					result[0] = METHOD_RESULT_FAIL;
					result[1] = 'Invalid End Date - ' + IS_DATE_RESPONSE_CODES[temp];
				}
			}
		} else if (endDateRequired){
				if (result[0] == METHOD_RESULT_FAIL) {
					result[1] += '<br/>End date is required';
				} else {
					result[0] = METHOD_RESULT_FAIL;
					result[1] = 'End date is required';
				}
		}
	}

	if (startDate != null && endDate != null) {
		if (startDate.getTime() > endDate.getTime()) {
			result[0] = METHOD_RESULT_FAIL;
			result[1] = 'Invalid date range - start date cant be after end date.';
		}
	}
	if (result[0] == METHOD_RESULT_FAIL) {
		setFieldMessageByFieldName(fieldName, result[1]);
	} else {
		resetFieldMessageByFieldName(fieldName);
	}
	return result[0] == METHOD_RESULT_PASS;
}




// ***************** DATE VALIDATION FUNCTIONS END **************************

