/*	
	Validations.js v 2.0 - Custom Validation Script	
	Author:  Nitin Menon
	Email: 	 nitin@bigbuzz.com
	Date:	 9/22/2006 5:42 PM	
	
	Validates Following:
	 - Empty Input Fields
	 - Check boxes 
	 - Radio buttons
	 - Email Format
	 - Date Format
	 - Zipcode Format (US/CA)
	 - Phone Number Format
	 - Social Security
	 - IP Address
	 - URL Format
	 - String Format
	 - Number Format
	 - Money Format
	 - Compares two strings
	 - Alpha Characters
	 - Alphanumeric Characters
	 - XSS Malicious Code
	 - Username Taken Verification (SPRY must be installed)
	 - Age Verification
*/

// CSS Style for the required text
var RequiredTextStyle = "color:red;padding-left:5px;font-family:arial;vertical-align:top;font-size:12px;";

function _$() {
	var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string') element = document.getElementById(element);
		if (arguments.length == 1) return element;
		elements.push(element);
	}
	return elements;
}

function trim(strValue){
	var objRegExp = /^(\s*)$/;
	if(objRegExp.test(strValue)){
	   strValue = strValue.replace(objRegExp, '');
	   if(strValue.length == 0) return strValue;
	};
	objRegExp = /^(\s*)([\W\w]*)(\b\s*$)/;
	if(objRegExp.test(strValue)) strValue = strValue.replace(objRegExp, '$2');
	return strValue;
};

/*
	This function can be used filter inputs before submitting the form,
	However this function is not used within the Validate() this can be 
	used with 'on' events 
*/
function filter(id,type){
	switch(type){
		case "string":
			var field = _$(id);
			var newVal = field.value.replace(/\d/g,"");
			field.value = newVal;
		break;
		case "number":
			var field = _$(id);
			var newVal = field.value.replace(/[a-zA-Z!@#$%^&*\s?'._~`:;<=>{}()|+-]/g,"");
			field.value = newVal;
		break;
		case "money":
			var field = _$(id);
			var newVal = field.value.replace(/[a-zA-Z!@#$%^&*\s?'_~`:;<=>{}()|+-]/g,"");
			field.value = newVal;
		break;
		case "special":
			var field = _$(id);
			var newVal = field.value.replace(/[!@#$%^&*\s?'._~`:;<=>{}()|+]/g,"");
			field.value = newVal;
		break;
	};	
};

/*
	This function is used to clear all required span tags 
*/
function eraseAllReqSpanTags(){
	var span = document.getElementsByTagName("span"); 
	var re_elmName = new RegExp("_req");
	for (var i = 0; i < span.length; i++) { 
		spID = span[i].getAttribute("id"); 
		if (re_elmName.test(spID)) span[i].innerHTML="";
	};	
};

function validate(params){
	// Default Params
	if(!params.type) params.type = "";
	if(!params.required) params.required = "no";
	if(!params.alerts) params.alerts = null;
	if(!params.minlength) params.minlength = null;

	/* 
		Firefox throws an exception error when focus() is called;
		To avoid this error, you have to turn off autocomplete
	*/
	var inputElements = document.getElementsByTagName("input");
	for (i=0; inputElements[i]; i++){
		inputElements[i].setAttribute("autocomplete","off");
	}
	if(!params.id){ // Must pass in field id
		alert("ERROR: You must specify a Field ID in your calling function. Please check your code."); 
		return false;
	}
	
	var FieldId = _$(params.id);
	
	if(!FieldId){
		alert("ERROR: An input field with the ID= " + params.id + " does not exist. Please make sure that all input fields are labeled with the correct ID and that it matches the field Name. Please check your code."); 
		return false;
	}
	
	if(params.type != "xsscode"){ //Malicious Code Check
		if(!validate(
			{ 
				id        : params.id,
				type 	  : "xsscode",
				required  : params.required,
				minlength : params.minlength,
				alerts    : params.alerts,
				id2       : params.id2,
				urlpath   : params.urlpath,
				minage    : params.minage 
			 }
			)){ 
			return false;
		}
	}
	
	if(!params.alerts){ // If alerts is not defined, it will use alert message instead of spans
		var newSpan = _$(params.id + "_req");
		if( newSpan == null ){ 
			newSpan = document.createElement("span"); 
			newSpan.setAttribute('id',params.id + '_req'); 
			newSpan.style.cssText = RequiredTextStyle;  // IE
			newSpan.setAttribute('style',RequiredTextStyle); // FireFox 
		};
		var parent = FieldId.parentNode; 
		parent.insertBefore(newSpan,FieldId.nextSibling); 
		eraseAllReqSpanTags();
	}else{
		var required_message = params.alerts;	
	}
	
	if(!trim(FieldId.value).length && params.required != "no"){
		if(!params.alerts){
			newSpan.innerHTML = "Required";	
		}else{
			alert(required_message);
		}
		
		if(params.type.toLowerCase() != "hidden"){ // Hidden Fields Do Not Allow Focus In Internet Explorer
			FieldId.focus();
		}
		return false;
	}else if(trim(FieldId.value).length){ 
		if(params.minlength && trim(FieldId.value).length < params.minlength){
			if(!params.alerts){
				newSpan.innerHTML = "Must Have Atleast " + params.minlength + " Characters";
			}else{
				alert(params.id + " Must Have Atleast " + params.minlength + " Characters");	
			}
			FieldId.focus();
			return false;
		};
		switch(params.type.toLowerCase()){
			
			// Validate Check boxes and Radio buttons	
			case "checkbox": case "radio":
				var fieldname = document.getElementsByName(params.id);
				var checked = -1;
				for (i=0; i < fieldname.length; i++){
					if(fieldname[i].checked) checked = i;
				};
				if(checked == -1){
					if(!params.alerts){
						newSpan.innerHTML = "Required";
					}else{
						alert(required_message);	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
				  	return true;
				};
			break;
			
			// Validate Email Addresses ( e.g: username@domain.com )
			case "email":
				if(!(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Enter Valid E-mail";
					}else{
						alert("Please Enter a Valid E-mail.");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
				  	return true;
				};
			break;
			
			// Validate Date ( e.g: mm/dd/yyyy )
			case "date":
				if(!(/^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Enter Date Format: [ mm/dd/yyyy ]";
					}else{
						alert("Please Enter Date Format: [ mm/dd/yyyy ].");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
				  	return true;
				};
			break;
			
			// Validate US & Canadian Zipcodes
			case "zipcode":
				var USZip = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
				var CAZip = /^((\d{5}-\d{4})|(\d{5})|([AaBbCcEeGgHhJjKkLlMmNnPpRrSsTtVvXxYy]\d[A-Za-z]\s?\d[A-Za-z]\d))$/;

				if(!(USZip.test(FieldId.value)) && !(CAZip.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Enter Valid Zipcode";
					}else{
						alert("Please Enter a Valid Zipcode.");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Validate Phone Number
			case "phone":
				if(!(/(\d{3})\D*(\d{3})\D*(\d{4})\D*(\d*)$/.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Enter Valid Phone Number";
					}else{
						alert("Please Enter a Valid Phone Number With Area Code.");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Validate Social Security
			case "social":
				var USSS = /^\d{3}\-?\d{2}\-?\d{4}$/;
				var CASS = /^\d{9}$/;
				
				if(!(USSS.test(FieldId.value)) && !(CASS.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Enter Valid Social Security";
					}else{
						alert("Please Enter a Valid Social Security.");	
					}	
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Validate IP Address
			case "ip":
				if(!(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Enter Valid IP Address";
					}else{
						alert("Please Enter a Valid IP Address.");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Validate URL (Could be better...)
			case "url":
				var strURL1 = "^(https?://)?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?";
				var strURL2 = "(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-z_!~*'()-]+\.)*([0-9a-z][0-9a-z-]";
				var strURL3 = "{0,61})?[0-9a-z]\.[a-z]{2,6})(:[0-9]{1,4})?((/?)|(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";
				var re = new RegExp(strURL1+strURL2+strURL3);
				if(!(re.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Enter Valid URL";
					}else{
						alert("Please Enter a Valid URL.");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Validate String Format
			case "string":
				if((/[\d]/.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Invalid! Only Letters Allowed";
					}else{
						alert("Invalid! Only Letters Allowed.");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Validate Number Format
			case "number":
				if((/\D/.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Invalid! Only Numbers Allowed";
					}else{
						alert("Invalid! Only Numbers Allowed.");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}return true;
				};
			break;
			
			// Validate Money Format
			case "money":
				if((/[$]/.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Please Remove The $";
					}else{
						alert("Please Remove The $.");	
					}
					FieldId.focus();
					return false;
				}else if((/[a-zA-Z!@#%^&*\s?'_~`:;<=>{}()|+-]/.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Invalid! Only Numbers Allowed";
					}else{
						alert("Invalid! Only Numbers Allowed..");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Compare two string
			case "compare":
				if(!params.id2){ alert("ERROR: You must specify a second Field ID in your calling function if your type is 'compare'."); return false;}
				var FieldId_2 = _$(params.id2);
				if(FieldId.value != FieldId_2.value){
					if(!params.alerts){
						newSpan.innerHTML = "Confirmation Mismatch";
					}else{
						alert("Confirmation Entry Does Not Match.");	
					}
					FieldId.focus();
					return false;		
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Validate Alpha Characters ONLY
			case "alpha":
				if(!(/^[a-zA-Z]+$/.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Invalid! Only Alpha Characters Allowed";
					}else{
						alert("Invalid! Only Alpha Characters Allowed.");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Validate Alphanumeric character ONLY
			case "alphanumeric":
				if(!(/^[a-zA-Z0-9]+$/.test(FieldId.value))){
					if(!params.alerts){
						newSpan.innerHTML = "Invalid! Only Alpha Numeric Characters Allowed";
					}else{
						alert("Invalid! Only Alpha Numeric Characters Allowed.");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Validate XSS Malicious Code
			case "xsscode":
				var strRegex = "(-- )|(' )|(script)|(<)|(>)|(%3c)|(%3e)|(select)|(update)|(insert)|(delete)|(drop)|(grant)|(revoke)|(union)|(&lt;)|(&gt;)";
				var re = new RegExp(strRegex);
				var str = FieldId.value.toLowerCase();
				if(str.match(re)){
					if(!params.alerts){
						newSpan.innerHTML = "XSS (malicious) code detected!";
					}else{
						alert("XSS (malicious) code detected!");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Check if user name is available (SPRY FRAMEWORK REQUIRED) 
			case "un_availablity":
				if(!params.urlpath){ 
					alert("Please pass in a url path to the file that Spry will read. Url Path should be the 7th parameter passed into this function."); 
					return false; 
				}
				try{
					// This Validation can only be done if the Spry Files are being referenced
					request = Spry.Utils.loadURL("GET", params.urlpath + encodeURIComponent(FieldId.value), false);
					var result = request.xhRequest.responseText;
 				}catch(err){
				   alert("There was an error using Spry. Please make sure that the Spry files are set up correctly.");
				   return false;
				}				
				
   				if(result==0){
					if(!params.alerts){
						newSpan.innerHTML = "Username Taken";
					}else{
						alert("Username Taken.");	
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			// Age Verification
			case "checkage":
				if(!params.minage) params.minage = 13; // Default Age

				var Today = new Date();
				Today.setHours(0,0,0,0); 
				// Must pass in date in mm/dd/yyyy format
				if(!validate({id:params.id,type:"date",required:"yes"})) return false;
				// Format field to be exactly in mm/dd/yyyy format
				FieldId.value = FieldId.value.replace(/^(\d{1}\/)/,"0$1").replace(/(\d{2}\/)(\d{1}\/)/,"$10$2");
				// Get Date using '/' as a delimiter  
				var splitDate = FieldId.value.split("/");
				// Creates Date from the value passed in an parsed [mm/dd/yyyy]
				var bDay = new Date(splitDate[2]+"/"+splitDate[0]+"/"+splitDate[1]);
				var age = Today.getFullYear() - bDay.getFullYear();
				var currYrbDay = new Date(Today.getFullYear(), bDay.getMonth(), bDay.getDate());
				if (currYrbDay > Today && age > 0) age--;
				
				if(age <  params.minage){
					alert("Sorry. You Are Not Old Enough To Continue.");	
					return false;
				}else{
					return true;
				};
			break;
			
			default: // Default Passed all validations
				if(!params.alerts){
					newSpan.innerHTML = "";
				}
				return true;
			break;
		};
	}else{
		if(!params.alerts){
			newSpan.innerHTML = "";
		}
		return true;
	};
};