$(document).ready(function(){
	
	/* INPUT FOCUS */
	$('.site-form input,.site-form textarea,.site-form select').focus(function(){ $(this).addClass('focus'); });
	$('.site-form input,.site-form textarea,.site-form select').blur(function(){ $(this).removeClass('focus'); });
	
	/* FORM SUBMITTED TO SERVER */
	$('.site-form abbr.form-error').each(function(){
	
		label = $(this).parent(); //grab label object
		input = $('#'+label.attr('for')); //grab input object
		if($(input).val() ==''){
			$(input).bind("keydown",function(){
				errorItemRemove($(this));
			}); //remove error message while being corrected		
		}
		if($(this).hasClass('email')){
			var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);  

			$(input).bind("keydown",function(){
				//remove error message while being corrected
				if(pattern.test( $(this).val() )){
				errorItemRemove($(this));
				}
			});
		} //close if email
		
	}); //close each
	
});

/*VALIDATE FORM*/

function validateForm(form){
	resetFormErrors();
	var errors = false;
	var label = '';
	var input = '';
	
	//cycle required fields
	$('.site-form abbr.required').each(function(){
	
		label = $(this).parent(); //grab label object
		id = label.attr('for');
		input = $('#'+id); //grab input object
		input_match = $('[title='+input.attr('title')+']').not(input);
		
		errors = validateEmptyFields(errors,input);
		errors = validateMatchingFields(errors,input,input_match);
		errors = validateEmailAddress(errors,input);
	});
	if(form == 'shipping'){
		errors = validateFormShipping(errors);
	}
	if(form == 'billing'){
		//credit card is wanted && first char is not '*'
		if($('#CreditCardExpiryMonth').attr('disabled')==false && $('#CreditCardNumber').val().charCodeAt(0) !=42){
			errors = checkCreditCard(errors,$('#CreditCardNumber').val(),$('#PaymentTypeID').val());
		}
		//errors = validateFormBilling(errors); still writing this
	}
	if(errors){	return false; } 
	else {return true; }
}

function resetFormErrors(){
	$('abbr,label,.item').removeClass('form-error');
	$('span.form-error').remove();
	$('input,select,textarea').removeClass('error-display'); //prevent multiple error displays on same element
	window.focused = false; //remove true
}
function errorMessage(input,message){
	if(!input.hasClass('error-display')){ //prevent multiple error displays on same element
		input.addClass('error-display'); //prevent displaying error twice
		input.parent().addClass('form-error');
		input.parent().children('label').children('abbr').addClass('form-error');
		input.parent().children('label').append(' <span class="form-error"><span></span>'+ message +'</span>');
	}
	if(!window.focused){ input.focus(); window.focused = true; } //focused on first error
	return true;
}
function errorItemRemove(input){
		$(input).parent().removeClass('form-error');
		$(input).parent().children('label').children('abbr').removeClass('form-error');
		$(input).parent().children('label').children('span.form-error').remove();
}

function validateEmptyFields(errors,input){
	if(input.val() =='' && !$(this).hasClass('email')){
		errors = errorMessage($(input),'Please correct input'); //apply error message
		input.bind("keydown",function(){
			errorItemRemove($(this));
		}); //remove error message while being corrected
	}
	return errors;
}
function validateMatchingFields(errors,input,input_match){
	if((input.val() != input_match.val()) && $(this).hasClass('match')){
		errors = errorMessage($(input),'Inputs did not match'); //apply error message
		
		input.bind("keyup",function(){										  
			//remove error message while being corrected
			if($(this).val() == $('[title='+$(this).attr('title')+']').not($(this)).val()){
				errorItemRemove($(this));
				errorItemRemove($('[title='+$(this).attr('title')+']').not($(this)));
			}
		});
	}
	return errors;
}
function validateEmailAddress(errors,input,input_match){
	if($(this).hasClass('email')){
		var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);  
		if(!pattern.test( input.val() )){
			errors = errorMessage($(input),'Please correct address format'); //apply error message
			input.bind("keydown",function(){
				//remove error message while being corrected
				if(pattern.test( $(this).val() )){
					errorItemRemove($(this));
				}
			}); //remove error message while being corrected
		}  
	}
	return errors;
}
function validateFormShipping(errors) {
	var intlCountry = 0;		
	var countrySelected = $("#CountryID").val();
	
	//international country?
	if (countrySelected != 'US' && countrySelected != 'CA' && countrySelected != 'AU') {
		intlCountry = 1;
	}
	
	// check if state was selected
	if (($("#StatePU").val().length < 1) && ($("#StateTX").val().length < 1)) {
		
		//international state not selected
		if (intlCountry == 1) {
			errors = errorMessage($('#StateTX'),'Please enter your State'); //apply error message
		}
		//US state not selected
		else {
			errors = errorMessage($('#StatePU'),'Please select your State'); //apply error message
			if (countrySelected == 'US') {
				$("#stShipUS").attr('selected',true);
				$("#StateTX").val('');
			}
			else if (countrySelected == 'CA') {
				$("#stShipCA").attr('selected',true);
				$("#StateTX").val('');
			}
			else if (countrySelected == 'AU') {
				$("#stShipAU").attr('selected',true);
				$("#StateTX").val('');
			}
		}
	}
	
	//validate if US state selected, country is United States
	if ( ($("#StatePU").val().length == 2) && (countrySelected != 'US' && countrySelected != 'CA') ) {
		if ($("#StateTX").val().length < 1) {
			errors = errorMessage($('#StateTX'),'You have selected a North American State but an International Country'); //apply error message
			$("#stShipIntl").attr('selected',true);
		}
	}
	// validate 2 char state is selected from state select menu for Country US
	if (countrySelected == 'US' && $("#StatePU").val().length != 2) {
		errors = errorMessage($('#StatePU'),'Please select a valid US State'); //apply error message
		$("#stShipUS").attr('selected',true);
		$("#StateTX").val('');
	}
	else if (countrySelected == 'CA' && $("#StatePU").val().length != 2) {
		errors = errorMessage($('#StateTX'),'Please select a valid Canadian State'); //apply error message
		$("#stShipCA").attr('selected',true);
		$("#StateTX").val('');
	}
	return errors;
}
/*
function validateFormBilling(errors){
	switch($('#CreditCardExpiryMonth').val()){
		case'01': month = 0; break;
		case'02': month = 1; break;
		case'03': month = 2; break;
		case'04': month = 3; break;
		case'05': month = 4; break;
		case'06': month = 5; break;
		case'07': month = 6; break;
		case'08': month = 7; break;
		case'09': month = 8; break;
		case'10': month = 9; break;
		case'11': month = 10; break;
		case'12': month = 11; break;
	}
	var currentDate=new Date();
	if(currentDate.getFullYear() == $('#CreditCardExpiryYear').val() && currentDate.getMonth() > month){
		$('#card-expiration').addClass('form-error');
		$('#card-expiration').children('label').children('abbr').addClass('form-error');
		$('#card-expiration .title').append(' <span class="form-error"><span></span>Date entered is expired</span>');
		
		$('#CreditCardExpiryYear,#CreditCardExpiryMonth').change("keyup",function(){										  
			//remove error message while being corrected
			if(currentDate.getFullYear() == $('#CreditCardExpiryYear').val() && currentDate.getMonth() > month){
				errorItemRemove('#CreditCardExpiryYear');
				errorItemRemove('#CreditCardExpiryMonth');
				errorItemRemove('#card-expiration');
			}
		});
	}
	else if($('#CreditCardCode').val().length < 3){
		$('#card-expiration').addClass('form-error');
		$('#card-expiration').children('label').children('abbr').addClass('form-error');
		$('#card-expiration .title').append(' <span class="form-error"><span></span>Security Code is incorrect</span>');
	}
	return errors;
}
*/
/*============================================================================*/
	/*
	
	This routine checks the credit card number. The following checks are made:
	
	1. A number has been provided
	2. The number is a right length for the card
	3. The number has an appropriate prefix for the card
	4. The number has a valid modulus 10 number check digit if required
	
	If the validation fails an error is reported.
	
	The structure of credit card formats was gleaned from a variety of sources on 
	the web, although the best is probably on Wikepedia ("Credit card number"):
	
	  http://en.wikipedia.org/wiki/Credit_card_number
	
	Parameters:
				cardnumber           number on the card
				cardname             name of card as defined in the card list below
	
	Author:     John Gardner
	Date:       1st November 2003
	Updated:    26th Feb. 2005      Additional cards added by request
	Updated:    27th Nov. 2006      Additional cards added from Wikipedia
	Updated:    18th Jan. 2008      Additional cards added from Wikipedia
	Updated:    26th Nov. 2008      Maestro cards extended
	
	*/
	
	/*
	   If a credit card number is invalid, an error reason is loaded into the 
	   global ccErrorNo variable. This can be be used to index into the global error  
	   string array to report the reason to the user if required:
	   
	   e.g. if (!checkCreditCard (number, name) alert (ccErrors(ccErrorNo);
	*/
	
	function checkCreditCard (errors,cardnumber,cardname) {		 
	
		var ccErrorNo = 0;
		var ccErrors = new Array ()
		
		ccErrors [0] = "Unknown card type";
		ccErrors [1] = "No card number provided";
		ccErrors [2] = "Credit card number is in invalid format";
		ccErrors [3] = "Credit card number is invalid";
		ccErrors [4] = "Credit card number has an inappropriate number of digits";
		
		switch(cardname){
			case '1': cardname = 'DinersClub'; break;
			case '2': cardname = 'Discover'; break;
			case '3': cardname = 'AmEx'; break;
			case '4': cardname = 'MasterCard'; break;
			case '5': cardname = 'Visa'; break;
			//case '6': cardname = 'Pay Pal'; break;
			//case '7': cardname = 'COD'; break;
			//case '8': cardname = 'Purchase Order'; break;
			default: cardname = ''; break;
		}
		
	  // Array to hold the permitted card characteristics
	  var cards = new Array();
	
	  // Define the cards we support. You may add addtional card types.
	  
	  //  Name:      As in the selection box of the form - must be same as user's
	  //  Length:    List of possible valid lengths of the card number for the card
	  //  prefixes:  List of possible prefixes for the card
	  //  checkdigit Boolean to say whether there is a check digit
	  
	  cards [0] = {name: "Visa",
				   length: "13,16", 
				   prefixes: "4",
				   checkdigit: true};
	  cards [1] = {name: "MasterCard", 
				   length: "16", 
				   prefixes: "51,52,53,54,55",
				   checkdigit: true};
	  cards [2] = {name: "DinersClub", 
				   length: "14,16", 
				   prefixes: "36,54,55",
				   checkdigit: true};
	  cards [3] = {name: "CarteBlanche", 
				   length: "14", 
				   prefixes: "300,301,302,303,304,305",
				   checkdigit: true};
	  cards [4] = {name: "AmEx", 
				   length: "15", 
				   prefixes: "34,37",
				   checkdigit: true};
	  cards [5] = {name: "Discover", 
				   length: "16", 
				   prefixes: "6011,622,64,65",
				   checkdigit: true};
	  cards [6] = {name: "JCB", 
				   length: "16", 
				   prefixes: "35",
				   checkdigit: true};
	  cards [7] = {name: "enRoute", 
				   length: "15", 
				   prefixes: "2014,2149",
				   checkdigit: true};
	  cards [8] = {name: "Solo", 
				   length: "16,18,19", 
				   prefixes: "6334, 6767",
				   checkdigit: true};
	  cards [9] = {name: "Switch", 
				   length: "16,18,19", 
				   prefixes: "4903,4905,4911,4936,564182,633110,6333,6759",
				   checkdigit: true};
	  cards [10] = {name: "Maestro", 
				   length: "12,13,14,15,16,18,19", 
				   prefixes: "5018,5020,5038,6304,6759,6761",
				   checkdigit: true};
	  cards [11] = {name: "VisaElectron", 
				   length: "16", 
				   prefixes: "417500,4917,4913,4508,4844",
				   checkdigit: true};
				   
	  // Establish card type
	  var cardType = -1;
	  for (var i=0; i<cards.length; i++) {
	
		// See if it is this card (ignoring the case of the string)
		if (cardname.toLowerCase () == cards[i].name.toLowerCase()) {
		  cardType = i;
		  break;
		}
	  }
	  
	  // If card type not found, report an error
	  if (cardType == -1) {
		errors = errorMessage($('#PaymentTypeID'),ccErrors [0]); //apply error message
	  }
	   
	  // Ensure that the user has provided a credit card number
	  if (cardnumber.length == 0)  {
		errors = errorMessage($('#PaymentTypeID'),ccErrors [1]); //apply error message
	  }
		
	  // Now remove any spaces from the credit card number
	  cardnumber = cardnumber.replace (/\s/g, "");
	  
	  // Check that the number is numeric
	  var cardNo = cardnumber
	  var cardexp = /^[0-9]{13,19}$/;
	  if (!cardexp.exec(cardNo))  {
		errors = errorMessage($('#PaymentTypeID'),ccErrors [2]); //apply error message
	  }
		   
	  // Now check the modulus 10 check digit - if required
	  if (cards[cardType].checkdigit) {
		var checksum = 0;                                  // running checksum total
		var mychar = "";                                   // next char to process
		var j = 1;                                         // takes value of 1 or 2
	  
		// Process each digit one by one starting at the right
		var calc;
		for (i = cardNo.length - 1; i >= 0; i--) {
		
		  // Extract the next digit and multiply by 1 or 2 on alternative digits.
		  calc = Number(cardNo.charAt(i)) * j;
		
		  // If the result is in two digits add 1 to the checksum total
		  if (calc > 9) {
			checksum = checksum + 1;
			calc = calc - 10;
		  }
		
		  // Add the units element to the checksum total
		  checksum = checksum + calc;
		
		  // Switch the value of j
		  if (j ==1) {j = 2} else {j = 1};
		} 
	  
		// All done - if checksum is divisible by 10, it is a valid modulus 10.
		// If not, report an error.
		if (checksum % 10 != 0)  {
		errors = errorMessage($('#PaymentTypeID'),ccErrors [3]); //apply error message
		}
	  }  
	
	  // The following are the card-specific checks we undertake.
	  var LengthValid = false;
	  var PrefixValid = false; 
	  var undefined; 
	
	  // We use these for holding the valid lengths and prefixes of a card type
	  var prefix = new Array ();
	  var lengths = new Array ();
		
	  // Load an array with the valid prefixes for this card
	  prefix = cards[cardType].prefixes.split(",");
		  
	  // Now see if any of them match what we have in the card number
	  for (i=0; i<prefix.length; i++) {
		var exp = new RegExp ("^" + prefix[i]);
		if (exp.test (cardNo)) PrefixValid = true;
	  }
		  
	  // If it isn't a valid prefix there's no point at looking at the length
	  if (!PrefixValid) {
		errors = errorMessage($('#PaymentTypeID'),ccErrors [3]); //apply error message
	  }
		
	  // See if the length is valid for this card
	  lengths = cards[cardType].length.split(",");
	  for (j=0; j<lengths.length; j++) {
		if (cardNo.length == lengths[j]) LengthValid = true;
	  }
	  
	  // See if all is OK by seeing if the length was valid. We only check the 
	  // length if all else was hunky dory.
	  if (!LengthValid) {
		errors = errorMessage($('#PaymentTypeID'),ccErrors [4]); //apply error message
	  };
	  return errors;
	}
	
/*============================================================================*/


/*VALIDATE FORM*/