/*	
	Validations.js v 2.7 - Custom Validation Script	
	Author:  Nitin Menon
	Email: 	 nitin@bigbuzz.com
	Date:	 11/5/2006 10:40 AM 	
	
	Validates Following:
	 - Empty Input Fields
	 - Check boxes [checkbox]
	 - Radio buttons [radio]
	 - Email Format [email]
	 - Date Format [date]
	 - Zipcode Format (US/CA) [zipcode]
	 - Phone Number Format [phone]
	 - Social Security [social]
	 - IP Address [ip]
	 - URL Format [url]
	 - String Format [string]
	 - Number Format [number]
	 - Money Format [money]
	 - Compares two strings [compare]
	 - Alpha Characters [alpha]
	 - Alphanumeric Characters [alphanumeric]
	 - XSS Malicious Code [xsscode]
	 - Username Taken Verification (SPRY must be installed) [un_availablity]
	 - Age Verification [checkage]
	 - Regular Expression [regexp]
*/

// Version number
var ScriptVersion = 2.7;

// 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){
	// Script Version detection
	if(!params.id && !params.name &&  ScriptVersion >= 2){
		alert('ERROR: You maybe using a calling function for an older version of the Validations script. The current version you have installed is v '+ ScriptVersion + '. The proper calling function syntax for this version is: \
			   \n \n if(!validate({id:"[fieldid]"})) return false; \n \n To view the complete list of parameters that can be passed into the validate function refer to the developer comment in the validation.js file.');
		return false;
	}
	
	// Default Params
	if(!params.type) params.type = "";
	if(!params.required) params.required = "yes";
	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 field is a radio or checkbox get the name of the field not the id
	if(params.type.toLowerCase() == "radio" || params.type.toLowerCase() == "checkbox"){
		if(!params.name){ // Must pass in field name
			alert("ERROR: You must specify a Field name in your calling function. Please check your code."); 
			return false;
		}		
		var fieldname = document.getElementsByName(params.name);
		if(!fieldname){
			alert("ERROR: An input field with the Name= " + params.name + " does not exist. Please make sure that all input fields are labeled with the correct name. Please check your code."); 
			return false;
		}
		var FieldId = fieldname[0];
	}else{
		if(!params.id && !params.name){ // Must pass in field id
			alert("ERROR: You must specify a Field ID in your calling function. Please check your code."); 
			return false;
		}
		
		if(params.id){
			 var FieldId = _$(params.id);
		}else if(params.name){
			 var FieldId = document.getElementsByName(params.name)[0];
		}

		
		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,
				name      : params.name,
				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 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
			case "url":
				if(!(/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.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."); 
					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;
			
			// Validate any regExp
			case "regexp":
				if(!params.regexp){ 
					alert("Please pass in a regular expression to validate. Check your code."); 
					return false; 
				}
				var re = new RegExp(params.regexp);
				if(!(re.test(FieldId.value))){
					if(!params.alerts){
						if(!params.errortext){
							newSpan.innerHTML = "Invalid Format";
						}else{
							newSpan.innerHTML = params.errortext;
						}
					}else{
						if(!params.errortext){
							alert("Invalid Format.");	
						}else{
							alert(params.errortext);
						}
					}
					FieldId.focus();
					return false;
				}else{
					if(!params.alerts){
						newSpan.innerHTML = "";
					}
					return true;
				};
			break;
			
			default: // Default Passed all validations
				if(!params.alerts){
					newSpan.innerHTML = "";
				}
				return true;
			break;
		};
	}else{
		if(!params.alerts){
			newSpan.innerHTML = "";
		}
		return true;
	};
};
