/*
form validation
written by Caleb Pierce
summer '08
copyright Roanoke College

These classes make a field required as well as
validate the value:
- notBlank
- decimal (allows for whole or decimal numbers)
- email
- url
- validDate
- creditcard

These class check a field if it has value but
does not make the field required:
- decimal_o (allows for whole or decimal numbers)
- email_o
- url_o
- validDate_o
- creditcard_o
*/

$(document).ready(function() { //javascript here will load after the document is ready
	
	//automatically adds asterisks to the labels of required input fields
	//note: this requires that the form is layed out according to the design standards
	$(".check .notBlank,.check .url,.check .decimal,.check .email,.check .validDate,.check .creditcard").parent("td").prev(":nth-child(1)").find("label").before("<span>*</span> ");
	
	$(".check").submit(function(){
		var thisForm = $(this);
		var errors = 0;

		//checks for a valid email address
		$(".email",this).each(function(){
			var e = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
			if (!e.test($(this).val())){
				errors++;
				$(this).css("background-color", "#FFA1A1");
			}
		});
		//checks for a valid email address - optional
		$(".email_o",this).each(function(){
			if ($(this).val() != ''){
				var e = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
				if (!e.test($(this).val())){
					errors++;
					$(this).css("background-color", "#FFA1A1");
				}
			}
		});

		//checks for a blank field
		//also works for radio buttons and checkboxes - w00t
		$(".notBlank",this).each(function(){
			var thisInput = $(this);
			if ($(this).is(":radio")){
				var name = $(this).attr("name");
				if ($(thisForm).find(":radio[name='"+ name + "']").add(thisInput).filter(":checked").length == 0){
					errors++;
				}
			}
			else if ($(this).is(":checkbox")){
				var name = $(this).attr("name");
				if ($(thisForm).find(":checkbox[name='"+ name + "']").add(thisInput).filter(":checked").length == 0){
					errors++;
				}
			}
			else { //note: for a select field, the value attribute is what's checked. it only works if this has
				 	//an unselected value of '' or ' '. Not "choose one", etc.
				if($(this).val() == '' || $(this).val() == ' ') {
					errors++;
					$(this).css("background-color", "#FFA1A1");
				}
			}
		});

		//tests for a valid url
		$(".url",this).each(function(){
			var e = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/;
			if (!e.test($(this).val())){
				errors++;
				$(this).css("background-color", "#FFA1A1");
			}
		});
		//tests for a valid url
		$(".url_o",this).each(function(){
			if ($(this).val() != ''){
				var e = /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/;
				if (!e.test($(this).val())){
					errors++;
					$(this).css("background-color", "#FFA1A1");
				}
			}	
		});

		//checks for a valid date
		$(".validDate",this).each(function(){
			if (/Invalid|NaN/.test(new Date($(this).val()))){
				errors++;
				$(this).css("background-color", "#FFA1A1");
			}
		});
		//checks for a valid date
		$(".validDate_o",this).each(function(){
			if ($(this).val() != ''){
				if (/Invalid|NaN/.test(new Date($(this).val()))){
					errors++;
					$(this).css("background-color", "#FFA1A1");
				}
			}
		});

		//checks for a valid decimal number
		$(".decimal",this).each(function(){
			var e = /(\d+|\.\d|\d+\.\d+)/;
			if (!e.test($(this).val())){
				errors++;
				$(this).css("background-color", "#FFA1A1");
			}
		});
		//checks for a valid decimal number
		$(".decimal_o",this).each(function(){
			if ($(this).val() != ''){
				var e = /(\d+|\.\d|\d+\.\d+)/;
				if (!e.test($(this).val())){
					errors++;
					$(this).css("background-color", "#FFA1A1");
				}
			}
		});
		
		//checks for a valid credit card number
		$(".creditcard",this).each(function(){
			var e = /[0-9]{4}[\-\s]?[0-9]{4}[\-\s]?[0-9]{4}[\-\s]?[0-9]{3,4}/;
			var content = $(this).val();
			
		    var strReplaceAll = content;
			var intIndexOfMatch = strReplaceAll.indexOf(" ");

			while (intIndexOfMatch != -1) {
				strReplaceAll = strReplaceAll.replace(" ", "");
				intIndexOfMatch = strReplaceAll.indexOf(" ");
			}
			
			var intIndexOfMatch = strReplaceAll.indexOf("-");

			while (intIndexOfMatch != -1) {
				strReplaceAll = strReplaceAll.replace("-", "");
				intIndexOfMatch = strReplaceAll.indexOf("-");
			}

			if (!e.test(content)){
				errors++;
				$(this).css("background-color", "#FFA1A1");
			}
		});
		//checks for a valid credit card number
		$(".creditcard_o",this).each(function(){
			if ($(this).val() != ''){
				var e = /[0-9]{4}[\-\s]?[0-9]{4}[\-\s]?[0-9]{4}[\-\s]?[0-9]{3,4}/;
				var content = $(this).val();

			    var strReplaceAll = content;
				var intIndexOfMatch = strReplaceAll.indexOf(" ");

				while (intIndexOfMatch != -1) {
					strReplaceAll = strReplaceAll.replace(" ", "");
					intIndexOfMatch = strReplaceAll.indexOf(" ");
				}

				var intIndexOfMatch = strReplaceAll.indexOf("-");

				while (intIndexOfMatch != -1) {
					strReplaceAll = strReplaceAll.replace("-", "");
					intIndexOfMatch = strReplaceAll.indexOf("-");
				}

				if (!e.test(content)){
					errors++;
					$(this).css("background-color", "#FFA1A1");
				}
			}
		});
		
		//handle select boxes
		if (errors != 0)
			alert("Please check the form for errors.\n(Fields with a red star are required.)");
			
		//return the results
		return errors == 0;
	}); //validate
	
	//clear the error divs on field focus
	$(".email,.email_o,.notBlank,.url,.url_o,.validDate,.validDate_o,.decimal,.decimal_o,.creditcard,.creditcard_o",this).focus(function(){
		if (!($(this).is(":radio") || $(this).is(":checkbox")))
			$(this).css("background-color", "#fff");
	});

});