/*
 * Extra validation methods to supplement jquery.validate library 
 * (some methods could be candidates for common JS library)
 * 
 * Yen Pai (yen.pai@gmail.com)
 *	
 */

/**
 * @param params[0] jQuery selector String for year (YYYY)
 * @param params[1] jQuery selector String for month (1-12)
 * @param params[2] jQuery selector String for day (1-31)
 * @param params[3] minimum required age
 */
$.validator.addMethod("minimumAge", function(value, element, params) {		
		if( params.length<4 ) return false;
		var yearSelector = params[0];
		var monthSelector = params[1];
		var daySelector = params[2];
		var minAge = params[3];
		
		var year = $(yearSelector).val();
		var month = $(monthSelector).val();
		var day = $(daySelector).val();
		
		//alert( "Y/M/D, minAge = "+yearSelector+" "+year+"/"+monthSelector+" "+month+"/"+daySelector+" "+day +", "+minAge);
		
		year = parseInt(year);
		month = parseInt(month);
		day = parseInt(day);
		minAge = parseInt(minAge);
		if( isNaN(year) || isNaN(month) || isNaN(day) || isNaN(minAge) ) {
			return false;
		}			
		
		var dateEnteredPlusYears = new Date();
		dateEnteredPlusYears.setFullYear(year+minAge, month-1, day);
	
		var today = new Date();
		
		return ( dateEnteredPlusYears<=today );
				
	}, 'Age does not meet minimum requirement.');


/**
 * @param value MM/DD/YYYY or YYYY/MM/DD
 * @param element
 * @param params[0] days from today (positive or negative integer)
 */
$.validator.addMethod("dayRangeFromToday", function(value, element, params) {		
	if( params.length<1 ) return false;
	var daysFromToday = params[0];
	var maxDaysFromToday = null;
	if( params.length==2 ) {
		maxDaysFromToday = params[1];
	}
	
	var dateTokens = value.split('/');
	if( dateTokens.length<3 ) {
		//alert( "dayRangeFromToday:  bad date format.");
		return false;
	}
	
	var year = null;
	var month = null;
	var day = null;
	if( dateTokens[0].length==4 ) {
		year = dateTokens[0];
		month = dateTokens[1];
		day = dateTokens[2];
	} else {
		year = dateTokens[2];
		month = dateTokens[0];
		day = dateTokens[1];
	}
	
	// alert( "Y/M/D, delta = "+year+"/ "+month+"/ "+day +"; daysFromToday="+daysFromToday +"; maxDaysFromToday="+maxDaysFromToday);

	year = parseInt(year);
	month = parseInt(month);
	day = parseInt(day);
	daysFromToday = parseInt(daysFromToday);
	maxDaysFromToday = parseInt(maxDaysFromToday);
	if( isNaN(year) || isNaN(month) || isNaN(day) || isNaN(daysFromToday) || isNaN(maxDaysFromToday) ) {
		//alert( "dayRangeFromToday:  bad date or range input.");
		return false;
	}	
	
	var dateEntered = new Date();
	dateEntered.setFullYear(year, month-1, day);

	var todayPlusDelta = new Date();
	todayPlusDelta.setDate( todayPlusDelta.getDate()+daysFromToday );
	
	var maxDate = todayPlusDelta;
	if( maxDaysFromToday!=null ) {
		if( daysFromToday>0 && maxDaysFromToday<0 ) {
			alert( "dayRangeFromToday:  daysFromToday and maxDaysFromToday must both be greater than zero.");
			return false;
		} else if( daysFromToday<0 && maxDaysFromToday>0 ) {
			alert( "dayRangeFromToday:  daysFromToday and maxDaysFromToday must both be less than zero.");
			return false
		} else if( maxDaysFromToday==0 ) {
			alert( "dayRangeFromToday:  maxDaysFromToday cannot be zero.");
			return false;
		} else {
			maxDate = new Date();
			maxDate.setDate( maxDate.getDate()+maxDaysFromToday );
		}
	}
	
	//alert( 'dateEntered='+dateEntered+"; todayPlusDelta="+todayPlusDelta+"; maxDate="+maxDate);
	
	if( daysFromToday>0 ) {
		return ( dateEntered>=todayPlusDelta ) && ( dateEntered<=maxDate );
	} else {
		return ( dateEntered<=todayPlusDelta ) && ( dateEntered>=maxDate );
	}
			
}, 'Date is not within required range.');

/**
 * Validates for US phone number
 */
$.validator.addMethod("phoneUS", function(phoneNumber, element) {
	phoneNumber = phoneNumber.replace(/\s+/g, "");
	//alert(phoneNumber);
	return this.optional(element) || phoneNumber.length > 9 &&
	phoneNumber.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);

}, "Please specify a valid phone number");

/**
 * Custom validator to require other fields as a set
 * @return true if field is NOT required because dependent fields are not filled out; or true if field is filled out
 */
$.validator.addMethod("requiredIf", function(value, element, params) {	
	var valueLength = $.trim(value).length;
	var retVal = false;	
	if( valueLength > 0 ) {
		retVal = true;
	} else {	
		retVal = $( params[0] ).size() == 0;
	}
	//alert( params[0] +"; valueLength="+valueLength+"; size = "+ $(params[0]).size()+"; retVal = "+retVal );
	return retVal;
}, "This field is required.");

/**
 * Validates that entered value is NOT a specific value 
 * (useful to make sure that field is not equal to default value)
 */
$.validator.addMethod("not", function(value, element, params) {
	//alert( "value="+value + "; params.length="+params.length);
	if( !params || params.length==0 ) return false;
	return value!=params[0];
}, "This field is required.");


/**
 * Validates that entered value is NOT a specific value 
 * (useful to make sure that field is not equal to default value)
 */
$.validator.addMethod("atLeastOneChecked", function(value, element, params) {
	//alert( "value="+value + "; params.length="+params.length);
	if( !params || params.length==0 ) return true;
	for( i=0; i<params.length; i++ ) {
		if( $(params[i]+":checked").size()>0 ) return true;
	}
	return false;
}, "At least one item must be checked.");

