//Checkout validation
//
//version 3.0
// 3.01 11/26/05 fixed iPostal msg and isPostal regexp error
//requires formapi.js

//Global flags for conditional inputs
var fIntl=0;	//International flag	
var fSpec=0;	//Specail handling flag
var fCC=0;		//CC Payment flag

//Normal state field colors
var color='#000';
var bgcolor='#fff';

//Invalid error messages
var iZip="This field must be a 5 or 9 digit US zipcode (like 94043 or 94043-1234). Please reenter it now.";
var iPostal="This field must be a valid postal code. If you are from the few countries without postal codes like Ireland, enter 'none'.";
var iEmail="This field must be a valid email address (like foo@bar.com). Please reenter it now.";
var iUSPhone="This field must be a 10 digit U.S. phone number (like (415) 555-1212). Please reenter it now.";
var iIntlPhone="This field must be a valid international phone number '+()-' and '0-9' allowed . Please reenter it now.";
var iUSState="This field must be a valid two character US state abbreviation (like CA for California) if you have 'Country of Origin' as USA. Please reenter it now.";
var iCC="Invalid Credit Card Number, please reenter";
var mCC="With credit card payments please select expiration date";

//error support functions
function killEnter(e) {
	if(typeof(event)!='undefined'){	//MSIE 
 	 	return (event.keyCode != 13);
 	}
	if(typeof(e)!='undefined'){
		if(typeof(e.keyCode)!='undefined'){ //W3C
			return (e.keyCode != 13);
		}
		if (typeof(e.which)!='undefined'){	//NN4x
			return (e.which != 13);
		}	
	}
	return true; //Not Supported	
}

function errorField(ff){	
	if(typeof(ff.style)!='undefined'){
		ff.style.color='#f00';
		ff.style.backgroundColor='#fdd';
	}
}

function resetField(ff){
	if(typeof(ff.style)!='undefined'){	
		ff.style.color=color;
		ff.style.backgroundColor=bgcolor;
	}	
}

function warn(ff, msg){
	alert(msg);
	errorField(ff);
	setFieldFocus(ff);	//must be AFTER alert or endless loop
	return false;	
}

function rtrim(raw){
	var re=/\s+$/
	return raw.replace(re, '');
}

function ltrim(raw){
	var re=/^\s+/;
	return raw.replace(re, '');
}

function trim(raw){
	return ltrim(rtrim(raw));
}

function limitString(){
	var me=this;
	if(me.value.length>me.Xmax){
		var msg="Note, you have exceeded the " + me.Xmax;
		msg+=" character limit for the " + me.Xname;
		msg+=" field and your entry has been truncated";
		alert(msg);
		me.value=me.value.substr(0, me.Xmax);
	}
}

function reformatZip(ff,goodDigits){
	var parts=goodDigits.match(/(\d{5})(\d{4})?/);
	if(parts[2]){ff.value=parts[1] + '-' + parts[2]; }
	else { ff.value=parts[1]; }
	return true;
}

function reformatUSPhone(ff,goodDigits){
	var re=/^(\d{3})(\d{3})(\d{4})/
	ff.value=goodDigits.replace(re,"($1) $2-$3");
	return true;
}

function reformatCC(ff,goodDigits){
	var re=/^(\d{4})(\d{4})(\d{4})(\d{1,4})/
	ff.value=goodDigits.replace(re,"$1-$2-$3-$4");
	return true;
}

//is functions
function isZip(digits){
	return ((digits.length==5) || (digits.length==9));
}

function isPostal(code){
	var re=/^[\w \d   -]{3,20}/;
	return re.test(code);
}

function isIntlPhone(code){
	var re=/^[+ ( \d][\d ( )   -]{9,20}/;
	return re.test(code);
}

function isUSPhone(digits){
	var re=/^[2-9]\d{9}$/;
	return re.test(digits);
}

function isEmail(clean){	//not too constraining
	var re=/^[^@]+@([-\w]+\.)+[A-Za-z]{2,4}$/;
	return re.test(clean);
}

function isUSState(code){
	var USStateCodes="AL AK AS AZ AR CA CO CT DE DC FM FL GA GU HI ID IL IN IA KS KY LA ME MH MD MA MI MN MS MO MT NE NV NH NJ NM NY NC ND MP OH OK OR PW PA PR RI SC SD TN TX UT VT VI VA WA WV WI WY AE AA AE AE AP";
	var re =new RegExp('\\b' + code + '\\b');	//sandwich with delim and easy way to insure whole 2 letter match!
		return re.test(USStateCodes);			//much simpler!
}

//set conditional flag functions, assoc with radio/check/select ctrls
function setOrigin(){
	var me=this;
	var val=getFormFieldValue(me);
	fIntl=(val!='USA');
	return fIntl;
}

function setSpecial(){
	var me=this;
	var val=getFormFieldValue(me);
	fSpec=(val=='yes');	//this flag is positive
	return fSpec;
}

function setPayment(){
	var me=this;
	var val=getFormFieldValue(me);
	fCC=((val!='CK/MO')&&(val!='none'));
	return fCC;
}


//check functions
function checkString(){
	var me=this;
	var clean=trim(me.value);
	me.value=clean;		//by default put clean value back	
	if(clean.length<me.Xmin)	{
		var msg="This field requires a valid " + me.Xname + ". Please reenter it now.";
		return warn(me, msg);
	}
	else {
		resetField(me);
		return true;
	}	
}

function checkPostal(){	
	var me=this;
	var clean=trim(me.value);
	me.value=clean;		//by default put clean value back	
	if(fIntl){
		if(isPostal(clean)){
			resetField(me);	
			return true;
		}
		else {
			return warn(me, iPostal);
		}
	}
	else{
		var digits=clean.replace(/\D/g, '');
		if(isZip(digits)){
			resetField(me);
			return reformatZip(me, digits);
		}
		else { 
			return warn(me, iZip); 
		}
	}
}

function checkPhone(){
	var me=this;
	var clean=trim(me.value);
	me.value=clean;		//by default put clean value back	
	if(fIntl){
		if(!isIntlPhone(clean)){
			return warn(me, iIntlPhone);
		}
		resetField(me);	
		return true;
	}
	else{
		var digits=clean.replace(/\D/g, '');
		if(!isUSPhone(digits)){
			return warn(me, iUSPhone);
		}
		resetField(me);
		return reformatUSPhone(me,digits);			
	}	
}

function checkEmail(){
	var me=this;
	var clean=trim(me.value);
	me.value=clean;		//by default put clean value back
	if(!isEmail(clean)){
		return warn(me, iEmail);	
	}
	resetField(me);
	return true;
}

function checkState(){
	var me=this;
	var clean=trim(me.value);
	me.value=clean;		//by default put clean value back
	if(fIntl){
		resetField(me);
		return true; //now 'province' optional
	}
	me.value=clean=clean.toUpperCase();
	if(!isUSState(clean)){
		return warn(me, iUSState);
	}
	resetField(me);
	return true;
}

//Special Conditional Checks
function checkCountry(){ //Conditional on fIntl 
	var me=this;
	var clean=trim(me.value);
	me.value=clean;		//by default put clean value back	
	if(fIntl){
		if(clean.length<me.Xmin){
			var msg="You have selected 'International', please enter your county's name.";
			return warn(me, msg);
		}
	}
	resetField(me);
	return true;
}

function checkSpecial(){ //Conditional on fSpec 
	var me=this;
	var clean=trim(me.value);
	me.value=clean;		//by default put clean value back		
	if(fSpec){
		if(clean.length<me.Xmin){
			var msg="You have checked Special Handling Request.";
			return warn(me, msg);
		}
	}
	resetField(me);
	return true;
}

function checkExpired(ffMo, ffYr){
	var mo=parseInt(ffMo.value, 10);
	var yr=parseInt(ffYr.value, 10);
	var card=((yr*100)+mo);
	var now=new Date();
	var today=(now.getFullYear()-2000) * 100;
	today+=(now.getMonth()+1)// 0-11 => 1-12
	if(card<today){
		return warn(ffYr, "The credit card has expired");
	}
	resetField(ffMo);	
	resetField(ffYr);
	return true;
}

function luhn10(ccstr){
	var sum=0;
	var digits=ccstr.split('');			//first split digits into an array
	digits.reverse()					//revese order to proccess from last digit
	for(var i=0; i<digits.length; i++){
		digits[i]=parseInt(digits[i]);	//convert from string to integers
		if(i % 2){						//double the odd digits
			digits[i]*=2;
			if(digits[i]>9){			//if product 2 digits, add digits together
				digits[i]-=9;			//	n-9 gives same result:
			}							// (13-9=4) as (13=> 1+3=4)
		}
		sum+=digits[i];			//sum digits
	}
	return((sum%10)==0); 		//return true if passed	
}

function checkCC(){
	var me=this;
	var digits=me.value.replace(/\D/g, '');	//strip all but digits
	var ffpmt=me.form.payment;
	var len=digits.length.toString();
	if(fCC){
		var pmt=getFormFieldValue(ffpmt);		
		var cc=new Object;	//same filter regex as php module
		cc['VISA']	={re:/^4/, 				lenre:/^1[36]$/, 	luhn10:1};   
		cc['MC']	={re:/^5[1-5]/, 		lenre:/^16$/,		luhn10:1};   
		cc['AMEX']	={re:/^3[47]/, 			lenre:/^15$/, 		luhn10:1};   
	//	cc['DISC']	={re:/^6011/, 			lenre:/^16$/, 		luhn10:1};   
	//	cc['ENRT']	={re:/^2(014|149)/, 	lenre:/^15$/, 		luhn10:0};   
	//	cc['JCB']	={re:/^(1800|2131|3)/, 	lenre:/^1[56]$/, 	luhn10:1};
		if(cc[pmt].lenre.test(len)){		//1st hurdle right length
			if(cc[pmt].re.test(digits)){	//2nd hurdle right prefix
				if(cc[pmt].luhn10){				//req luhn?
					if(!luhn10(digits)){		//if not passed
						return warn(me, iCC + ' LUHN');
					}
				}
				resetField(me);
				return reformatCC(me, digits);	//passed
			}
			return warn(me, iCC + ' PFX');	
		}		
		return warn(me, iCC + ' LEN');		
	}
	else{
		if(len) { 
			return warn(ffpmt, "You need to select Credit Card type for credit card payments"); 
		}
	}
	resetField(me);
	return true;
}

function checkDate(){
	var me=this;
	if(fCC){
		if(me.value=='none'){
			return warn(me, mCC);
		}
		else if(me.name=='expYr'){
			var ffMo=me.form['expMo'];
			if(ffMo.value!='none'){ //if not will exit with error	
				return checkExpired(ffMo, me);				
			}
			return warn(ffMo, mCC);
		}
		else { //mo is not non so check expired if not yr not none
			var ffYr=me.form['expYr'];
			if(ffYr.value!='none'){
				return checkExpired(me, ffYr);
			}
		}		
	}
	resetField(me);
	return true;
}

function validatePayment(){
	var me=this;
	var ffCC=me.form.cc;
	var ffMo=me.form.expMo;
	var ffYr=me.form.expYr;
	if(fCC){
		return(ffCC.valid() && ffYr.valid());
	}
	setFormFieldDefaultValue(ffCC);//ffCC.value='';
	setFormFieldDefaultValue(ffMo);//ffMo.value='';
	setFormFieldDefaultValue(ffYr);//ffYr=me.value='';
	return true;	
}

function initField(ff, func, friendlyname, min, max){
	ff.onchange=func;		
	ff.valid=func;	
	ff.Xname=friendlyname; 
	ff.Xmin=min;
	ff.Xmax=max;
	if(typeof(max)!='undefined'){
		ff.onkeypress=limitString;
	}
}

function initPaymentGroup(f){
	//'payment' SELECT for payment type sets fCC 
	//'cc' TEXT conditional when fCC set
	//'expMo' & 'expYr'SELECT conditional when fCC set
	f.payment.onchange=setPayment;		//only set flag
	f.payment.valid=validatePayment;	//special validate only function when posting
	f.payment.Xname='Payment Type';
	f.cc.onchange=checkCC;
	f.cc.valid=checkCC;
	f.cc.Xname='Credit Card Number';
	f.expMo.onchange=checkDate;
	f.expMo.valid=checkDate;
	f.expMo.Xname='Expiration Month';
	f.expYr.onchange=checkDate;
	f.expYr.valid=checkDate;
	f.expYr.Xname='Expiration Year';
}

function confirmMailedPmt(me){	//now attached to next button so only check when going forward
	var f=me.form;
	var ot=getFormFieldValue(f.orderType);
	var pt=getFormFieldValue(f.payment);	
	if(pt=='CK/MO'){
		var msg;
		if(ot=="Gallery"){
		msg="Items from the Gallery are one-of-a-kind pieces and are sold on a first come basis.\n";
		msg+="We will hold your piece for 7 business days for your payment, but credit card is\n";
		msg+="by far the safest and surest way to guarantee a successful addition to your collection!\n\n";
		}
		else if(ot=="Ebay"){
		msg="We expect payment for items sold at auction within 7 business days of the auction's \n";
		msg+="conclusion unless previously arranged, but credit card is by far the safest and \n";
		msg+="surest way to guarantee a successful addition to your collection!\n\n";
		}
		else{
		msg="We will start you project upon receipt of your payment, but credit card\n"; 
		msg+="is by far the safest and most expedient way to get your project started.\n\n";
		}
		return(confirm(msg + "Do you want to continue with your payment choice?"));		
	}
	return true;
}

