var POSTCODE_REGEX = /^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$/;
var EMAIL_REGEX = /^[a-zA-Z][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$/;

//function used to hide all of the error message being displayed
function HideAllErrors(container) {
	container.find('span.validateDropDownList').hide();
	container.find('span.validatePostcode').hide();
	container.find('span.validateEmail').hide();
	container.find('span.validateNumeric').hide();
	container.find('span.validateNonNumeric').hide();
	container.find('span.validatePhoneNumberLength').hide();
	container.find('span.requiredField').hide();
	container.find('span.validateIsMobileNumber').hide();
	container.find('span.validateMatchingPasswords').hide();
	container.find('span.validatePasswordComplexity').hide();
}

//function used to setup the required field validators
function ValidateRequiredFields(container) {
	var valid = true;
	container.find('div.requiredField').each(function(){
		var input = $(this).find('input:text, input:password');
		var error = $(this).find('span.requiredField');
		
		if(TrimText(input.val()) == '') {
			error.css('display','block');
			valid = false;
		}
		else {
			error.css('display','none');
		}
	});
	return valid;
}

//function used to validate that a dropdownlist has been selected
function ValidateDropDownList(container) {
	var valid = true;
	container.find('div.validateDropDownList').each(function() {
		var select = $(this).find('select');
		var error = $(this).find('span.validateDropDownList');
		if(select.val() == '-1') {
			error.css('display','block');
			valid = false;
		}
		else {
			error.css('display','none');
		}
	});
	return valid;
}

//function used to validate any of the postcodes on the page
function ValidatePostcode(container) {
	var valid = true;
	container.find('div.validatePostcode').each(function() {
		var input = $(this).find('input');
		var error = $(this).find('span.validatePostcode');
		var regex = new RegExp(POSTCODE_REGEX);
		if(TrimText(input.val()) != '') {
			//the postcode needs a space, so if one isn't there then insert it
			if(input.val().indexOf(' ') == -1 && input.val().length > 4) {
				var part1 = input.val().substring(0,input.val().length-3);
				var part2 = input.val().substring(input.val().length-3,input.val().length);
				input.val(part1 + ' ' + part2);
			}
			
			//now check the postcode matches the regex
			if (input.val().match(regex)) {
				error.css('display','none');
			}
			else {
				error.css('display','block');
				valid = false;
			}
		}
	});
	return valid;
}

//function used to ensure that a user enters a valid mobile phone number
function ValidateIsMobileNumber(container) {
	var valid = true;
	container.find('div.validateIsMobileNumber').each(function() {
		if($(this).find('span.requiredField').css('display')!='block'){
			var input = $(this).find('input:text');
			var error = $(this).find('span.validateIsMobileNumber');
			var inputText = TrimText(input.val());
			if((inputText.substring(0,2) == '07') || (inputText.substring(0,4) == '+447')) {
				error.css('display','none');
			}
			else {
				error.css('display','block');
				valid = false;
			}
		}
	});
	return valid;
}

//function used to validate that two passwords entered match
function ValidatePasswordsMatch(container) {
	var valid = true;
	
	//find the elements needed to perform the validation
	var password = container.find('input.password');
	var passwordConfirm = container.find('input.confirm-password');
	var passwordErrors = container.find('span.validateMatchingPasswords');
	
	//check if the password match
	if(password.val() != passwordConfirm.val()) {
		passwordErrors.css('display','block');
		valid = false;
	}
	else {
		passwordErrors.css('display','none');
	}
			
	return valid;
}

//function used to validate that the passwords entered are complex enough
function ValidatePasswordComplexity(container) {
	var valid = true;
	
	//only validate this is the passwords are present and match
	if((container.find('div.validatePasswordComplexity span.requiredField').css('display') == 'none') && (container.find('div.validatePasswordComplexity span.validateMatchingPasswords').css('display') == 'none')) {
		//find the elements needed to perform the validation	
		var password = container.find('input.password');
		var passwordErrors = container.find('span.validatePasswordComplexity');

		//check the complexity of the password
		var validNumeric = '0123456789';
		var validAlpha = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
		var validNonAlphaNumeric = ' ,./;\'#[]-=<>?:@~{}_+!"£$%^&*()';
		var textValue = TrimText(password.val());
		
		var internalNumericValid = false;
		var internalAlphaValid = false;
		var internalNonAlphaNumericValid = false;
		if(password.val().length >= 8) {
			for(var i=0;i<=textValue.length-1;i++) {
				if(validNumeric.indexOf(textValue.charAt(i)) > -1) {
					internalNumericValid = true;
				}
				if(validAlpha.indexOf(textValue.charAt(i)) > -1) {
					internalAlphaValid = true;
				}
				if(validNonAlphaNumeric.indexOf(textValue.charAt(i)) > -1) {
					internalNonAlphaNumericValid = true;
				}
			}
		}
		
		//check to ensure that all parts are present
		if(internalNumericValid && internalAlphaValid && internalNonAlphaNumericValid) {
			passwordErrors.css('display','none');
		}	
		else {
			passwordErrors.css('display','block');
			valid = false;
		}
	}
	
	return valid;
}

//function used to validate any email addresses on the page
function ValidateEmailAddress(container) {
	var valid = true;
	container.find('div.validateEmail').each(function() {
		var input = $(this).find('input:text');
		var error = $(this).find('span.validateEmail');
		var regex = new RegExp(EMAIL_REGEX);
		if(TrimText(input.val()) != '') {
			//now check the postcode matches the regex
			if (input.val().match(regex)) {
				error.css('display','none');
			}
			else {
				error.css('display','block');
				valid = false;
			}
		}
	});
	return valid;
}

//function used to validate the length of a telephone number
function ValidatePhoneNumberLength(container) {
	var validLength;
	var valid = true;
	container.find('div.validatePhoneNumberLength').each(function() {
		var input = $(this).find('input');
		var error = $(this).find('span.validatePhoneNumberLength');
		var textValue = TrimText(input.val());
		
		//set the length according to whether we're dealing with internation or uk telephone number
		 if (textValue.indexOf('+') > -1) {
			validLength = 13;
		 }
		 else {
			validLength = 11;
		 }
		
		if(textValue != '') {
			if(textValue.length != validLength) {
				valid = false;
				error.css('display','block');
			}
		}
	});
	return valid;
}


//function used to validate whether a field contains only numeric characters
function ValidateIsNumeric(container) {
	var validChars = '+0123456789';		// + needs to be included to catch international dialing codes
	var valid = true;
	container.find('div.validateNumeric').each(function() {
		var input = $(this).find('input:text');
		var error = $(this).find('span.validateNumeric');
		var textValue = TrimText(input.val());
		if(TrimText(textValue) != '') {
			//interval valid var used to check this instance of the numeric validator
			var internalValid = true;
			for(var i=0;i<=textValue.length-1;i++) {
				if(validChars.indexOf(textValue.charAt(i)) == -1) {
					//alert(textValue[i]);
					internalValid = false;
				}
			}
		
			//see if this instance of the validator has passed or not
			if(internalValid) {
				error.css('display','none');
			}
			else {
				error.css('display','block');
				valid = false;
			}
		}
	});
	return valid;
}

//function used to return a string with all whitespace removed
function TrimText(text) {
	var retval = text;
	while(retval.indexOf(' ') > -1) {
		retval = retval.replace(' ','');
	}
	return retval;
}