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]$/;

$(document).ready(function() {
	//Based on our active state select the matching DOM container.
	var initialEntryContainer = $(document).find('div.initialEntryForm');
	var dvlaLookupContainer = $(document).find('div.dvlaLookup');
	var manualLookupContainer = $(document).find('div.manualVehicleLookup');
	var additionalDetailsContainer = $(document).find('div.additional-details');
	var selectServiceItemsContainer = $(document).find('div.select-service-items');
	var bookingDateContainer = $(document).find('div.bookingDate');
	var requestCallbackContainer = $(document).find('div.request-callback-container');
	
	//Check for the existence of a specific container and wire up our JS validation.
	if(initialEntryContainer.length > 0) setupInitialEntry(initialEntryContainer);
	if(dvlaLookupContainer.length > 0) setupDvlaLookup(dvlaLookupContainer);
	if(manualLookupContainer.length > 0) setupManualVehicleLookup(manualLookupContainer);
	if(additionalDetailsContainer.length > 0) setupAdditionalDetails(additionalDetailsContainer);
	if(selectServiceItemsContainer.length > 0) setupSelectServiceItems(selectServiceItemsContainer);
	if(bookingDateContainer.length > 0) setupBookingDate(bookingDateContainer);	
	if(requestCallbackContainer.length > 0) setupRequestCallback(requestCallbackContainer);	
	
	//Bind any callback elements to update the search and pull down new values.
	//bindFilterEvents($("form#searchCriteriaForm"));	
	
	//Hide the pre-loader.
	$("form.osbPanel div#osbLoadingContainer").hide();	
});

//When the user causes a postback or timeout then display a UI message explaining what is happening.
function displayLoadingMessage(type, message, yOffset, initiatingEvent)
{
	var popUpContainer = $("form.osbPanel div#osbLoadingContainer");
	var imageContainer = popUpContainer.find("#osbLoadingIcon");
	var messageContainer = popUpContainer.find("#osbLoadingMessage");
	var okButton = popUpContainer.find("#osbLoadingOk");
	var cancelButton = popUpContainer.find("#osbLoadingCancel");
	
	//yOffset = (($(window).height() - popUpContainer.height()) / 2) + $(document).scrollTop(); 
	if ($(document).scrollTop() > yOffset) yOffset = $(document).scrollTop() + 50;
	//alert($(window).height());
	//alert($(document).scrollTop());
	//alert(yOffset);
	
	if (yOffset) popUpContainer.css("top",yOffset);
	if (message) messageContainer.html(message);
	if (type) imageContainer.attr("class", type);
	
	switch(type)
	{
		case "waiting" :
			okButton.hide();
			cancelButton.hide();
			break;
			
		case "information" :
			okButton.show();
			cancelButton.hide();
			
			//Handle the ok action of this pop-up.
			okButton.click( function() {
				popUpContainer.hide();
				return false;
			});
	
			break;
			
		case "confirm" :
			//Prevent the default event from firing.
			initiatingEvent.preventDefault();
			var targetItem = $(initiatingEvent.target);
			var aItem;
			if (targetItem.is("a")) {
				aItem = targetItem;
			}
			else {
				aItem = targetItem.parents("a");
			}
			
			eventSignature = $(aItem).attr("href").replace("javascript:", "");
			okButton.show();
			cancelButton.show();
			
			//Handle the ok action of this pop-up.
			okButton.click( function() {
				popUpContainer.hide();
				eval(eventSignature);
				return true;
			});
			
			//Handle the cancel action of this pop-up.
			cancelButton.click( function() {
				popUpContainer.hide();
				return false;
			});
	
			break;
	}

	//Now our container is configured show it.
	popUpContainer.show();
}

//load the validation for the initial entry screen
function setupInitialEntry (container) {

	//wire up the validation to the button click
	container.find('input.formNext').click(function(event) {
		var valid = true;
		
		//hide any existing errors
		HideAllErrors(container);
		
		//run the various validation routines and see if they all pass
		if(!ValidateRequiredFields(container)) valid = false;
		if(!ValidatePostcodes(container)) valid = false;
		if(!ValidateEmailAddress(container)) valid = false;	
		if(!ValidateTelephone(container)) valid = false;
		if(!ValidateDropDownList(container)) valid = false;
		if(!ValidateLength(container)) valid = false;
		if(!ValidateNonNumeric(container)) valid = false;
		if(!ValidateJointRequiredFields(container)) valid = false;
		
		if(!valid) {
			event.preventDefault();
		}
	});	
	
	/*
	container.find('input.formNext').click(function(event) {
		var valid = true;
		
		//run the various validation routines and see if they all pass
		if(!ValidateRadioGroup(container)) valid = false;
		
		if(!valid) {
			event.preventDefault();
		}		
	});
	*/
	
	//Bind up the scripts to selectivly hide the required astrix from the telephone and email fields depending on what has been entererd
	container.find('div.item.telephone input, div.item.email input').change(function() {
		//get the two inputs		
		var telInput = container.find('div.item.telephone input');
		var emailInput = container.find('div.item.email input');
		var emailAstrix = container.find('div.item.email abbr.mandatory');
		var telAstrix = container.find('div.item.telephone abbr.mandatory');
		
		//if the user has entered an email address then the telephone number isn't required
		if(TrimText(emailInput.val()) != "") {
			telAstrix.hide();
		} 
		else {
			telAstrix.show();
		}	
		
		//if the user had entered a telephone number then the email address isn't required
		if(TrimText(telInput.val()) != "") {
			emailAstrix.hide();
		}
		else {
			emailAstrix.show();
		}
	});
}

//load the validation for the dvlaLookup screen
function setupDvlaLookup(container) {
	//on submit click run the various validation routines
	container.find('input.formNext').click(function(event) {
		var valid = true;
		
		if(!ValidateRadioGroup(container)) valid = false;
		
		if(!valid) {
			event.preventDefault();
		}
	});
}

//load the validation for the manualVehicleLookup screen
function setupManualVehicleLookup(container) {
	//on submit click run the various validation routines
	container.find('input.formNext').click(function(event) {
		var valid = true;
		
		if(!ValidateDropDownList(container)) valid = false;
		if(!ValidateRadioGroup(container)) valid = false;
		
		if(!valid) {
			event.preventDefault();
		}
	});
}

//bind up the validation for the additional info page
function setupAdditionalDetails(container) {
	var emailContainer = container.find('div#emailContainer');
	var smsContainer = container.find('div#smsContainer');
	var emailInput = emailContainer.find('div.emailYesNo div.confirmationYes input');
	var emailInputNo = emailContainer.find('div.emailYesNo div.confirmationNo input');
	var smsInput = smsContainer.find('div.smsYesNo div.confirmationYes input');
	var smsInputNo = smsContainer.find('div.smsYesNo div.confirmationNo input');
	
	container.find('input.formNext').click(function(event) {
		
		var valid = true;
		
		//If the user has entered a mileage check that it is valid.
		if(!ValidateIsNumeric(container)) valid = false;
		
		//if the user has selected to recieve email validation then validate the email address that has been entered
		if(emailInput[0].checked) {
			if(!ValidateRequiredFields(emailContainer)) valid = false;
			if(!ValidateEmailAddress(emailContainer)) valid = false;
		}
		else {
			if(!ValidateEmailAddress(emailContainer)) valid = false;
		}
					
		//if the user has selected to recieve an sms validation then validate the phone number that has been entered
		if(smsInput[0].checked) {
			if(!ValidateIsMobileNumber(smsContainer)) valid = false;
		}
		else {
			if(!ValidateTelephone(smsContainer)) valid = false;
			if(!ValidateLength(smsContainer)) valid = false;
		}
		
		//If the user has select not to recieve any confirmation then they must enter a number to call them on
		if(smsInputNo[0].checked && emailInputNo[0].checked) {
			if(!ValidateRequiredFields(smsContainer,'manualConfirmation')) valid = false;
		}		
		
		if(!valid) {
			event.preventDefault();
		}
	});
}


//bind up the functions used within the select service items state
function setupSelectServiceItems(container) {
	var showChk = container.find('input.show-comments');
	var content = container.find('textarea.comments');
	var label = container.find('div.comments-label');
	var advice = container.find('span.advice');
	
	//Hide our checkbox if we have no additional text specified.
	if (!showChk[0].checked)
	{
		content.hide();
		label.hide();
		advice.hide();
	}
	
	showChk.click(function() {
		if(showChk[0].checked) {
			label.show();
			content.show();
			advice.show();
		}
		else {
			content.hide();
			label.hide();
			advice.hide();
		}
	});
}



//load the validation for the bookingDate screen
function setupBookingDate(container) {

	//Wire up our change dealership js confirmation pop-up.
	container.find('a.altDealership, td.calendarDateAltAvailable > a').click(function(event) {
		displayLoadingMessage('confirm', 'If you switch preferred dealership then you will need to re-select your required service items. Not all service options are available at all dealerships. Are you happy to continue?', 600, event);
	});

	//on submit we need to make sure that the user has selected a valid date and time and collection address if required.
	container.find("input.formNext").click(function(event) {
		var valid = true;
		
		//Check that the user selected a date
		if(container.find("select.ddlTime").length == 0) {
			valid = false;
			var error = container.find('span.validateCalendar');
			error.css('display','block');
		}
		
		//Validate address details complete.
		if(!ValidateRequiredFields(container)) valid = false;
		
		//Validate time drop down list.
		if(!ValidateDropDownList(container)) valid = false;
		
		if(!valid) {
			event.preventDefault();
		}
	});
}

//load the validation functions for the callback request state
function setupRequestCallback(container) {
	var input = container.find("input.formNext");
	
	input.click(function(event) {
		var valid = true;
				
		//hide any previous errors
		HideAllErrors(container);
		
		//now evaluate the user inputs to assess if they are valid
		if(!ValidateDropDownList(container)) valid = false;
		if(!ValidateRequiredFields(container)) valid = false;
		if(valid) {if(!ValidateTelephone(container)) valid = false; }
		if(valid) {if(!ValidateLength(container)) valid = false; }

		if(!valid) {
			event.preventDefault();
		}	
	});	
}

//function used to hide all of the error message being displayed
function HideAllErrors(container) {
	container.find('span.jointRequiredField').hide();
	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.validateLength').hide();
	container.find('span.requiredField').hide();
	container.find('span.validateIsMobileNumber').hide();
	container.find('span.validateRadioGroup').hide();
}

//function used to validate any joint required fields
function ValidateJointRequiredFields(container) {
	var valid = false
	container.find('div.jointRequiredField').each(function() {
		var input = $(this).find('input');
		if(TrimText(input.val()) != '') {
			valid = true;
		}
	});
	if(!valid) {
		container.find('div.jointRequiredField span.jointRequiredField').css('display','block');
	}	
	else {
		container.find('div.jointRequiredField span.jointRequiredField').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 phone numbers, in the uk or international form
function ValidateTelephone(container) {
	var valid = true;
	var validChars = '+0123456789';
	container.find('div.validateTelephone').each(function() {
		var input = $(this).find('input');
		var error = $(this).find('span.validateTelephone');	
		var textValue = TrimText(input.val(),true);
		
		if(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) {
					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 validate any of the postcodes on the page
function ValidatePostcodes(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);
		var textValue = TrimText(input.val(), true);
		
		if(textValue != '') {
			//the postcode needs a space, so if one isn't there then insert it
			if(textValue.indexOf(' ') == -1 && textValue.length > 4) {
				var part1 = textValue.substring(0, textValue.length-3);
				var part2 = textValue.substring(textValue.length-3,textValue.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 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);
		var textValue = TrimText(input.val(), true);
		
		if(textValue != '') {
			//now check the postcode matches the regex
			if (textValue.match(regex)) {
				error.css('display','none');
			}
			else {
				error.css('display','block');
				valid = false;
			}
		}
		input.val(textValue);
	});
	return valid;
}

//function used to validate whether a field contains only numeric characters
function ValidateIsNumeric(container) {
	var validChars = '0123456789.';
	var valid = true;
	container.find('div.validateNumeric').each(function() {
		var input = $(this).find('input');
		var error = $(this).find('span.validateNumeric');
		var textValue = TrimText(input.val().replace(',',''), true);
		
		if(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;
			}
		}
		input.val(textValue);
	});
	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() {
		var input = $(this).find('input.validateIsMobileNumber');
		var error = $(this).find('span.validateIsMobileNumber');
		var inputText = TrimText(input.val());
		
		if(	(	(inputText.substring(0,2) == '07') ||
				(inputText.substring(0,4) == '+447')
			) &&
			(ValidateLength(container)) &&
			(ValidateTelephone(container))
			) {
			error.css('display','none');
		}
		else {
			error.css('display','block');
			valid = false;
		}
		input.val(inputText);
	});
	return valid;
}

//function used to ensure that no numeric chars have been entered into a field
function ValidateNonNumeric(container) {
	var inValidChars = '0123456789';
	var valid = true;
	container.find('div.validateNonNumeric').each(function() {
		var input = $(this).find('input');
		var error = $(this).find('span.validateNonNumeric');
		var textValue = TrimText(input.val());
		
		if(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(inValidChars.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 validate the length of a telephone number
function ValidateLength(container) {
	var validLength;
	var valid = true;
	container.find('div.validateLength').each(function() {
		var input = $(this).find('input');
		var error = $(this).find('span.validateLength');
		var textValue = TrimText(input.val(), true);
		
		//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');
			}
			else {
				error.css('display','none');
			}
		}	
	});
	return valid;
}

//function used to validate radio group selection
function ValidateRadioGroup(container) {
	var valid = true;
	container.find('div.validateRadioGroup').each(function(){
		var input = $(this).find('input:checked').val();		
		var error = $(this).find('span.validateRadioGroup');
		
		if(!input) {
			error.css('display','block');
			valid = false;
		}
		else {
			error.css('display','none');
		}
	});
	return valid;
}

//function used to setup the required field validators
function ValidateRequiredFields(container, cssClass) {
	var valid = true;
	if(!cssClass) cssClass = 'requiredField'
	container.find('div.' + cssClass).each(function(){
		var input = $(this).find('input:text, textarea');
		var error = $(this).find('span.' + cssClass);
		var textValue = TrimText(input.val());
		
		if(TrimText(input.val()) == '') {
			error.css('display','block');
			valid = false;
		}
		else {
			error.css('display','none');
		}
		
		input.val(textValue);
	});
	return valid;
}

//function used to return a string with all whitespace removed
function TrimText(text, includeInnerSpaces) {
	if(includeInnerSpaces)
	{
		return GlobalTrim(text);
	}
	else
	{
		return OuterTrim(text);
	}
}

// Removes leading whitespaces
function LTrim(value) {
	
	var re = /\s*((\S+\s*)*)/;
	return value.replace(re, "$1");
	
}

// Removes ending whitespaces
function RTrim(value) {
	
	var re = /((\s*\S+)*)\s*/;
	return value.replace(re, "$1");
	
}

// Removes leading and ending whitespaces
function OuterTrim(value) {
	
	return LTrim(RTrim(value));
	
}

// Removes leading and ending whitespaces
function GlobalTrim(value) {

	OuterTrim(value);
	
	while(value.indexOf(' ') > -1)
	{
		value = value.replace(' ','');
	}
	return value;	
}

