var FV = function formValidate(valForm, focus) {
	if( focus == undefined ) { focus = true; }
	for( var item in this.extendForm ) {
		valForm[item] = this.extendForm[item];
	}
	if( focus ) { valForm.startFocus(); }
	return valForm;
}

FV.prototype = {
	extendForm : {
		onsubmit : function() {
			this.errors = false;
			this.focusElem = null;
			for( var i = 0, len = this.elements.length; i < len; i++ ) {
				var elem = this.elements[i];
				if( elem.nodeType == 1 ) {
					var errorChecks = ["required", "email", "date", "areYouHuman"];
					for( var j = 0, errLen = errorChecks.length; j < errLen; j++ ) {
						var error = errorChecks[j];
						var testClass = new RegExp("(^|\\s)" + error + "(\\s|$)");
						if(testClass.test(elem.className)) {	
							if( !this.validate(elem, error) ) {
								this.errors = true; this.setError(elem, true);
								if( !this.focusElem ) { this.focusElem = elem; }
							} else { this.setError(elem, false); }
						}
					}
					if( elem.id == "urn" ) {
						if( elem.value.length < 9 ) { 
							this.errors = true;
							this.setError(elem, true);
							if( !this.focusElem ) { this.focusElem = elem; }
						}
					}
				}
			}
			if( this.focusElem ) { this.focusElem.focus(); }
			return !this.errors;
		},
		setError : function(elem, error) {
			if(error == true) { elem.parentNode.className = elem.parentNode.className.replace("error", "") + " error"; }
				else { elem.parentNode.className = elem.parentNode.className.replace("error", ""); }
		},
		validate : function(elem, type) {
			/*
			 * A switch case is used so I can reference the form directly with the "this".
			 * If the functions are in an object as below the "this" references the flipping object the functions are in.
			 * The age validation is the one that benefits at the moment
			 * e.g. validate : { email : function(){} } 
			 *
			 */
			switch(type) {
				case "required":
					if(elem.value == "" || (elem.type == "checkbox" && elem.checked == false ) ) {
						return false;
					} else {
						return true;
					}
					break;
				
				case "email":
					if( !elem.value.match(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i) ) {
						return false;
					} else {
						return true;
					}
					break;
				
				case "date":
					var age = parseInt(elem.className.replace("date", "").replace("age-", "")); // TODO: Fix this.
					var collectionName = elem.name.replace(/\[[a-zA-Z]\]/, "");
					
					var day = this[collectionName+"[d]"];
					var month = this[collectionName+"[m]"];
					var year = this[collectionName+"[y]"];
					
					var dob = new Date((parseInt(year.value) + age), parseInt(month.value)-1, parseInt(day.value));
					var today = new Date();
					
					if( (today.getTime() - dob.getTime()) < 0 ) {
						return false;
					} else {
						return true;
					}
					break;
				case "areYouHuman":
					var captchaValue = document.getElementById("areYouHumanValue");
					captchaValue = captchaValue.childNodes[0].nodeValue;
					if( elem.value == captchaValue ) {
						return true;
					} else {
						return false;
					}
					break;
				default: 
					return false;
			}
		},
		errors : false,
		focusElem : null,
		startFocus : function() {
			for( var i = 0, len = this.elements.length; i < len; i++ ) {
				var elem = this.elements[i];
				if( elem.nodeType == 1 && elem.value == "" ) {
					elem.focus();
					return elem;
				}
			}
		}
	}
}
