/*******************************************************************************
 *ValidationUtility 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 ValidationUtility = Class.create();
ValidationUtility.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	=	element.parentNode;
		    (!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(str){
    var trimmed	=	str;
    trimmed			= trimmed.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){
    var is_valid = true;
    if ( element_id.length > 0 && !($(element_id).checked) ){ is_valid = false; }
    return is_valid;
  }

  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;
  }