var validator = null;

function initFormValidation()
{
	var arrValidationForms = $ES('form').filterByAttribute('validationrequired','=','true').filter(function(item){
		validator = new Validate(item);											 
		return validator;
	});
}

/**************************************************************

	Script		: Validate
	Version		: 2.1
	Authors		: Samuel Birch
	Desc		: Form validation
	Licence		: Open Source MIT Licence

**************************************************************/

var Validate = new Class({
	
	getOptions: function(){
		return {
			validateOnKeys: true,
			validateOnBlur: true,
			errorFieldClass: 'errorField',
			errorMsgListClass: 'errorMessageList',
			errorFieldMsgClass: 'errorFieldMessage',
			formatFieldMsgClass: 'formatFieldMessage',
			dateFormat: 'dd/MM/yyyy',
			onFail: failedValidation,
			onSuccess: submitForm,
			showErrorsInline: true,
			label: 'Please wait...'
		};
	},

	initialize: function(form, options){
		this.setOptions(this.getOptions(), options);
				
		this.form = $(form);
		this.errMsgList = new Element('ul');
		this.errListDiv = new Element('div').addClass(this.options.errorMsgListClass).injectAfter(this.form);
		this.errMsgList.injectInside(this.errListDiv);

		this.allelements = this.form.getElementsBySelector('input, textarea, select');
		this.elements = this.form.getElementsBySelector('input, textarea, select').filterByAttribute('validationrequired','=','true');

		this.list = [];
		this.fieldlist = new Array();
		
		this.allelements.each(function(el,i){
			this.fieldlist.include(el.name);
		}.bind(this));

		
		// Added to do capitalisation
		this.allelements.each( function(el, i) {
		
			if(el.getProperty('transform') != null )
			{
				el.addEvent('blur', this.transform.bind(this, el) );	
			}
		
		}.bind(this));
		

		if(this.options.validateOnKeys)
		{
			this.elements.each(function(el,i){
				if (el.getProperty('type')=='checkbox' || el.getProperty('type')=='radio')
				{
					el.addEvent('click', this.keyupvalidate.bind(this, el));
				}
				else if (el.getProperty('type')=='select-one')
				{
					el.addEvent('mousedown', this.clearselect.bind(this, el));
					el.addEvent('change', this.keyupvalidate.bind(this, el));
				}
				else if (el.getProperty('type')=='text' || el.getProperty('type')=='textarea')
				{
					el.addEvent('keyup', this.keyupvalidate.bind(this, el));
					el.addEvent('focus', this.keyupvalidate.bind(this, el));
				}
			}.bind(this));
		}

		if(this.options.validateOnBlur)
		{
			this.elements.each(function(el,i){
				if (el.getProperty('type')=='text' || el.getProperty('type')=='textarea' || el.getProperty('type')=='select-one')
				{
					el.addEvent('blur', this.blurvalidate.bind(this, el));
				}
			}.bind(this));
		}


		this.form.addEvent('submit', function(e){
					
			var event = new Event(e);
			var doSubmit = true;
			this.elements.each(function(el,i){
				if(! this.validate(el)){
					event.stop();
					doSubmit = false
					this.list.include(el);
				}else{
					this.list.remove(el);
				}
			}.bind(this));
			
			if(doSubmit){
				if(this.options.onSuccess){
					event.stop();
					
					var oFieldOrder = this.form.getElement('input[id=fieldorder]');
					if(!oFieldOrder)
					{
						oFieldOrder = new Element('input');
						oFieldOrder.setProperty('type', 'hidden');
						oFieldOrder.setProperty('id', 'fieldorder');
						oFieldOrder.setProperty('name', 'fieldorder');
						oFieldOrder.setProperty('value', this.getFieldList());
						oFieldOrder.injectInside(this.form);
					}
					else
					{
						oFieldOrder.setProperty('value', this.getFieldList());
					}
					
					var oSendMail = this.form.getElement('input[id=sendmail]');
					if(!oSendMail)
					{
						oSendMail = new Element('input');
						oSendMail.setProperty('type', 'hidden');
						oSendMail.setProperty('id', 'sendmail');
						oSendMail.setProperty('name', 'sendmail');
						oSendMail.setProperty('value', 'true');
						oSendMail.injectInside(this.form);
					}
					else
					{
						oSendMail.setProperty('value', 'true');
					}
					this.options.onSuccess(this.form);
				}else{
					this.form.getElement('input[type=submit]').setProperty('value',this.options.label);
				}
			}
			else
			{
				this.options.onFail(this.getList(), this.errMsgList);
			}
		}.bind(this));
		
	},
	
	getList: function(){
		var list = new Element('ul');
		this.list.each(function(el,i){
			if(el.title != ''){
			var li = new Element('li').injectInside(list);
			new Element('label').setProperty('for', el.id).setText(el.title).injectInside(li);
			}
		});
		return list;
	},

	getFieldList: function(){
		var list = new String();
		var i = 0;
		this.fieldlist.each(function(item){
			if (!item.contains('fieldorder')&&!item.contains('sendmail')&&!item.trim()=='')
			{
				list = list + ((i>0)? "," : "") + item;
				i++;
			}
		});
		return list;
	},
	
	addFieldToList: function(el){
		this.fieldlist.include(el.name);
	},

	emptyField: function(valfield){ 
		var emptyString = /^\s*$/ ;
		return emptyString.test(valfield.value);
	},

	ltrim: function(el){
		return el.value.replace(/^\s+/,'');
	},

	rtrim: function(el){
		return el.value.replace(/\s+$/,"");
	},

	trim: function(el){
		return el.value.replace(/^\s+|\s+$/g,"");
	},

	validateminlength: function(el){
		if (el.getProperty('minlength'))
		{
			return (parseInt(el.getProperty('minlength'))<=this.ltrim(el).length);
		}
		else
		{
			return true;
		}
	},

	clearselect: function(el){
		this.clearMsg(el);
	},

	cancelevent: function(el)
	{
		event.cancelBubble = true;
	},

	keyupvalidate: function(el){
		if ((el.type=='text')||(el.type=='textarea'))
		{
			if (el.value.length)
			{	
				if(this.emptyField(el))
				{
					el.value = this.trim(el);
				}
				else
				{
					this.validate(el, false);
				}
			}
			if (!el.value.length)
			{
				this.clearMsg(el);
			}
		}
		else if ((el.type=='checkbox')||(el.type=='radio'))
		{
			this.validate(el, false);
		}
		else if (el.type=='select-one')
		{
			this.validate(el, false);
		}
	},

	blurvalidate: function(el){
		el.value = this.trim(el);
		return this.validate(el, true);	
	},
	
	validate: function(el, bValidateMinLength){
		var valid = true;
		if(el.getProperty('validationrequired')=='true')
		{
			switch(el.type){
				case 'text':
				case 'textarea':
				case 'select-one':
					if(el.value != ''){
						if(el.getProperty('validationdatatype')=='email'){
//							var regEmail = /^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/;
							var regEmail = /^[^@]+@[^@.]+\.[^@]*\w\w$/;
							if(el.value.toUpperCase().match(regEmail)){
								valid = true;
								this.clearMsg(el);
							}else{
								valid = false;
								this.setMsg(el, 'Please enter a valid email address');
							}
						}
						
						if(el.getProperty('validationdatatype')=='numeric'){
							var regNum = /^\d+$/;
							if(el.value.match(regNum)){
								valid = true;
								this.clearMsg(el);
							}else{
								valid = false;
								this.setMsg(el, 'Please enter numbers only');
							}
							if (valid && bValidateMinLength)
							{
								if(!this.validateminlength(el))
								{
									valid = false;
									this.setMsg(el, 'Please enter at least '+ el.getProperty('minlength') +' numerals');
								}
							}
						}
	
						if(el.getProperty('validationdatatype')=='alpha')
						{
							var regAlpha = /^\D+$/;
							if(el.value.match(regAlpha))
							{
								valid = true;
								this.clearMsg(el);
							}
							else
							{
								valid = false;
								this.setMsg(el, 'Please enter letters only');
							}
							if (valid && bValidateMinLength)
							{
								if(!this.validateminlength(el))
								{
									valid = false;
									this.setMsg(el, 'Please enter at least '+ el.getProperty('minlength') +' letters');
								}
							}
						}
	
						if(el.getProperty('validationdatatype')=='alphanumeric'){
							var regAlphaNumeric = /[A-Za-z0-9]/;
							if(el.value.match(regAlphaNumeric)){
								valid = true;
								this.clearMsg(el);
							}
							else
							{
								valid = false;
								this.setMsg(el, 'Please enter letters and numbers only');
							}
							if (valid && bValidateMinLength)
							{
								if(!this.validateminlength(el))
								{
									valid = false;
									this.setMsg(el, 'Please enter at least '+ el.getProperty('minlength') +' letters or numbers');
								}
							}
						}
						if(el.getProperty('validationdatatype')=='ukpostcode'){
							// This regex supports all uk postcode formats with or without a space, eg
							// OX14 4RY
							// OX144RY
							// EC1N 2NT
							// W12AA
							// 
							// it does not check whether they are valid UK postcodes
							var regPC = /^([A-Za-z]{1,2})([0-9]{1,2})([A-Za-z]{0,1})([ ]{0,1})([0-9]{1})([A-Za-z]{2})$/;
							if(el.value.match(regPC)){
								valid = true;
								this.clearMsg(el);
							}else{
								valid = false;
								this.setMsg(el, 'Please enter a valid postcode');
							}
						}
/*						if(el.getProperty('validationdatatype')=='postcode'){
							var regPC = /^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$/
							if(el.value.match(regPC)){
								valid = true;
								this.clearMsg(el);
							}else{
								valid = false;
								this.setMsg(el, 'Please enter a valid postcode');
							}
						}
*/						
						if(el.getProperty('validationdatatype')=='date'){
							var d = Date.parseExact(el.value, this.options.dateFormat);
							if(d != null){
								valid = true;
								this.clearMsg(el);
							}else{
								valid = false;
								this.setMsg(el, 'Please enter a valid date in the format: '+this.options.dateFormat.toLowerCase());
							}
						}
					}else{
						valid = false;
						this.setMsg(el);
					}
					break;
					
				case 'checkbox':
					if(!el.checked){
						valid = false;
						this.setMsg(el);
					}else{
						valid = true;
						this.clearMsg(el);
					}
					break;
					
				case 'radio':
					var rad = $A(this.form[el.name]);
					var ok = false;
					rad.each(function(e,i){
						if(e.checked){
							ok = true;
						}
					});
					valid = ok;
					if (!valid)
					{
						this.setMsg(rad.getLast(), 'Please select an option');
					}
					else
					{
						this.clearMsg(rad.getLast());
					}
					break;
			}
 		}
		return valid;
	},
	
	setMsg: function(el, msg){
		var bFormatError = true;

		if (el.type=='radio')
		{
			if (el.title!='')
			{
				bFormatError = false;
				msg = el.title;
			}
		}
		else if(msg == undefined)
		{
			bFormatError = false;
			msg = el.title;
		}
		if(this.options.showErrorsInline){
			if(el.error == undefined)
			{
				el.error = new Element('span').injectAfter(el);
			}
			el.error.setText(msg);
			el.error.addClass(((bFormatError)?this.options.formatFieldMsgClass:this.options.errorFieldMsgClass));
			el.addClass(this.options.errorFieldClass);
		}
	},
	
	clearMsg: function(el){
		el.removeClass(this.options.errorFieldClass);
		if(el.error != undefined){
			el.error.remove();
			el.error = undefined;
		}
	},
	
	transform: function(el)
	{
		if(el.getProperty('type') == 'text' && el.value.length > 0)
		{
			if( el.getProperty('transform') == 'capitalise' )
			{
				    val = el.value;
					newVal = '';
					val = val.split(' ');
					for(var c=0; c < val.length; c++) {
						newVal += val[c].substring(0,1).toUpperCase() +
						val[c].substring(1,val[c].length) + ' ';
					}
					el.value = newVal;
			}
			
			if( el.getProperty('transform') == 'capitalisehyphen' )
			{
				    val = el.value;
					newVal = '';
					val = val.split(' ');
					for(var c=0; c < val.length; c++) {
						newVal += val[c].substring(0,1).toUpperCase() +
						val[c].substring(1,val[c].length);
						
						if( c < val.length-1) newVal += ' ';
					}
					val = newVal;
					
					newVal = '';
					val = val.split('-');
					for(var c=0; c < val.length; c++) {
						newVal += val[c].substring(0,1).toUpperCase() +
						val[c].substring(1,val[c].length);
						
						if( c < val.length-1) newVal += '-';
					}
					
					el.value = newVal;
			}
			
			if( el.getProperty('transform') == 'uppercase' ) el.value = el.value.toUpperCase();
			
			if( el.getProperty('transform') == 'ukpostcode' )
			{
				el.value = el.value.toUpperCase();
				
				if(el.value.indexOf(' ')  == -1)
				{					
					el.value = el.value.substr(0, el.value.length - 3) + ' ' + el.value.substring(el.value.length-3);	
				}
			}
		}
	}
	
});


function failedValidation(arrErrors, oErrMsgList)
{
	oErrMsgList.setHTML(arrErrors.innerHTML);
}

function submitForm(myForm)
{
	myForm.submit();	
}

Validate.implement(new Options);
Validate.implement(new Events);


/*************************************************************/
/*
window.addEvent('domready', function(){
	initFormValidation();
});
*/

