/*
  -------------------------------------------------------------------------
	                    Javascript Form Validator 
                                Version 1.0
	Based off the "JavaScript Form Validator Version 2.0.2" which can be 
	found at JavaScript-coder.com.
	
	Recreation by Phoenix Development February 27, 2008.
	
	Works in collaboration with PHP class "class.validator.php".
    -------------------------------------------------------------------------  
*/

function Validator(fName) {
	this.fObj = document.forms[fName];

	if(!this.fObj) {
	  	alert("Error: could not get form object " + fName);
		return false;
	}

	if(this.fObj.onsubmit) {
		this.fObj.old_onsubmit = this.fObj.onsubmit;
		this.fObj.onsubmit = null;
	} else {
		this.fObj.old_onsubmit = null;
	}
	this.vElements = new Array();
	this.fObj.onsubmit = form_submit_handler;
	this.addValidation = add_validation;
	this.clearAllValidations = clear_all_validations;
}

function clear_all_validations() {
	for(var i = 0; i < this.fObj.elements.length; i++) {
		this.fObj.elements[i].validationset = null;
	}
}

function form_submit_handler() {
	for(var i = 0; i < this.elements.length; i++) {
		if(this.elements[i].val && !this.elements[i].val.validate(this)) {
			return false;
		}
	}
	return true;
}

function add_validation(elementName, desc, err)
{
	if(!this.fObj) {
		alert("Error: the form object is not set properly");
		return;
	}

	var elementObj = this.fObj[elementName];
	if(!elementObj) {
		elementArray = elementName.split("|");
		if(elementArray.length > 1) {
			if(!this.fObj[elementArray[0]] || !this.fObj[elementArray[1]]) {
				alert("Error: Could not get the input objects");
				return;
			} else {
				if(!this.fObj[elementArray[0]].val) {
					this.fObj[elementArray[0]].val = new Val();
					this.fObj[elementArray[0]].val.add(elementName, desc, err);
				} else {
					this.fObj[elementArray[0]].val.add(elementName, desc, err);
				}
			}
		} else {
			alert("Error: Could not get the input object named: " + elementName);
			return;
		}
	} else {
		if(!elementObj.val) {
			elementObj.val = new Val();
			elementObj.val.add(elementName, desc, err);
		} else {
			elementObj.val.add(elementName, desc, err);
		}
	}
}

function Val(elementName, desc, err) {
	this.vSet = new Array();
	this.add = addVal;
	this.validate = validate;
}

function addVal(elementName, desc, error) {
	this.vSet[this.vSet.length] = new Array(elementName, desc, error);
}

function validate(fObj) {
	for(i = 0; i < this.vSet.length; i++)
	{
		if(!checkValidation(this.vSet[i][0], this.vSet[i][1], this.vSet[i][2], fObj)) {
			elementArray = this.vSet[i][0].split("|");
			fObj[elementArray[0]].focus();
			return false;
		}
	}
	return true;
}

function checkValidation(elementName, descriptor, err, fObj) {
	var tmpArray = descriptor.split("=");
	command = tmpArray[0]; 
	cmdvalue = (tmpArray.length > 1) ? tmpArray[1] : '';
	
	var patterns = new Array();
	patterns['alnum'] = /[^A-Za-z0-9\ ]/;
	patterns['alnumhyphen'] = /[^A-Za-z0-9\-_]/;
	patterns['alpha'] = /[^A-Za-z]/;
	patterns['custom'] = /[^A-Za-z0-9\042\047\055\057\ _$.,!?()]/;
	patterns['date'] = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/;
	patterns['email'] = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
	patterns['float'] = /[^0-9\.]/;
	patterns['img'] = /^[0-9A-Za-z_ \-]+(.[jJ][pP][gG]|.[jJ][pP][eE][gG]|.[gG][iI][fF]|.[pP][nN][gG])$/;
	patterns['num'] = /[^0-9]/;
	patterns['phone'] = /[^0-9\- ()]/;
	patterns['URL'] = /(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?/;
	patterns['zip'] = /[^-0-9]/;
	
	switch(command) 
	{
		case "alnum": 
		case "alphanumeric": 
			var charpos = fObj[elementName].value.search(patterns['alnum']);
			if(fObj[elementName].value.length > 0 &&  charpos >= 0) {
				if(!err || err.length == 0) err = elementName + " must be alpha-numeric";
				alert(err + "\n [Error character position " + eval(charpos + 1) + "]");
				return false;
			}
			break; 

		case "alnumhyphen":
			var charpos = fObj[elementName].value.search(patterns['alnumhyphen']); 
			if(fObj[elementName].value.length > 0 &&  charpos >= 0) { 
				if(!err || err.length == 0) err = elementName + " may only contain alpha-numeric, hyphen and underscore characters";
				alert(err + "\n [Error character position " + eval(charpos + 1) + "]"); 
				return false;
			}
			break;

		case "alphabetic": 
		case "alpha": 
			var charpos = fObj[elementName].value.search(patterns['alpha']); 
			if(fObj[elementName].value.length > 0 &&  charpos >= 0) {
				if(!err || err.length == 0) err = elementName + " may only contain letters (no symbols or numbers)";
				alert(err + "\n [Error character position " + eval(charpos + 1) + "]");
				return false;
			}
			break;

		case "custom":
			var charpos = fObj[elementName].value.search(patterns['custom']);
			if(fObj[elementName].value.length > 0 &&  charpos >= 0) { 
				if(!err || err.length == 0) err = elementName + " may only contain alpha-numeric, {'}, {,}, {.}, {&}, {/}, {-}, {\"}, {?}, {(}, {)}, {_} and {!} characters";
				alert(err + "\n [Error character position " + eval(charpos + 1) + "]"); 
				return false; 
			} 
			break;

		case "date":
			if(fObj[elementName].value.length > 0) {
				var charpos = fObj[elementName].value.match(patterns['date']);
				if(charpos == null) {
					if(!err || err.length == 0) err = elementName + " must contain a valid date (yyyy-mm-dd)";
					alert(err);
					return false; 
				}
			}
			break;

		case "email": 
			if(fObj[elementName].value.length > 0) {
				var charpos = fObj[elementName].value.match(patterns['email']);
				if(charpos == null) {
					if(!err || err.length == 0) err = elementName + " must contain a valid email address"; 
					alert(err); 
					return false;
				}
			}
			break; 

		case "extension":
		case "ext":
			var accept = cmdvalue.split("|");
			var ext = fObj[elementName].value.split(".")[fObj[elementName].value.split(".").length-1].toLowerCase();
			if(accept.indexOf(ext) == -1) {
				if(!err || err.length == 0) err = elementName + " may only contain the following file types: " + accept;
				alert(err + "\n[Current file type: \"" + ext + "\" ]");
				return false;
			}
			break; 

		case "float": 
			var charpos = fObj[elementName].value.search(patterns['float']); 
			if(fObj[elementName].value.length > 0 &&  charpos >= 0) { 
				if(!err || err.length == 0) err = elementName + " may only contain numbers and a period"; 
				alert(err + "\n [Error character position " + eval(charpos + 1) + "]"); 
				return false; 
			}
		break;               

		case "gt":
		case "greaterthan":
			if(isNaN(fObj[elementName].value)) { 
				alert(elementName + " must be numeric"); 
				return false; 
			}
			if(eval(fObj[elementName].value) <= eval(cmdvalue)) {
				if(!err || err.length == 0) err = elementName + " must contain a number greater than " + cmdvalue;
				alert(err);
				return false;
			}
			break;

		case "image":
		case "img":
			var imgfile = fObj[elementName].value.split("\\")[fObj[elementName].value.split("\\").length-1];
			var charpos = imgfile.match(patterns['img']);
			if(fObj[elementName].value.length > 0 &&  charpos >= 0) { 
				if(!err || err.length == 0) err = elementName + " may only hold an image with extensions jpg, jpeg, gif or png.";
				alert(err + "\n [Error character position " + eval(charpos + 1) + "]"); 
				return false;
			}
			break;

		case "lt":
		case "lessthan":
			if(isNaN(fObj[elementName].value)) {
				alert(elementName + " must be numeric");
				return false;
			}
			if(eval(fObj[elementName].value) >= eval(cmdvalue)) {
				if(!err || err.length == 0) err = elementName + " must contain a number less than "+ cmdvalue;
				alert(err);
				return false;
			}
			break;

		case "match":
			var tmpElements = elementName.split("|");
			if(fObj[tmpElements[0]].value != fObj[tmpElements[1]].value) {
				if(!err || err.length == 0) err = tmpElements[0] + " and " + tmpElements[1] + " must match";
				alert(err);
				return false;
			}
			break;

		case "maxlength": 
		case "maxlen":
			if(eval(fObj[elementName].value.length) > eval(cmdvalue)) {
				if(!err || err.length == 0) err = elementName + " may not be longer than " + cmdvalue + " characters";
				alert(err + "\n[Current length = " + fObj[elementName].value.length + " ]");
				return false;
			}
			break;              

		case "minlength": 
		case "minlen": 
			if(eval(fObj[elementName].value.length) < eval(cmdvalue)) {
				if(!err || err.length == 0) err = elementName + " may not be shorter than " + cmdvalue + " characters";
				alert(err + "\n[Current length = " + fObj[elementName].value.length + " ]");
				return false;                 
			} 
			break; 

		case "num": 
		case "numeric": 
			var charpos = fObj[elementName].value.search(patterns['num']); 
			if(fObj[elementName].value.length > 0 && charpos >= 0) { 
				if(!err || err.length == 0) err = elementName + " must be a number"; 
				alert(err + "\n [Error character position " + eval(charpos + 1) + "]"); 
				return false; 
			} 
			break;

		case "phone":
			var charpos = fObj[elementName].value.search(patterns['phone']); 
			if(fObj[elementName].value.length > 0 &&  charpos >= 0) { 
				if(!err || err.length == 0) err = elementName + " must contain a valid phone number";
				alert(err + "\n [Error character position " + eval(charpos + 1) + "]"); 
				return false;
			} 			
			break;

		case "regexp": 
			if(fObj[elementName].value.length > 0) {
				if(!fObj[elementName].value.match(cmdvalue)) { 
					if(!err || err.length == 0) err = elementName + " contains invalid characters";                                                
					alert(err); 
					return false;                   
				} 
			}
			break;

		case "req": 
		case "required":
			if(eval(fObj[elementName].value.length) == 0 || fObj[elementName].type == "checkbox" && fObj[elementName].checked == false) {
				if(!err || err.length == 0) err = elementName + " is a required field";
				alert(err); 
				return false;
			}
			break;

		case "req2":
			if(eval(fObj[elementName].value.length) == 0 || fObj[elementName].type == "checkbox" && fObj[elementName].checked == false || fObj[elementName].value == fObj[elementName].title) {
				if(!err || err.length == 0) err = elementName + " is a required field";
				alert(err); 
				return false;
			}
			break;

		case "URL":
			if(fObj[elementName].value.length > 0) {
				var charpos = fObj[elementName].value.match(patterns['URL']);
				if(charpos == null) {
					if(!err || err.length == 0) err = elementName + " must contain a valid URL";
					alert(err);
					return false;
				}
			}
			break;

		case "zip":
			var charpos = fObj[elementName].value.search(patterns['zip']);
			if(fObj[elementName].value.length > 0 &&  charpos >= 0) {
				if(!err || err.length == 0) err = elementName + " must contain a valid zip code";
				alert(err + "\n [Error character position " + eval(charpos + 1) + "]");
				return false; 
			} 
			break;               

		default:break;
	}
	return true;
}
