function FormValidator(formID){
	// Validation object for Form Validator
	// You can customize this when you instantiate FormValidator Class
	this.FV = {
		/***** CUSTOMIZABLE PROPERTIES *****/
		// Border style for invalid fields
		borderError:'solid 2px #ff0000',
		// border style for valid fields
		borderPass:'1px solid rgb(191, 200, 192)',
		// Default error messages to display if validation fails per type
		errorMessage:{
			emptyField		:'Please fill in all the required fields!',
			email			:'Please enter a valid email address!',
			integer			:'Please only use numbers!',
			alphabet		:'Please use only letters!',
			selection		:'Please make a selection!',
			extendedMessage	:'Form did not validate!'
		},
		// Class for FormValidator to validate
		validateClasses:[
			'validate',
			'validateEmail',
			'validateInteger',
			'validateAlphabet'
		],
		/***********************************/
		/***** LEAVE AS IS *****/
		// Set an empty current radio object for looping
		curRadio:{},
		// Leave empty - updates with current validateClass being checked
		curClass:'',
		// Leave emptyField - Sets which error is to be thrown
		errorType:'emptyField',
		// Leave false - controls which field this.focus() jumps to
		firstFocus:false,
		// Leave false - if errors are found sets to true
		foundErrors:false,
		// Leave false - if a radio is checked in a given name group sets to true
		radioChecked:false,
		// Leave at 0 - Counts how many time the script is run
		timesValidated:0,
		// You can pipe in your own validation after instantiating this class
		// This function runs at the end of this.validate()
		// This function must return true or false
		extendedValidation:function(){
			// this.foundErrors = true;
			// this.errorMessage.extendedMessage = 'Custom error message!';
			return true;
		},
		// Checks if a radio is the last radio within a given name set
		// Passed the current radio and the next input field
		isLastRadio:function(elem,nextElem){
			if(nextElem && nextElem.attributes['type']){
				if(nextElem.attributes['type'].nodeValue=='radio', elem.attributes['name'].nodeValue == nextElem.attributes['name'].nodeValue){
					return false;
				}else{
					return true;
				}
			}
		},
		// Checks if input has the class of this.validateClass
		// Handles multiple classes per input
		isValidateClass:function(elem){
			var classes = elem.className.split(" ");
			for(c in classes){
				for(v in this.validateClasses){
					if(classes[c]==this.validateClasses[v]){
						this.curClass = classes[c];
						return true;
					}
				}
			}
			return false;
		},
		// Gives a valid field a passing border
		passingBorder:function(elem){
			elem.style['border'] = this.borderPass;
		},
		// Resets FV object on each submit event
		reset:function(){
			this.foundErrors = false;
			this.firstFocus = false;
			this.radioChecked = false;
			this.setCurRadio();
			this.timesValidated++;
		},
		// Sets a Dummy radio field for first radio check
		setCurRadio:function(){
			this.curRadio = document.createElement('input');
			this.curRadio.setAttribute('type','radio');
			this.curRadio.setAttribute('name','DUMMY');
			this.curRadio.checked = false;
			return this.curRadio;
		},
		// Sets the focus to the top most invalid form field
		setFirstFocus:function(elem){
			if(!this.firstFocus){
				elem.focus();
				this.firstFocus = true;
				this.firstErrorType = this.errorType;
				return true;
			}else{
				return false;
			}
		},
		// Throws the error message
		// Customize your own throwError in a thickbox if you like
		throwError:function(){
			alert(this.errorMessage[this.errorType=='extendedMessage' ? this.errorType : this.firstErrorType]);
		}
	};
	// Creates an empty form element to be populated when instantiated
	this.form = document.createElement('form');
	// Sets the form to be validated and binds the submit event
	this.setForm = function(formID){
			var FVinstance = this;
			this.form = document.getElementById(formID);
			this.form.onsubmit = function (){
				return FVinstance.validate();
			};
	};
	this.setForm(formID);
	// Validates this.form on submit based on configuration
	this.validate = function(){
		// Resets FV class to defaults
		this.FV.reset();
		
		// custom for Fax or Submit reset red boxes
		if (document.getElementById('svradio1')) {
		  document.getElementById('svradio1').parentNode.style.border=this.FV.borderPass;
		}
		if (document.getElementById('svradio2')) {
		  document.getElementById('svradio2').parentNode.style.border=this.FV.borderPass;
		}
		
		var f = this.form;
		for(var i=0;i<f.length;i++){
			// Checks if is a validatable class
			if(this.FV.isValidateClass(f[i])){
				// Checks if form field is an input field with a type attribute
				if(f[i].attributes['type']){
					// Loop through types
					switch(f[i].attributes['type'].nodeValue){
						case 'radio':
							if(f[i].checked){
								this.FV.radioChecked = true;
							}
							if(this.FV.isLastRadio(f[i],f[i+1])){
								this.FV.foundErrors = !this.FV.radioChecked ? true: false;
								this.FV.radioChecked = false;
							}
							this.FV.curRadio = f[i];
							// Generate errors and borders for radio buttons
							if(this.FV.foundErrors){
								f[i].parentNode.style['border'] = this.FV.borderError;
								this.FV.errorType = 'selection';
								this.FV.setFirstFocus(f[i]);
							}else{
								this.FV.passingBorder(this.FV.curRadio.parentNode);
							}
						break;
						// Handles text and password based on the class
						// Make cases for these if you want something different
						default:
							switch(this.FV.curClass){
								case 'validateEmail':
									var emailFilter=/^.+@.+\..{2,3}$/;
									if (!(emailFilter.test(f[i].value))){
										this.FV.errorType = 'email';
										this.FV.foundErrors = true;
									}
								break;
								case 'validateInteger':
									if(!isInteger(f[i].value)){
										this.FV.errorType = 'integer';
										this.FV.foundErrors = true;
									}
								break;
								case 'validateAlphabet':
									if(!isAlpha(f[i].value)){
										this.FV.errorType = 'alphabet';
										this.FV.foundErrors = true;
									}
								break;
								default:
									if(f[i].value==''){
										this.FV.errorType = 'emptyField';
										this.FV.foundErrors = true;
									}
								break;
								
							}
							// Generate errors and borders for input fields
							if(this.FV.foundErrors){
								f[i].style['border'] = this.FV.borderError;
								this.FV.setFirstFocus(f[i]);
							}else{
								this.FV.passingBorder(f[i]);
							}
						break;
					}
				}else{
					// Validates selects and textareas
					switch(f[i].nodeName){
						default:
							if(f[i].value==''){
								this.FV.foundErrors = true;
								switch(f[i].tagName){
									case 'TEXTAREA':
										this.FV.errorType = 'emptyField';
									break;
									case 'SELECT':
										this.FV.errorType = 'selection';
									break;
								}
							}
						break;
					}
					// Generate errors and borders for selects and textareas
					if(this.FV.foundErrors){
						f[i].style['border'] = this.FV.borderError;
						this.FV.setFirstFocus(f[i]);
					}else{
						this.FV.passingBorder(f[i]);
					}
				}
			}
		}
		if(!this.FV.foundErrors){
			// If no errors found check the custom validations
			if(!this.FV.extendedValidation()){
				this.FV.throwError();
				return false;
			}else{
				return true;
			}
		}else{
			this.FV.throwError();
			return false;
		}
	};
}