/*///////////////////////////////////////////////////////////////////////
/ AzT3K Verifier Object
/ Copyright Aaron Latham-Anderson 2008
/ Last update:  22/04/2010
/ -----------------------------------------------------------------------
---------
BUGS, ISSUES AND THING TO IMPROVE
---------

*Batch Validation for prefixed checkbox inputs e.g.

function v2(o){
	var i=0
	while(i<document.forms['batch_select'].elements.length){
		var curElem = document.forms['batch_select'].elements[i]
		var re = /batch_/
		var match1 = re.test(curElem.name)
			if(match1==true){
				if(curElem.checked==true){
					var selection_made = true
				}			
			}
		i++
	}
	if(selection_made==true){
		o.form.submit()
	}else{
		document.forms['batch_select'].elements['function'].selectedIndex = 0
		alert("you must make a selection first")
	}
}

*New Validation Types
-Word Limit
-illegal word 
	- word groups e.g. profanity, html tags etc
	- add_illegal_term()


---------
 USAGE
---------
<head>
	<script language="javascript" type="text/javascript" src="script/avo.js"></script>
	<script language="javascript" type="text/javascript">
			
		//Custom response functions
		function custom_error(e_name,e){
			var o = document.forms[this.fname].elements[e_name];
			var o_name = this.field_names[this.ids[e_name]];
			switch(e){
				case "empty":
					o.style.backgroundColor = '#ffcccc';
					switch(o.type){
						case "text":
							alert('Please fill in the '+o_name+' field');					
						break;
						case "select-one":
							alert('Please make a selection from the '+o_name+' selector');					
						break;
						case "textarea":
							alert('Please fill in the '+o_name+' field');					
						break;
						case "checkbox":
							alert('Please check the '+o_name+' checkbox');					
						break;					
						default:
							alert('Please fill in the '+o_name+' field');					
						break;
					}				
				break;
				case "syntax":
					o.style.backgroundColor = '#ffcccc';
					alert('The information you provided in the '+o_name+' field was invalid')
				break;
				case "max_chars":
					o.style.backgroundColor = '#ffcccc';
					alert('The information you provided in the '+o_name+' field has too many characters')
				break;
				case "invalid_chars":
					o.style.backgroundColor = '#ffcccc';
					alert('The information you provided in the '+o_name+' field contains illegal characters')
				break;							
			}
		}
		
		function custom_ok(e_name){
			var o = document.forms[this.fname].elements[e_name];
			o.style.backgroundColor = '#ffffff';
			switch(o.type){
				case "text":
				break;
				case "select-one":
				break;
				case "textarea":
				break;
				case "checkbox":
				break;					
				default:
				break;
			}				
		}	
		
		//prototype in custom response functions
		avo.prototype.custom_error = custom_error
		avo.prototype.custom_ok = custom_ok
	</script>	
</head>
<body>
	<form></form>
	<script language="javascript" type="text/javascript">
		//Constructor
		//avo(form_name/identifier-STRING-[DEAFULT=0], error_function name-STRING-[DEAFULT='error'], ok_function name-STRING-[DEAFULT='ok'])
		
		var test = new avo(); //uses document.forms[0], avo.error() and avo.ok()
		var test_custom = new avo('form1','custom_error','custom_ok'); //uses document.forms['form1'], and custom response functions
		avo.errorColour 					= "#000000";
		avo.okColour					 	= "#004400";	
		
		//Add fields to verifier / define verification type
		//addField(element_name-STRING, field_title(for response funcs)-STRING, check_if_empty-BOOLEAN, syntax_validation_type-STRING/NULL(no check), max_char_limit-INT/NULL(no check), add_event_listener_max_chars-BOOLEAN, illegal_char_expression-REGULAR EXPRESSION/NULL(no check),add_event_listener_illegal_chars-BOOLEAN)
		test.addField('textbox','description text box',true,null,100,true,test.rs_num,true)
		test.addField('txt1',true,'web');
		test.addField('txt2',true,null);
		test.addField('txt3',false,'email');
		test.addField('sel1',true,null);
		test.addField('chk1',true,null);		
	</script>
</body>

///////////////////////////////////////////////////////////////////////*/

function avo(form_name,error_func_name,ok_func_name,error_colour,ok_colour){
	
	//Properties - Options
	this.allow_select_0 				= false;
	this.allow_select_null_value 		= true;
	this.prevent_multiple_submissions 	= true;
	this.errorColour 					= (typeof error_color != 'undefined' && error_color) ? error_color :  "#ffcccc" ;
	this.okColour					 	= (typeof ok_color != 'undefined' && ok_color) ? ok_color :  "#ffffff" ;	
	
	//Properties - Arrays	
	this.ids			= [];
	this.fields 		= [];
	this.field_names	= [];
	this.v_empty 		= [];
	this.v_syntax 		= [];	
	this.v_chars 		= [];
	this.v_chars_l 		= [];	
	this.v_max			= []; //name space clash with v_max()	
	this.v_max_l 		= [];
	this.v_max_words	= [];	
	this.v_max_words_l 	= [];		

	//Properies - States
	this.form_submitted 	= false;	
	this.is_empty 			= false;
	this.has_invalid_syntax = false;
	this.has_illegal_chars	= false;	
	this.has_too_many_chars	= false;
	this.has_too_many_words	= false;

	//Properties from arguments
	form_name		== null	? this.fname	= 0 		: this.fname	= form_name;
	error_func_name	== null	? this.efn 		= 'error'	: this.efn		= error_func_name;
	ok_func_name	== null	? this.ofn 		= 'ok' 		: this.ofn		= ok_func_name;
	
	//Properties - illegal character strings
	this.rs_email	= /[=+!#$%\^&;:*()_\\|{}\[\]?<>\"~`€¢£¥¤§¦¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿]/
	this.rs_alpha	= /[0-9=+!@#$%\^&;:*()_\\|{}\[\]?\/.,<>\"\'~`€¢£¥¤§¦¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿-]/
	this.rs_name	= /[0-9=+!@#$%\^&;:*()_\\|{}\[\]?\/.,<>\"~`€¢£¥¤§¦¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿]/
	this.rs_company	= /[=+!@#$%\^&;:*()_\\|{}\[\]?\/,<>\"~`€¢£¥¤§¦¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿]/
	this.rs_address	= /[=+!@#$%\^&;:*()_\\|{}\[\]?<>\"~`€¢£¥¤§¦¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿]/
	this.rs_num		= /[a-zA-Z=+!@#$%\^&;:*()_\\|{}\[\]?\/.,<>\"\'~`€¢£¥¤§¦¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿-]/
	this.rs_int		= /[a-zA-Z=+!@#$%\^&;:*()_\\|{}\[\]?\/.,<>\"\'~`€¢£¥¤§¦¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿-]/	
	this.rs_decimal	= /[a-zA-Z=+!@#$%\^&;:*()_\\|{}\[\]?\/,<>\"\'~`€¢£¥¤§¦¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿-]/	
	this.rs_ph		= /[a-zA-Z=!@#$%\^&;:*_\\|{}\[\]?\/.,<>\"\'~`€¢£¥¤§¦¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿-]/
	this.rs_price	= /[a-zA-Z=+!@#$%\^&;:*()_\\|{}\[\]?\/,<>\"\'~`€¢£¥¤§¦¨©ª«¬®¯°±²³´¶·¸¹º»¼½¾¿-]/
	
	//Methods - addField(element_name-STRING, field_title(for response funcs)-STRING, check_if_empty-BOOLEAN, check_syntax_validation_type-STRING/NULL(no check), max_char_limit-INT/NULL(no check), add_event_listener_max_chars-BOOLEAN, illegal_char_expression-REGULAR EXPRESSION/NULL(no check),add_event_listener_illegal_chars-BOOLEAN)
	this.addField = function(e_name,f_name,chk_e,chk_s,chk_mx,chk_mx_l,chk_chars,chk_chars_l,chk_mx_words,chk_mx_words_l){
		var new_length = this.fields.push(e_name)
		var id = new_length - 1
		this.ids[e_name] = id	
		this.field_names[id] = f_name	
		this.v_empty[id] = chk_e
		this.v_syntax[id] = chk_s
		this.v_chars[id] = chk_chars
		this.v_chars_l[id] = chk_chars_l
		this.v_max[id] = chk_mx		
		this.v_max_l[id] = chk_mx_l
		this.v_max_words[id] = chk_mx_words		
		this.v_max_words_l[id] = chk_mx_words_l		
		this.update_event_listeners()
	}
	
	//Methods - removeField(element_name-STRING)
	this.removeField = function(e_name){
		var id = this.ids[e_name]
		if(id==null){
			return false
		}else{
			delete this.ids[e_name]
			delete this.field_names[id]
			delete this.v_empty[id]
			delete this.v_syntax[id]
			delete this.v_max[id]
			delete this.v_max_l[id]
			delete this.v_chars[id]				
			delete this.v_chars_l[id]			
			delete this.fields[id]
			this.update_event_listeners()	
			return true						
		}
	}
	
	//Methods - editField(element_name-STRING, field_title(for response funcs)-STRING, check_if_empty-BOOLEAN, check_syntax_validation_type-STRING/NULL(no check), max_char_limit-INT/NULL(no check), add_event_listener_max_chars-BOOLEAN, illegal_char_expression-REGULAR EXPRESSION/NULL(no check),add_event_listener_illegal_chars-BOOLEAN)
	this.editField = function(e_name,f_name,chk_e,chk_s,chk_mx,chk_mx_l,chk_chars,chk_chars_l,chk_mx_words,chk_mx_words_l){
		if(this.ids[e_name]==null || this.ids[e_name]=='undefined'){
			this.addField(e_name,f_name,chk_e,chk_s,chk_mx,chk_mx_l,chk_chars,chk_chars_l,chk_mx_words,chk_mx_words_l)
		}else{
			var id = this.ids[e_name]
			this.field_names[id] = f_name			
			this.v_empty[id] = chk_e
			this.v_syntax[id] = chk_s
			this.v_chars[id] = chk_chars
			this.v_chars_l[id] = chk_chars_l
			this.v_max[id] = chk_mx		
			this.v_max_l[id] = chk_mx_l
			this.v_max_words[id] = chk_mx_words		
			this.v_max_words_l[id] = chk_mx_words_l			
			this.update_event_listeners()	
		}
	}
	
	//Methods - this.add_e_handler(obj, e, func) - adds event hander to object
	this.add_e_handler = function(obj, e, func){
		//test if func exists - prevents problems in IE
		if(typeof func != "undefined"){		
			if(obj.attachEvent){
				obj.attachEvent('on' + e, func);
			}else if(obj.addEventListener){
				obj.addEventListener(e, func, false);
			}else{
				obj['on' + e] = func;
			}
		}
	}
	
	//Methods - this.remove_e_handler(obj, e, func) - removes event hander from object
	this.remove_e_handler = function(obj, e, func){
		//test if func exists - prevents problems in IE		
		if(typeof func != "undefined"){
			if (obj.detachEvent){
				obj.detachEvent('on' + e, func);
			}else if(obj.removeEventListener){
				obj.removeEventListener(e, func, false);
			}else{
				obj['on' + e] = null;
			}
		}
	}
	
	this.update_event_listeners = function(){
		var i=0
		for( i=0; i<this.fields.length; i++ ){	
			var current_field = document.forms[this.fname].elements[this.fields[i]]
			if(this.v_max_l[i]){
				//Remove previously assigned events with the same listener to prevent double ups
				this.remove_e_handler(current_field, "keypress", this['f_max'+i])				
				//for some reason the event listener doesn't get deleted properly when the function is reassigned - so has to be assigned from a previous value of null or undefined
				delete this['f_max'+i]
				//Generate curried function = max_char(450,this,event) => leave event to be autofilled 				
				this['f_max'+i] = this.curry(this.r_max,this.v_max[i],current_field)
				//Add
				this.add_e_handler(current_field, "keypress", this['f_max'+i])
			}
			if(this.v_max_words_l[i]){
				//Remove previously assigned events with the same listener to prevent double ups
				this.remove_e_handler(current_field, "keypress", this['f_max_word'+i])				
				//for some reason the event listener doesn't get deleted properly when the function is reassigned - so has to be assigned from a previous value of null or undefined
				delete this['f_max_word'+i]
				//Generate curried function = max_words(450,this,event) => leave event to be autofilled 				
				this['f_max_word'+i] = this.curry(this.r_max_word,this.v_max_words[i],current_field)
				//Add
				this.add_e_handler(current_field, "keypress", this['f_max_word'+i])
			}			
			if(this.v_chars_l[i]){
				//Remove previously assigned events with the same listener to prevent double ups
				this.remove_e_handler(current_field, "keypress", this['f_chars'+i])
				//for some reason the event listener doesn't get deleted properly when the function is reassigned - so has to be assigned from a previous value of null or undefined				
				delete this['f_chars'+i]
				//generate curried function = r_char(name1,this,event) => leave event to be autofilled				
				this['f_chars'+i] = this.curry(this.r_char,this.v_chars[i],current_field)
				//Add
				this.add_e_handler(current_field, "keypress", this['f_chars'+i])
			}
		}	
	}
	
	//Methods - v() form submission control - usage onsubmit="return v();"	
	this.v = function(thisArg,e){
		if (!e) var e = window.event;
		//innocent until proven guilty
		thisArg.is_empty = false;
		thisArg.has_invalid_syntax	= false;
		thisArg.has_illegal_chars	= false;	
		thisArg.has_too_many_chars	= false;
		thisArg.has_too_many_words	= false;		
		var field_ok = true;
		
		for( i=0; i<thisArg.fields.length; i++ ){
			field_ok = true;			
			//Check if empty
			if(thisArg.v_empty[i]){
				field_ok = thisArg.chk_empty(thisArg.fields[i])
			}
			//if the field passes empty validation
			if(field_ok){
				//Check the syntax
				if(thisArg.v_syntax[i]!=null && thisArg.v_syntax[i]!=""){
					field_ok = thisArg.chk_syntax(thisArg.fields[i],thisArg.v_syntax[i])
				}
			}
			//if the field passed previous validation
			if(field_ok){
				//Check the length
				if(thisArg.v_max[i]!=null && thisArg.v_max[i]!=""){
					field_ok = thisArg.v_max(thisArg.fields[i],thisArg.v_max[i])
				}
			}
			//if the field passed previous validation
			if(field_ok){
				//Check the length
				if(thisArg.v_max_words[i]!=null && thisArg.v_max_words[i]!=""){
					field_ok = thisArg.v_max_word(thisArg.fields[i],thisArg.v_max_words[i])
				}
			}			
			//if the field passed previous validation
			if(field_ok){
				//Check for illegal characters
				if(thisArg.v_chars[i]!=null && thisArg.v_chars[i]!=""){
					field_ok = thisArg.v_char(thisArg.fields[i],thisArg.v_chars[i])
				}
			}			
		}
		
		//Return validation status
		if(thisArg.is_empty || thisArg.has_invalid_syntax || thisArg.has_too_many_chars || thisArg.has_too_many_words || thisArg.has_illegal_chars || !field_ok){
			//preventDefault() is effectively the same as using return before calling a function that returns false to stop the default action		
			(e.preventDefault) ? e.preventDefault() : e.returnValue = false;		
			return false;
		}else{
			if(thisArg.prevent_multiple_submissions){
				if(thisArg.form_submitted){
					(e.preventDefault) ? e.preventDefault() : e.returnValue = false;			
					return false;	
				}else{
					thisArg.form_submitted = true;		
					return true;	
				}
			}else{
				thisArg.form_submitted = true;
				return true;							
			}			
		}
	}
	
	//Methods - chk_syntax(element_name-STRING, syntax_validation_type-STRING)
	this.chk_syntax = function(e_name,t){
		var eo = document.forms[this.fname].elements[e_name]
		var e = eo.value;
		//Dont test syntax if the field is blank or if the field has predefined values
		if( (e=="" || e==null) || (eo.type=='select-one' || eo.type=='radio' || eo.type=='checkbox') ){
				return true;			
		}else{
			if(t=='email'){
				var regexp = "^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$";
			}else if(t=='web'){
				var regexp = "^((https?|ftp)\://((\[?(\d{1,3}\.){3}\d{1,3}\]?)|(([-a-zA-Z0-9]+\.)+[a-zA-Z]{2,4}))(\:\d+)?(/[-a-zA-Z0-9._?,'+&%$#=~\]+)*/?)$";	
			}
			if (e.match(regexp)){	
				this[this.ofn](e_name);			
				return true;
			}else{   
				this[this.efn](e_name,'syntax');
				this.has_invalid_syntax = true;				
				return false;
			}
		}
	}
	
	//Methods - chk_empty(element_name-STRING)
	this.chk_empty = function(e_name){
		var e = document.forms[this.fname].elements[e_name];
		if(typeof e != "undefined"){
			switch(e.type){
				case "text":
					if(e.value == null || e.value == ""){
						this[this.efn](e_name,'empty');
						this.is_empty = true;
						return false;
					}else{
						this[this.ofn](e_name);						
						return true;
					}				
				break;
				case "select-one":
					if(!this.allow_select_null_value && this.allow_select_0){
						if(e.value == null || e.value == ""){
							this[this.efn](e_name,'empty');
							this.is_empty = true;
							return false;
						}else{
							this[this.ofn](e_name);							
							return true;
						}
					}
					if(!this.allow_select_0 && !this.allow_select_null_value){
						if(e.selectedIndex == 0 || (e.value == null || e.value == "")){
							this[this.efn](e_name,'empty');
							this.is_empty = true;
							return false;
						}else{
							this[this.ofn](e_name);							
							return true;
						}
					}
					if(!this.allow_select_0 && this.allow_select_null_value){
						if(e.selectedIndex == 0){
							this[this.efn](e_name,'empty');
							this.is_empty = true;
							return false;
						}else{
							this[this.ofn](e_name);							
							return true;
						}
					}					
				break;
				case "textarea":
					if(e.value == null || e.value == ""){
						this[this.efn](e_name,'empty');
						this.is_empty = true;
						return false;
					}else{
						this[this.ofn](e_name);						
						return true;
					}				
				break;
				case "password":
					if(e.value == null || e.value == ""){
						this[this.efn](e_name,'empty');
						this.is_empty = true;
						return false;
					}else{
						this[this.ofn](e_name);						
						return true;
					}				
				break;
				case "checkbox":
					if(e.checked == false){
						this[this.efn](e_name,'empty');
						this.is_empty = true;
						return false;
					}else{
						this[this.ofn](e_name);
						return true;
					}				
				break;				
			}
		}
	}
	
	//Methods - v_max() - Max Characters validator
	this.v_max = function(e_name,maxchars){
		var o = document.forms[this.fname].elements[e_name];
		if(o.value.length <= maxchars){
			this[this.ofn](e_name);		
			return true
		}else{
			this.has_too_many_chars	= true;	
			this[this.efn](e_name,'max_chars');						
			return false
		}
	}
	
	//Methods - v_max_word() - Max words validator
	this.v_max_word = function(e_name,maxwords){
		var o = document.forms[this.fname].elements[e_name];
		var matches = o.value.split(/\b/);
		var ln = (!matches) ? 0 : matches.length/2 ;
		if(ln < maxwords){
			this[this.ofn](e_name);		
			return true
		}else{
			this.has_too_many_words	= true;	
			this[this.efn](e_name,'max_words');						
			return false
		}
	}	
	
	//Methods - v_char() -  Input Restriction Validator
	this.v_char = function(e_name,re){
		var o = document.forms[this.fname].elements[e_name];
		var has_invalid_chars = re.test(o.value)
		if(has_invalid_chars){
			this.has_illegal_chars = true;	
			this[this.efn](e_name,'invalid_chars');			
			return false
		}else{
			this[this.ofn](e_name);						
			return true
		}
	}	
	
	//event based methods	
	
	//Methods - r_max() - Max Characters Restrictor e.g. onkeypress="return max_char(450,this,event);"	
	this.r_max = function(maxchars,o,e){	
		//event is automatically passed to the response function as e in ff/ns and is accessible via the event register in the window object in i.e.
		if (!e) var e = window.event;
		var keynum
		var keychar
		if(window.event){// IE 
			keynum = e.keyCode
		}else if(e.which){// Netscape/Firefox/Opera
			keynum = e.which
		}
		//keynum=="46"==delete && keynum=="8"==backspace my del key's num is undefined
		keychar = String.fromCharCode(keynum)
		if(o.value.length < maxchars || keynum==undefined || keynum=="8" || keynum=="46"){
			return keychar
		}else{
			//preventDefault() is effectively the same as using return before calling a function that returns false to stop the default action		
			(e.preventDefault) ? e.preventDefault() : e.returnValue = false;			
			alert("charcter limit reached (limit "+maxchars+")")					
			return false
		}
	}
	
	//Methods - r_max() - Max Characters Restrictor e.g. onkeypress="return max_char(450,this,event);"	
	this.r_max_word = function(maxwords,o,e){	
		//event is automatically passed to the response function as e in ff/ns and is accessible via the event register in the window object in i.e.
		if (!e) var e = window.event;
		var keynum
		var keychar
		if(window.event){// IE 
			keynum = e.keyCode
		}else if(e.which){// Netscape/Firefox/Opera
			keynum = e.which
		}
		//keynum=="46"==delete && keynum=="8"==backspace my del key's num is undefined
		keychar = String.fromCharCode(keynum)
		var matches = o.value.split(/\b/);
		var ln = (!matches) ? 0 : matches.length/2 ;
		if(ln < maxwords || keynum==undefined || keynum=="8" || keynum=="46"){
			return keychar
		}else{
			//preventDefault() is effectively the same as using return before calling a function that returns false to stop the default action		
			(e.preventDefault) ? e.preventDefault() : e.returnValue = false;			
			alert("word limit reached (limit "+maxwords+")")					
			return false
		}
	}	
	
	//Methods - r_char() -  Input Restrictor e.g. onkeypress="return restrict(name1,this,event);"	
	this.r_char = function(re,o,e){
		if (!e) var e = window.event;
		if(window.event){// IE 
			var keynum = e.keyCode
		}else if(e.which){// Netscape/Firefox/Opera
			var keynum = e.which
		}
		var keychar = String.fromCharCode(keynum)
		if(re.test(keychar)){
			//preventDefault() is effectively the same as using return before calling a function that returns false to stop the default action
			(e.preventDefault) ? e.preventDefault() : e.returnValue = false;			
			alert("illegal character")
			return false
		}else{
			return keychar		
		}
	}	
	
	//Methods - Curry	
	this.curry = function(method){
		var curried = [];
		for (var i = 1; i < arguments.length; i++) {
			curried.push(arguments[i]);
		}
		return function() {
			var args = [];
			for (var i = 0; i < curried.length; i++) {
				args.push(curried[i]);
			}
			for (var i = 0; i < arguments.length; i++) {
				args.push(arguments[i]);
			}
			return method.apply(null, args);
		}
	}
	
	//Add on submit listener
	this.form = document.forms[this.fname];
	if(!this.form || this.form==null || typeof this.form == 'undefined'){
		this.form = document.getElementById(this.fname);
	}
	if(!this.form || this.form==null || typeof this.form == 'undefined'){
		alert( "cannot find form with id or name : "+this.fname )
	}else{
		this.curried_v = this.curry(this.v,this);
		if (this.form.addEventListener) {
			this.form.addEventListener("submit",this.curried_v,false);
		} else if (this.form.attachEvent) {
			this.form.attachEvent("onsubmit",this.curried_v);
		} else {
			this.form.onsubmit = this.curried_v;
		}					
	}
	//Default Response Functions
	
	//Methods - error(element_name-STRING, error_type-STRING) determines an action when an error is encountered
	this.error = function(e_name,e){
		var o = document.forms[this.fname].elements[e_name];
		var o_name = this.field_names[this.ids[e_name]];
		switch(e){
			case "empty":
				o.style.backgroundColor = this.errorColour;
				switch(o.type){
					case "text":
						alert('Please fill in the '+o_name+' field');					
					break;
					case "select-one":
						alert('Please make a selection from the '+o_name+' selector');					
					break;
					case "textarea":
						alert('Please fill in the '+o_name+' field');					
					break;
					case "checkbox":
						alert('Please check the '+o_name+' checkbox');					
					break;					
					default:
						alert('Please fill in the '+o_name+' field');					
					break;
				}				
			break;
			case "syntax":
				o.style.backgroundColor = this.errorColour;
				alert('The information you provided in the '+o_name+' field was invalid')
			break;
			case "max_chars":
				o.style.backgroundColor = this.errorColour;
				alert('The information you provided in the '+o_name+' field has too many characters')
			break;
			case "max_words":
				o.style.backgroundColor = this.errorColour;
				alert('The information you provided in the '+o_name+' field has too many words')
			break;			
			case "invalid_chars":
				o.style.backgroundColor = this.errorColour;
				alert('The information you provided in the '+o_name+' field contains illegal characters')
			break;							
		}
	}
	
	//Methods - ok(element_name-STRING) ensures fields that previously failed and now pass validation revert back to the default style
	this.ok = function(e_name){
		var o = document.forms[this.fname].elements[e_name];
		o.style.backgroundColor = this.okColour;
		switch(o.type){
			case "text":
			break;
			case "select-one":
			break;
			case "textarea":
			break;
			case "checkbox":
			break;					
			default:
			break;
		}				
	}	
	
}