//change an id to readable text for error string
String.prototype.toPlainText = function(){
    
	var plainString = this
	plainString = plainString.replace( /\d/g, '')
	plainString = plainString.replace( /_/g, ' ')
	return plainString.capitalize()
	
}

/*
 * FORM VALIDATOR
 * use specific classes on form elements to validate them
 * 
 * email - proper format, no illegal characters
 * phone - proper length, no illegal characters, formats input
 * state - proper length, converts to caps
 * zip - handles American and Canadian, proper length, no illeagal characters, formats input
 * required - tests if the form element is empty or unset, workes on text, checkbox, radio, select, textarea
 */

// defaults
var ERRORBACKGROUNDCOLOR = 'yellow'
var ORIGINALBACKGROUNDCOLOR = 'white'
var SELECTNULL = "" //value for an "unselected" option in a select

//constraint: every required field must have an id for error message to display correctly
function validateForm( theEvent){
	
	var theForm = theEvent.target

	stripAllTextInputs( theForm)
	
	var validatedFields = new Array();
	
	var reason = "";
	
	// validate specific formats
	// gather the fields with specific formats and validate them with the appropriate specific function, then place in an array of already validated fields
	validatedFields = validatedFields.concat($A(theForm.select(    'input.email').each(    validateEmail)))
	validatedFields = validatedFields.concat($A(theForm.select(    'input.phone').each(    validatePhone)))
	validatedFields = validatedFields.concat($A(theForm.select(    'input.state').each(    validateState)))
	validatedFields = validatedFields.concat($A(theForm.select(      'input.zip').each(      validateZip)))
	
	// make sure required fields are not empty
	// gather all the required fields, remove the fields already validated, and validate the remaining fields
	var requiredFields = theForm.select( 'input.required', 'select.required', 'textarea.required')
	var fieldsNotValidated = requiredFields.reject( function( reqFld){ return validatedFields.member( reqFld) })
	
	fieldsNotValidated.each( validateEmpty)
	
	//if there were any invalid inputs, popup the error text and stop submission
	if (reason != ""){
		alert("Some fields need correction:\n" + reason);
		theEvent.stop()
	}

	
	
	
	/***************************************************************
	 * MEMBER FUNCTIONS
	 ***************************************************************/
	
	function stripAllTextInputs( theForm){
		
		for(var i = 0; i < theForm.elements.length; i++){
	
			if(theForm.elements[i].type == "text")
				theForm.elements[i].value.strip()
	
		}
		
	}
	
    function validateEmpty( fld) {

        if(fld.tagName.toLowerCase() == 'select'){
			
			if(fld.value == SELECTNULL){
                fld.style.background = ERRORBACKGROUNDCOLOR;
                reason += "Pick a " + fld.id.toPlainText() + ".\n"
			}else
                fld.style.background = ORIGINALBACKGROUNDCOLOR;

        }else if(fld.tagName.toLowerCase() == 'textarea'){
            
			if(fld.value == ""){
                fld.style.background = ERRORBACKGROUNDCOLOR;
				reason += "Respond to " + fld.id.toPlainText() + ".\n"
			}else
                fld.style.background = ORIGINALBACKGROUNDCOLOR;
            
        }else if(fld.tagName.toLowerCase() == 'input'){
            
            if(fld.type.toLowerCase() == 'text' || fld.type.toLowerCase() == 'password'){
		   
	            if (fld.value.length == 0) {
			        fld.style.background = ERRORBACKGROUNDCOLOR; 
			        reason += "The " + fld.id.toPlainText() + " field has not been filled in.\n"
				} else 
                    fld.style.background = ORIGINALBACKGROUNDCOLOR;
		      
            }else if(fld.type.toLowerCase() == 'checkbox' || fld.type.toLowerCase() == 'radio'){

                var flds = $A(fld.form.getInputs( undefined, fld.name))

				if(flds.all( function(oneFld){ return !oneFld.checked })){
					var reasonText = "Respond to " + fld.id.toPlainText() + ".\n"
					if(!reason.include( reasonText))  // if all boxes or radios have required class, keep the message from reapeating
						reason += reasonText
				}
		        
			}else
                throw('type not recognized: ' + fld)
			    
		}else
		      throw('tag not recognized: ' + fld)  
		        
    }
	       
	function validateEmail( fld) {
	
	    var emailFilter = /^[^@]+@[^@.]+\.[^@]*\w\w$/ ;
	    var illegalChars= /[\(\)\<\>\,\;\:\\\"\[\]]/ ;
	   
	    if (fld.value == "") {
			if(fld.hasClassName( 'required')){
				reason += "The Email field has not been filled in.\n"
	        	fld.style.background = ERRORBACKGROUNDCOLOR;
	        }else
		        fld.style.background = ORIGINALBACKGROUNDCOLOR;
	    } else if (!emailFilter.test(fld.value)) {
	        reason += "Please enter a valid email address.\n";
	        fld.style.background = ERRORBACKGROUNDCOLOR;
	    } else if (fld.value.match(illegalChars)) {              //test email for illegal characters
	        reason += "The email address contains illegal characters.\n";
	        fld.style.background = ERRORBACKGROUNDCOLOR;
	    } else {
	        fld.style.background = ORIGINALBACKGROUNDCOLOR;
	    }
	
	}
	
	// constraint: no international numbers
	function validatePhone( fld) {
	
	    var stripped = fld.value.replace(/[\(\)\.\-\ ]/g, '');
		phoneFilter = /^\d{10}$/
	
	   if (fld.value == "") {
			if(fld.hasClassName('required')){
				reason += "The Phone number field has not been filled in.\n";
	        	fld.style.background = ERRORBACKGROUNDCOLOR;
	        }else
		        fld.style.background = ORIGINALBACKGROUNDCOLOR;
	    } else if (!(stripped.length == 10)) {
	        reason += "The Phone number is the wrong length. Make sure you included an area code.\n";
	        fld.style.background = ERRORBACKGROUNDCOLOR;
	    } else if (!phoneFilter.test(stripped)) {
	        reason += "The Phone number contains illegal characters.\n";
	        fld.style.background = ERRORBACKGROUNDCOLOR;
	    } else {
	        fld.style.background = ORIGINALBACKGROUNDCOLOR;
			//standardise input
	    	fld.value = "(" + stripped.substr( 0, 3) + ") " + stripped.substr( 3, 3) + " " + stripped.substr( 6);
	    }
	
	}
	
	function validateState( fld){
	
	    fld.value = fld.value.toUpperCase();
		var stateFilter = /^[A-Z]{2}$/;
		
		if (fld.value == "") {
			if(fld.hasClassName('required')){
				reason += "The State field has not been filled in.\n";
	        	fld.style.background = ERRORBACKGROUNDCOLOR;
	        }else
		        fld.style.background = 'White';
		}else if(!stateFilter.test( fld.value)){
			reason += "The State field is invalid.\n"
			fld.style.background = ERRORBACKGROUNDCOLOR;
	    } else
	        fld.style.background = ORIGINALBACKGROUNDCOLOR;
		
	}
	
	// handles american and canadian
	function validateZip( fld){
	
	    var stripped = fld.value.replace(/[\(\)\.\-\ ]/g, '');    
		var zipFilterUS = /^\d{5}(\d{4})?$/;
		var zipFilterCanada = /^[ABCEGHJKLMNPRSTVXY]\d[A-Z] *\d[A-Z]\d$/
		
	   if (fld.value == "") {
			if(fld.hasClassName('required')){
				reason += "The Zip Code field has not been filled in.\n";
	        	fld.style.background = ERRORBACKGROUNDCOLOR;
	        }else
		        fld.style.background = ORIGINALBACKGROUNDCOLOR;
		}else if(stripped == ""){
	        reason += "The Zip field has not been filled in.\n";
	        fld.style.background = ERRORBACKGROUNDCOLOR;
		}else if(!zipFilterUS.test( stripped) && !zipFilterCanada.test( stripped)){
			reason += "The Zip field is invalid.\n"
			fld.style.background = ERRORBACKGROUNDCOLOR;
	    } else {
	        fld.style.background = ORIGINALBACKGROUNDCOLOR;
			//standardise input
			if(stripped.length == 9){ fld.value = stripped.substr( 0, 5) + "-" + stripped.substr( 5) }
			else if(stripped.length == 6){ fld.value = stripped.substr( 0, 3) + " " + stripped.substr( 3) }
		}
		
	}
	
}

// validate all forms with the 'validate' class
Event.observe( window, 'load', function(){
	
	//set original background color to the first text input seen, default white
	//constraint: doesn't work if multiple validated forms on page have different background colors for inputs
	var possibleInput = $$( 'form input[type=text]', 'form textarea', 'form select')
	if(possibleInput)
		ORIGINALBACKGROUNDCOLOR = possibleInput[0].style.background

	$$( 'form.validate').each( function( theForm){ theForm.observe( 'submit', validateForm)})

})

