/*******************************************************************************
 *Validator class
 *requires form elements to have the error validation to be a class i.e. <input name="field" class="required" />
 *runs utitly functions based on the elements passed, matches validation with class
 *returns true or false
 *some custom error display: right now it there is no error msging, but it highlights a field or designated element
 */
var Validator = Class.create();
Validator.prototype =
{
	initialize: function(form_elements){
		this.current_element_id = "";
		this.validations				= "";
		this.form_elements			= form_elements;
	},
	isFormValid : function(){
		var	element_count	=	0;
		var error_elements			=	new Array();
		
		this.validations = this.form_elements.collect(function(element){
		this.current_element_id = element.id;
		var is_valid 						= true;
		var	is_custom_error 		= false;
			
			//assume you attached validation to year
			if(/(validate-dates)/i.test(element.className)){
				var dates	=	getArrayOfIds(this.current_element_id, 3);
				is_valid	= (isValidDate(dates[0], dates[1], dates[2]));
				
				//add error style for date fields
				addRemoveClasses(is_valid, dates);
				is_custom_error	=	true;
			}
			
			//assume you attached validation to year
			if(/(validate-past-dates)/i.test(element.className)){
				var dates	=	getArrayOfIds(this.current_element_id, 3);
				is_valid	= (isValidPast(dates[0], dates[1], dates[2]));
				
				//add error style for date fields
				addRemoveClasses(is_valid, dates);
				is_custom_error	=	true;
			}
			if(/(validate-request-date)/i.test(element.className)){
				var dates	=	getArrayOfIds(this.current_element_id, 3);
				is_valid = (isValidCoverage(dates[0], dates[1], dates[2]));
				
				//add error style for date fields
				addRemoveClasses(is_valid, dates);
				is_custom_error	=	true;
			}
			if(/(validate-in-months)/i.test(element.className)){
				var dates	=	getArrayOfIds(this.current_element_id, 2);
				is_valid = (isValidLengthInMonths(dates[0], dates[1]));
				is_custom_error	=	true;			
			}
			if(/(validate-two-radios)/i.test(element.className)){
				var radios	=	getArrayOfIds(this.current_element_id, 2);
				is_valid		= (isOneSelected(radios));
				var parent	=	element.parentNode;				
				(!is_valid) ? parent.addClassName("fieldWithErrors") : parent.removeClassName("fieldWithErrors");
				is_custom_error	=	true;			
			}
			if(/(validate-three-radios)/i.test(element.className)){
				var radios	=	getArrayOfIds(this.current_element_id, 3);
				is_valid		= (isOneSelected(radios));
				var parent	=	element.parentNode;		
				(!is_valid) ? parent.addClassName("fieldWithErrors") : parent.removeClassName("fieldWithErrors");
				is_custom_error	=	true;			
			}
			if(/(validate-phone)/i.test(element.className)){
				var phone_numbers	=	getArrayOfIds(this.current_element_id, 3);
				is_valid 					= (isValidPhone(phone_numbers));
				is_custom_error		=	true;
				//add error style for phone fields
				addRemoveClasses(is_valid, phone_numbers);
			}
			if(/(validate-checked)/i.test(element.className)){
				is_valid = (isChecked(this.current_element_id));
				is_custom_error	=	true;
				var parent	=	$("privacy_policy_container");
				(!is_valid) ? parent.addClassName("fieldWithErrors") : parent.removeClassName("fieldWithErrors");
			}

			//regular validations
			if(/(required)/i.test(element.className)){
				is_valid = (isNotEmptyInput(this.current_element_id));
			}
			if(/(validate-alpha)/i.test(element.className)){
				is_valid = (isValidRequiredAlphaInput(this.current_element_id));
			}
			if(/(validate-email)/i.test(element.className)){
				is_valid = (isValidEmail(this.current_element_id));
			}
			if(/(validate-state)/i.test(element.className)){
				is_valid = (isValidUsState(this.current_element_id));
			}
			if(/(validate-zip)/i.test(element.className)){
				is_valid = (isValidZip(this.current_element_id));
			}
			if(/(validate-number)/i.test(element.className)){
				is_valid = (isValidRequiredNumberInput(this.current_element_id));
			}
			if(/(validate-coverage-amount)/i.test(element.className)){
				is_valid = (isValidCoverageAmount(this.current_element_id));
				if(is_valid){ grabDigits(); }
			}
			
			if(!is_custom_error){
				(!is_valid) ? $(element).addClassName("fieldWithErrors") : $(element).removeClassName("fieldWithErrors");
			}
			return is_valid;
		});
		
		return this.validations.all(function(v){ return (v == true); });
	}
}

	/*
	 *util functions
	 *
	 *isNullorEmpty :: check for empty or null values
	 *trim :: remove white space
	 *showHide:: hide or show hidden fields passing switch state and id
	 *isDefined :: checks if id/field exists
	 */
	function trim(field){
		var trimmed	= field.replace(/^\s+/, '');	// left trim
		trimmed			=	trimmed.replace(/\s+$/, '');	// right trim
		return trimmed;
	}

	//test if null or empty
	function isNullOrEmpty(id){
		return (	(trim($F(id)) == null || trim($F(id)) == '') && isDefined(id)	)
	}

	function isDefined(id){
		if($(id) == null){
			if(document.getElementsByName(id).length == 0){ return false; }
		}else{
			return true;
		}
	}

	function fadeIn(id){
		if(isDefined(id)){
			new Effect.Appear(id);
		}
	}

	function fadeOut(id){
		if(isDefined(id)){
			new Effect.Fade(id);
		}
	}

	function clearErrorMessage(id){
		if(isDefined(id)){
			$(id).innerHTML="";
		}
	}
	
	function grabDigits(){
		var raw_value = $F("coverage_amount").gsub(/\D/, '');
		var first_group =""; var second_group=""; var third_group=""; var millions =""; var start_group ="";
		if(raw_value.length > 6){
			//grab first 7 digits
			millions 			= raw_value.substr(0,7);	
			start_group 	= (millions.length%3 == 0) ? 3 : (millions.length%3);		
			first_group		= millions.substr(0, start_group);
			second_group 	= millions.substr(1, 3);
			third_group 	= millions.substr(4, 3);
		}else{
			start_group 	= (raw_value.length%3 == 0) ? 3 : (raw_value.length%3);		
			first_group 	= raw_value.substr(0, start_group);
			second_group 	= raw_value.substr(start_group, 3);
		}		
		$("coverage_amount").value = (third_group == '') ? first_group + "," + second_group : first_group + "," + second_group + "," + third_group;
	}
	
	/* error msgs */
	var error_msg_required			=	'\nThis is a required field.';
	var error_msg_select_one		=	'\nPlease select one of the above options.';
	var error_msg_numeric				=	'\nThis is a numeric field.';
	var error_msg_weight				=	'\nPlease enter a valid weight.';
	var error_msg_alpha_num			=	'\nPlease use letters only (a-z).';
	var error_msg_email					=	'\nPlease enter a valid email address.';
	var error_msg_phone					=	'\nPlease enter a valid phone number.';
	var error_msg_height				=	'\nPlease select a valid height.';
	var error_msg_height				=	'\nPlease select a valid weight.';
	var error_msg_zipcode				=	'\nPlease enter a valid zip code.';
	var error_msg_dob						=	'\nPlease enter a valid date of birth.';
	var error_msg_child_dob			=	'\nQuotes cannot be provided for children over 25 years old.';
	var error_msg_child_parent	=	'\nChildren cannot be older than the parent(s).';
	
	
	function isValidSelection(element_id){
		var is_valid = true;
		if(isDefined(element_id)){
			var parent			= $(element_id).parentNode;
			var selections	= parent.getElementsByTagName('SELECT');
			if(selections.length > 0){
				if ( $(selections[0].id).value == "" ){ is_valid = false; }
			}
		}
		return is_valid;
	}
	
	function isOneSelected(element_ids){
		var is_valid 	= true;
		is_valid	 		= element_ids.any(function(e){ return $(e).checked });
		return is_valid;
	}

	function isChecked(element_id){
		return $(element_id).checked;
	}

	function unChecked(element_id){
		var is_valid = true;
		if(isDefined(element_id) ){
			var checkbox = Form.getElements($(element_id).parentNode);
			checkbox[0].checked = false;
			checkbox[1].checked = false;
		}
		return is_valid;
	}

	function isNotEmptyInput(element_id){
		var is_not_empty = true;
		if(isDefined(element_id)){
			var input_field	 = Form.getElements($(element_id).parentNode);
			if(input_field.length > 0){
				if ( isNullOrEmpty(input_field[0].id) ){ is_not_empty = false; }
			}
		}
		return is_not_empty;
	}

	function isValidNumber(element_id){
		var is_valid = true;
		if(	isDefined(element_id)	){
			var number_field	= Form.getElements($(element_id).parentNode);
			if(number_field.length > 0){
				if ( /\D/.test(trim($(number_field[0].id).value) ) ){ is_valid = false; }
			}
		}
		return is_valid;
	}

	function isValidRequiredNumberInput(element_id){
		var is_valid = true;
		if(isDefined(element_id)){
			var number_field	 = Form.getElements($(element_id).parentNode);
			if(number_field.length > 0){
				if (isNullOrEmpty(number_field[0].id)){
					is_valid = false;
				}else if ( /\D/.test( (trim($(number_field[0].id).value)) ) ){
					is_valid = false;
				}
			}
		}
		return is_valid;
	}

	function isValidCoverageAmount(element_id){
		var is_valid = true;		
		var raw_value = $F(element_id).gsub(/\D/, '');
		
		if (isNullOrEmpty(element_id)){
			is_valid = false;
		}else if ( !/\d/.test( (trim(raw_value)) ) ){
			is_valid = false;
		}
		return is_valid;
	}

	function isValidRequiredAlphaInput(element_id){
		var is_valid = true;
		if(isDefined(element_id)){
			var alpha_field	 = Form.getElements($(element_id).parentNode);
			if(alpha_field.length > 0){
				if (isNullOrEmpty(alpha_field[0].id)){
					is_valid = false;
				}else if ( !/^[\D]+$/.test( (trim($(alpha_field[0].id).value)) )	){ 
					is_valid = false; 
				}
			}
		}
		return is_valid;
	}

	function isValidUsState(element_id){
		var is_valid = true;
		if( isDefined(element_id) ){
			var parent_node		= $(element_id).parentNode;
			var states				 = parent_node.getElementsByTagName('SELECT');
			
			if(states.length == 0){ //checks for drop down element is valid
				var states	 	= parent_node.getElementsByTagName('INPUT');
			}
			var all_states 	=	new Array("al","ak","az","ar","ca","co","ct","de","dc","fl","ga","hi","id","il","in","ia","ks","ky","la","me","md","ma","mi","mn","ms","mo","mt","ne","nv","nh","nj","nm","ny","nc","nd","oh","ok","or","pa","ri","sc","sd","tn","tx","ut","vt","va","wa","wv","wi","wy");
			
			var is_valid		=	all_states.any(function(value){ return (states[0].value).toLowerCase()	== value; });
		}
		return is_valid;
	}

	function isValidEmail(element_id){
		var is_valid = true;
		// validate email
		if( isDefined(element_id)	){
			var email_field = Form.getElements($(element_id).parentNode);
			if(email_field.length > 0){
				var email		 = email_field[0].id;
				if( isNullOrEmpty(email) ){
					is_valid = false;
				}else if( !/\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test($F(email)) ){
					is_valid = false;
				}
			}
		}
		return is_valid;
	}

	function isValidPhone(phone_fields){
		var is_valid		 = true;
		if(phone_fields.length == 3){
			var phone_area			= $F(phone_fields[0]);
			var phone_exchange	= $F(phone_fields[1]);
			var phone_station	 = $F(phone_fields[2]);
		}else if(phone_fields.length == 1){
			var phone_area			= $F(phone_fields[0]).substr(0,3);
			var phone_exchange	= $F(phone_fields[0]).substr(3,3);
			var phone_station	 = $F(phone_fields[0]).substr(6,4);
		}

		if(	!/^[2-9][0-8][0-9]$/.test(phone_area) || !/^[2-9][0-9][0-9]$/.test(phone_exchange) || !/^[0-9][0-9][0-9][0-9]$/.test(phone_station)	){
			is_valid = false;
		}
		return is_valid;
	}

	function isValidZip(element_id){
		var is_valid	 = true;
		
		if(isDefined(element_id)){
			var zipcode		 = Form.getElements($(element_id).parentNode);
			if( !/^\d{5}$/.test($F(zipcode[0].id)) ){ is_valid = false; }
		}
		return is_valid;
	}
	
	/*gets element ids by getting ids from the parent
	 * returns an array of ids: (ids determined by the field count or how many fields)
	 */
	function getArrayOfIds(element_id, field_count){
		var has_elements 	= false;
		var parent				=	$(element_id).parentNode;
		while(!has_elements){
			if(Form.getElements(parent).length != field_count){
				parent	=	parent.parentNode;
			}else{
				has_elements	=	true;
			}
		}
		var elements		=	Form.getElements(parent);
		var element_ids = new Array();
		for(i=0; i < elements.length; i++){
			element_ids[i]	=	elements[i].id;
		}
		return element_ids;
	}
	
	function isValidLengthInMonths(element_yyyy_id, element_mm_id){
		var is_valid 	= true;
		var years			=	trim($F(element_yyyy_id));
		var months		=	trim($F(element_mm_id));
		
		if(	(years == "" && months == "") || (years == 0 && months == 0)){
				is_valid = false;
				$(element_mm_id).addClassName("fieldWithErrors");
				$(element_yyyy_id).addClassName("fieldWithErrors");
		}else{
			//if not empty make sure they are in the correct format			
			if( years != 0 && (months == 0 || months != "")){
				if(	!(/(^[1-9]{1}$|^[1-9]{1}[0-9]{1}$)/.test(years)) ){
					is_valid = false;
					$(element_yyyy_id).addClassName("fieldWithErrors");
				}else{
					$(element_yyyy_id).removeClassName("fieldWithErrors");
				}
			}
			if((months == 0 && (years != 0 || years != ""))){
				if(	!(/^0$|^[1-9]{1}$|^[1]{1}[0-1]{1}$/.test(months)) ){
					is_valid = false;
					$(element_mm_id).addClassName("fieldWithErrors");
				}else{
					$(element_mm_id).removeClassName("fieldWithErrors");
				}
			}		 
		}
		return is_valid;
	}
	
	function addRemoveClasses(is_valid, elements){
		for(i=0; i < elements.length; i++){
			(!is_valid) ? $(elements[i]).addClassName("fieldWithErrors") : $(elements[i]).removeClassName("fieldWithErrors");
		}
	}

	/*
	 *isValidDate(element_id)
	 *returns: true/false
	 *checks if it is a valid date
	 */
 function isValidDate(element_mm_id, element_dd_id, element_yyyy_id){
		var is_valid				 = true;
		if(isDefined(element_mm_id) && isDefined(element_dd_id) && isDefined(element_yyyy_id)){
			var new_date	= new Date();
			var this_mm	 = $(element_mm_id).value - 1;
			var full_date = this_mm + "/" + $(element_dd_id).value + "/" + $(element_yyyy_id).value;
			new_date.setFullYear( $(element_yyyy_id).value, this_mm,	$(element_dd_id).value );

			if(	$(element_mm_id).value		== "" || new_date.getMonth() != this_mm ||
				 	$(element_dd_id).value		== "" || /Invalid|NaN/.test(new Date(full_date)) ||
					$(element_yyyy_id).value	== "" || $(element_yyyy_id).value < 1911 ||	$(element_yyyy_id).value > 2038){
					is_valid = false;
			}
		}
		return is_valid;
	}

	/*
	 *isValidDate(error_id)
	 *returns: true/false
	 *checks if it is a valid date
	 */
	function isValidPast(element_mm_id, element_dd_id, element_yyyy_id){
		var is_valid = true;
		is_valid		 = isValidDate(element_mm_id, element_dd_id, element_yyyy_id);
		if(is_valid){
			var todays_date	 = new Date();
			var df_mm	 			= $F(element_mm_id) - 1;
			var df_dd	 			= $F(element_dd_id);
			var df_yyyy 			= $F(element_yyyy_id);
			var ins_date			= new Date();
			ins_date.setFullYear(df_yyyy, df_mm, df_dd)
			is_valid					= (todays_date >= ins_date);
		}
		return is_valid;
	}
