/*************************************************************************************
*                                Error Validation Script                             *
*   Page Title:   Error Validation Script                                            *
*   Page Version: 1.0                                                                *
*   Author:       Tyler Klein                                                        *
*   Date:         03/11/2009 
*   updated by:	  Chris Deemer 5/27/2009                                             *
*************************************************************************************/
// **** include FSErrorMessageSetUp.jspf before this js file so the error messeges are read from a properties files.
// 		<%@ include file="../snippets/ReusableObjects/FSErrorMessageSetUp.jspf"%>

var INC_ERRORS = true;      //An indicator that this page has been included

var minErrY = 0;            //The minimum top position that an error can be. Keeps errors from going above the fold
var minErrX = 455;          //The minimum left position that an error can be. Keeps errors from overlapping fields inadvertantly. If 0, the error appears immediately to the left of the field

var showFirstError = false; //true - pop-up appears on the first error in the list
var divErrMsg = null;       //Internal variable reference to the message overlay's div

var errFields = [];         //A list of fields that are associated with error messages
var errMap = [];            //The list of different error types
var firstTimeThru = true;
var showPopupErrors = true;		//used to indicate whether popups are shown - determined by user clicking on close button in popup - set by userClosedPopup();
var errLabelClass = 'error';
var errFieldClass = 'error';

/*******************************************************
* Validation Functions                                 *
*******************************************************/
function alwaysTrue(v){return(true);}
function alwaysFalse(v){ return(false); }
function isEmpty(v){ return( v.length == 0 ); }
function isLen2(v){ return( v.length != 2 ); }
function isLen3(v){ return( v.length != 3 ); }
function isLen4(v){ return( v.length != 4 ); }
function isLen5(v){ return( v.length != 5 ); }
function isSelected(v){ return(  v == 0 ); }
function emailNotExists(){ if(typeof(emailNotFound) != 'undefined' && emailNotFound == 'false'){return true;}else{return false;} }
function isSearchTextDefault(v) { return (document.getElementById('query').value == 'Enter Keyword or Item #');  }
function isBoxChecked(v){return $('#terms').is(':checked') ? false:true;}

function isValidLocationString(){return (RosettaFossilLocator.MyAddressGood()==0);}
function isEmail(v){ return( !(validateRegExp(v, "^[a-zA-Z0-9!#$%^&*+?._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9]+$") || (v.length == 0) ) ); } //blank email returns valid
function isARadioSelected(gname){return $('input[name="' + gname + '"]:checked').length>0 ? true:false;}
function isValidPassword(v) { return( v.length == 0 ); } // add other validation for password
function doPasswordsMatch() { 
	if(!(isEmail($('#userConfirmPassword').val()))){
		return false;
	}
	return  ($('#userPassword').val() != $('#userConfirmPassword').val()); 
	} 
function doUserRegPasswordsMatch() { 
	return  (document.getElementById('logonPassword').value != document.getElementById('logonPasswordVerify').value); 
	} 	
// regular expression helper function
function validateRegExp(value, exp){ 
	 var regex = new RegExp(exp);
	 return regex.test(value);
}

function isMinSearchTerm(v){
	return (v.length <= 2)
}


/******************************************************
* Review & Payment Error Functions                  *
******************************************************/

function isValidCC(v){
	var ccNumber = trim(v);
	return (ccNumber == "" || ccNumber == null || ((checkCountDigits(ccNumber, 16)==false)&&(checkCountDigits(ccNumber, 15)==false)));
}

function isValidCVC(v){
	var cvcNumber = trim(v);
	return (cvcNumber == "" || cvcNumber == null || ((checkCountDigits(cvcNumber, 3)==false)&&(checkCountDigits(cvcNumber, 4)==false)))
}


function isValidGiftCardNumber(v) {
var bGiftcardNumberError = false;
	var giftCardNumber = trim(v);
	if (giftCardNumber.length != 19) {
		bGiftcardNumberError = true;
	}
	var prefix = giftCardNumber.substr(0, 6);
	if (prefix != "603571") {
		bGiftcardNumberError = true;
	}
 return bGiftcardNumberError;
}
var current_date = new Date();
var current_year = current_date.getFullYear();
var current_month = current_date.getMonth() + 1;
function isValidMonthYear(v) { 

	return $('#cardYear').val() <= current_year && $('#cardMonth').val() < current_month;
	} 

function isValidMonthYear_saved(v) { 

	return $('#savedCardYear').val() <= current_year && $('#savedCardMonth').val() < current_month;
	} 

/*******************************************************
* Global Error Registration Functions                  *
*******************************************************/
function registerErrMsg( fn, msg, isError ){
	errMap[errMap.length] = {fn:fn, msg:msg, error:isError};
	return(errMap.length - 1);
}
function addMsgToControl( obj, errId ){
	var errStr = $(obj).attr('errors');
	$(obj).attr( 'errors', errId + (errStr ? "," + errStr : null) );
	var eArr = $(obj).data( 'errArr' );
	eArr.push( errId );
	$(obj).data( 'errArr', eArr );
}


/******************************************************
* Shipping & Billing Error Functions                  *
******************************************************/
function isEmptyFirstName(v){ return (v.length == 0);}
function isEmptyLastName(v){ return (v.length == 0);}
function isEmptyAddress(v){ return (v.length == 0);}
function isEmptyCity(v){ return (v.length == 0);}
function isEmptyState(v){ return (v.length == 0);}
function isEmptyZipCode(v){ return (v.length == 0);}
function isEmptyEmail(v){ return (v.length ==0);}
function isEmptyPhoneNo(v){ return (v.length == 0);}
function isValidPhoneNo(v) { 
 var phoneNumberWithoutSpaces = v.replace(/^\s+/g, "");
 var phoneRE = /^\(\d\d\d\)\d\d\d-\d\d\d\d$/; 
 var phoneRE1 = /^\(\d\d\d\) \d\d\d-\d\d\d\d$/; 
 var phoneRE2 = /^\d\d\d\-\d\d\d-\d\d\d\d$/; 
 var phoneRE3 = /^\d\d\d\d\d\d\d\d\d\d$/; 
 if (v.match(phoneRE)) { 
   return false; 
 } else if (v.match(phoneRE)) { 
   return false; 
 } else if (v.match(phoneRE1)) { 
   return false; 
 } else if (v.match(phoneRE2)) { 
   return false; 
 }  else if (v.match(phoneRE3)) { 
   return false; 
 } else{ 
   return true; 
 } 
}

function isValidZipCode(v) {

var regZip = /^([0-9]{5})$/;
 if (v.match(regZip)) { 
   return false; 
  } else {
   return true;
  } 

}

/*******************************************************
* Some common error message types                      *
*******************************************************/
errMap[0] = {fn:isEmpty, msg:errMapMsg_0, error:true};
errMap[1] = {fn:isEmail, msg:errMapMsg_1, error:true};
errMap[2] = {fn:isSelected, msg:errMapMsg_2, error:true};
errMap[3] = {fn:emailNotExists, msg:errMapMsg_3, error:true};
errMap[4] = {fn:isValidPassword, msg:errMapMsg_4, error:true};
errMap[5] = {fn:doPasswordsMatch, msg:errMapMsg_38, error:true};
errMap[6] = {fn:isValidLocationString,  msg:errMapMsg_39, error:true};
errMap[7] = {fn:isEmptyFirstName, msg:errMapMsg_7, error:true};
errMap[8] = {fn:isEmptyLastName, msg:errMapMsg_8, error:true};
errMap[9] = {fn:isEmptyAddress, msg:errMapMsg_9, error:true};
errMap[10] = {fn:isEmptyCity, msg:errMapMsg_10, error:true};
errMap[11] = {fn:isEmptyState, msg:errMapMsg_11, error:true};
errMap[12] = {fn:isEmptyZipCode, msg:errMapMsg_12, error:true};
errMap[13] = {fn:isEmptyPhoneNo, msg:errMapMsg_13, error:true};
errMap[14] = {fn:isEmptyEmail, msg:errMapMsg_14, error:true};
errMap[15] = {fn:isValidPhoneNo, msg:errMapMsg_15, error:true};
errMap[16] = {fn:isEmptyState, msg:errMapMsg_16, error:true};
errMap[17] = {fn:isValidGiftCardNumber, msg: errMapMsg_17, error:true };
errMap[18] = {fn:isLen4, msg:errMapMsg_18, error:true };

errMap[19] = {fn:isValidCC, msg:errMapMsg_19, error:true }; // credit card number
errMap[20] = {fn:isValidCVC, msg:errMapMsg_20, error:true }; // cvc number
errMap[21] = {fn:isSelected, msg:errMapMsg_21, error:true }; // month
errMap[22] = {fn:isSelected, msg:errMapMsg_22, error:true }; //year
errMap[23] = {fn:isValidMonthYear, msg:errMapMsg_23, error:true };  // year and month
errMap[24] = {fn:isSelected, msg:errMapMsg_24, error:true }; //  cc type
errMap[25] = {fn:isLen4, msg:errMapMsg_25, error:true }; // saved cc number
errMap[26] = {fn:isValidCVC, msg:errMapMsg_26, error:true }; // saved cvc
errMap[27] = {fn:isValidMonthYear_saved, msg:errMapMsg_23, error:true }; 
errMap[28] = {fn:isSearchTextDefault, msg:errMapMsg_28, error:true };
errMap[29] = {fn:isMinSearchTerm, msg:errMapMsg_29, error:true };
errMap[30] = {fn:isEmpty, msg:errMapMsg_30, error:true };
errMap[31] = {fn:isEmail, msg:errMapMsg_30, error:true };
errMap[32] = {fn:isEmpty, msg:errMapMsg_31, error:true };
errMap[33] = {fn:isEmpty, msg:errMapMsg_32, error:true };
errMap[34] = {fn:isEmpty, msg:errMapMsg_33, error:true };
errMap[35] = {fn:isEmpty, msg:errMapMsg_34, error:true };
errMap[36] = {fn:doUserRegPasswordsMatch, msg:errMapMsg_5, error:true };
errMap[37] = {fn:isEmpty, msg:errMapMsg_1, error:true };
errMap[38] = {fn:isValidPassword, msg:errMapMsg_38, error:true };
errMap[39] = {fn:isEmpty, msg:errMapMsg_39, error:true };
errMap[40] = {fn:isEmpty, msg:errMapMsg_40, error:true };
errMap[41] = {fn:isEmail, msg:errMapMsg_41, error:true };
errMap[42] = {fn:isValidZipCode, msg:errMapMsg_12, error:true };
errMap[43] = {fn:isEmpty, msg:errMapMsg_43, error:true};
errMap[44] = {fn:isEmail, msg:errMapMsg_43, error:true};
errMap[45] = {fn:isEmpty, msg:errMapMsg_17, error:true};
errMap[46] = {fn:isEmpty, msg:errMapMsg_18, error:true};
errMap[47] = {fn:isSelected, msg:errMapMsg_47, error:true};
errMap[48] = {fn:isSelected, msg:errMapMsg_48, error:true};
errMap[49] = {fn:isSelected, msg:errMapMsg_49, error:true};
errMap[50] = {fn:isLen4, msg:errMapMsg_50, error:true}; /* BML valid SSN digits  */
errMap[51] = {fn:isBoxChecked, msg:errMapMsg_51, error:true}; /* BML checkbox  */
//var ERR_REQUIRED = registerErrMsg(isEmpty, 'This field is required.', true); //error:false - message, error:true - error
//var ERR_EMAIL    = registerErrMsg(isEmail, "Email addresses must contain an '@' and end in '.com', '.net', '.org', etc.", true);

/*******************************************************
* Error Message Functions                              *
*******************************************************/
//Sets up all error message fields currently in the DOM

function setupErrors( _context ){
	var context = _context==undefined ? '#content_div' : _context;
	$(context + ' [errors]').each( function(Index){
		$(this).data('seenFocus', false);
		var errPage = $(this).attr("errPage"); $(this).data('errPage', errPage);
		var errors = $(this).attr("errors"); $(this).data('errors', errors);
		var errArr = errors.split(','); $(this).data('errArr', errArr);
		
		errFields[errFields.length] = $(this);
		
		$(this).blur( function(){
			for( var i = 0; i<errArr.length; i++){
				var eMap = errMap[errArr[i]];
				if( eMap.fn(this.nodeType == 'select' ? this.selectedIndex : $(this).val(), $(this)) ){
					if( eMap.error ){
						//$(this).addClass(errFieldClass);
						$(this).data('error', eMap.msg);
						updateError(context);
						return;
					}
				}
			}
			//$(this).removeClass(errFieldClass);
			$(this).data('error', null);
			updateError(context);
		})
		.focus( function(){
			//if( !$(this).data('seenFocus') ){ $(this).data('seenFocus', true); return;	}
			for( var i = 0; i<errArr.length; i++){
				var eMap = errMap[errArr[i]];
				if( eMap.fn($(this).val(), $(this)) ){
					//$(this).addClass(errFieldClass);
					showError( $(this), eMap.msg, eMap.error ? "error" : "info" , context);
					$(this).data('error',eMap.msg); //only flag this object as errored if it is an error and not a message.
					return;
				}
			}
			//$(this).removeClass(errFieldClass);
			$(this).error = null;		
		});
		
	})
}

function checkForEmailNotFoundParam(){
	if(typeof(emailNotFound) != 'undefined' && emailNotFound == 'false'){
		checkAllErrors(0,"emailFieldWrapper");
		/*firstTimeThru = false;
		showFirstError = true;
		var errPage = $('#email').attr("errPage"); 
		$('#email').data('errPage', errPage);
		var errors = $('#email').attr("errors"); 
		$('#email').data('errors', errors);
		var errArr = errors.split(','); $('#email').data('errArr', errArr);
		var eMap = errMap[errArr[0]];
		$('#email').addClass(errFieldClass);
		$('label[for=email]').addClass(errFieldClass);
		showError( $('#email'), eMap.msg, eMap.error ? "error" : "info" );
		$('#email').data('error',eMap.msg);
		emailNotFound = 'true';*/
	}
}


$().ready(function(){setupErrors();});

//Checks the errors list and repositions the error message window accordingly
function updateError(context){
	clearRosError();
		if (showFirstError) {
			for (var i = 0; i < errFields.length; i++) {
				if (errFields[i].data('error') && !errFields[i].data('suspendError')) {
					//showError(errFields[i], errFields[i].data('error'), "error", context);
					return;
				}
			}
		}
		else {
			for (var i = errFields.length - 1; i >= 0; i--) {
				if (errFields[i].data('error') && !errFields[i].data('suspendError')) {
					showError(errFields[i], errFields[i].data('error'), "error", context);
					return;
				}
			}
		}
}

//Suspends error messages on an object and its children
function suspendErrors( obj ){
	$('[errors]', $(obj)).each( function(index){ $(this).data('suspendError', true); });
}
//Enables error messages on an object and its children
function enableErrors( obj ){
	$('[errors]', $(obj)).each( function(index){ $(this).data('suspendError', false); });
}
//Removes the error message overlay
function clearRosError(){
	if( divErrMsg == null ) return;
	//killIFrameShim(message);
	divErrMsg.remove();
	divErrMsg = null;	
}

//Checks for errors within the set of fields with pageId = to the page number passed. By default this page number is 0. Returns true if no errors found.
function checkAllErrors(_page, _context){
	var firstActiveErrField;
	var al = arguments.length;
	var pageIndex;
	var contextIndex;
	for(var ai = 0; ai < al; ++ai){
		if(typeof(arguments[ai])=="number"){pageIndex=ai;}
		if(typeof(arguments[ai])=="string"){contextIndex=ai;}
	}
	var page = typeof(pageIndex)=='number' ? arguments[pageIndex] : 0;
	var context = typeof(contextIndex)=='undefined' ? '#content_div' : arguments[contextIndex];
	showPopupErrors = true;
	showFirstError = true;
	firstTimeThru = false;
	var isClean = true;
	for( var j=0; j<errFields.length; j++ ){
		var obj = errFields[j];
		if( (obj.data('errPage') == page) && (!obj.data('suspendError')) ){
			for( var i = 0; i<obj.data('errArr').length; i++){
				var eMap = errMap[obj.data('errArr')[i]];
				if( eMap.fn(obj.val(), $(this)) ){
					obj.addClass(errFieldClass);
					$('label[for='+obj.attr('id')+']').addClass(errLabelClass);
					obj.data('error', eMap.msg);
					isClean = false;
					if(typeof(firstActiveErrField) == "undefined"){firstActiveErrField = obj;}
					break;
				}
				else{
					obj.removeClass(errFieldClass);
					$('label[for='+obj.attr('id')+']').removeClass(errLabelClass);
					obj.data('error', null);
				}
			}
		} else {
			obj.removeClass(errFieldClass);
			$('label[for='+obj.attr('id')+']').removeClass(errLabelClass);
			obj.data('error', null);
		}
	}
	
	updateError(context);
	if(typeof(firstActiveErrField) != 'undefined'){firstActiveErrField.focus();}
	
	return( isClean );
}

//Draws the error message on the screen
function showError( field, msg, classPrefix, context ){
	clearRosError();
	if (showFirstError && showPopupErrors && !firstTimeThru) {
		
		var iHTML = '<div id="form_error_popup" '+(context==undefined?'':'style="z-index:1010"')+'><div class="wrapper clearfix"><div class="content">';
		iHTML += msg;
		iHTML += '</div><img alt="x" class="close_btn" src="/wcsstore/Fossil/images/en_US/form_validation/close_btn.png" /></div><div class="arrow"> </div></div>';
		

		$(context).append(iHTML);
		divErrMsg = $('#form_error_popup');
		$(divErrMsg).find('img.close_btn').mousedown(userClosedPopup);
		var $target = $(field);
		var $tt = divErrMsg;
		var $arrow = $tt.find('.arrow').eq(0);
		var wrapper = $(context).position();
		var targPos = $target.position();
		var targHeight = $target.height();
		var targWidth = $target.outerWidth()+ 20;
		var arrowWidth = $arrow.width();
		var arrowHeight = $arrow.height();
		var tipWidth = $tt.width();
		var tipHeight = $tt.height();
		
		var notifWidth = $tt.find('div.content').outerWidth() + $tt.find('img.close_btn').width()+20;
		
		var Top = targPos.top - tipHeight;
		
		if($().bgiframe){$(divErrMsg).bgiframe();}
		
		var tooCloseToRight = (notifWidth + targPos.left) > $('#content_div').width() ? true : false;
		
		var labelWidth = $('label[for='+$target.attr('id')+']').width() + 10;
		
		var fieldWidth = 0;		
		//how many child fields?
		var $childFields = $('label[for='+$target.attr('id')+']').parent().find("input, select");
		if($childFields.length == 1){
			fieldWidth = $childFields.eq(0).width();
		}
		if($childFields.length > 1){
			$childFields.each(function(i, obj){
				fieldWidth += $(obj).outerWidth(true);
			});
		}
		if($childFields.length == 0){//no label - position over target
		    fieldWidth = 20;
		}
		fieldWidth -= 20;
		
		var Left = targPos.left  + (labelWidth > fieldWidth ? fieldWidth : labelWidth);
		
		if(tooCloseToRight){
			$arrow.css('left', notifWidth-50);
			//target offset left + target width - notifWidth to get right aligned with target
			Left = targPos.left + targWidth - notifWidth;
		}
		
		$tt.css({
			left: Left,
			top: Top,
			width: notifWidth
		});
	}
}

function userClosedPopup(){
	showPopupErrors = false;
	clearRosError();
	return false;
}

