var validator = null;



function initFormValidation()

{

	var arrValidationForms = $ES('form').filterByAttribute('validationrequired','=','true').filter(function(item){

		validator = new Validate(item);											 

		return validator;

	});

}



var Validate = new Class({

	

	getOptions: function(){

		return {

			validateOnKeys: true,

			validateOnBlur: true,

			errorFieldClass: 'errorField',

			errorMsgListClass: 'errorMessageList',

			errorFieldMsgClass: 'errorFieldMessage',

			formatFieldMsgClass: 'formatFieldMessage',

			dateFormat: 'dd/MM/yyyy,dd/MM/yy',

			dateFormatSeparator: ',',

			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','!=','');

		this.list = [];

		this.fieldlist = new Array();

		this.allelements.each(function(el,i){

			this.fieldlist.include(el.name);

		}.bind(this));

		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('change', this.keyupvalidate.bind(this, el));

					el.addEvent('keypress', this.keyupvalidate.bind(this, el));

				}

				else if (el.getProperty('type')=='text' || el.getProperty('type')=='textarea'|| el.getProperty('type')=='password'){

					if (el.getProperty('validateonkeypress')!='false'){

						el.addEvent('keyup', this.keyupvalidate.bind(this, el));

					}

					if (el.getProperty('allowblanks')=='false'){

						el.addEvent('keydown', this.stopkeydown.bind(this));

					}

					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){

//alert('Attempting bind of submit event');

			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));

//alert('Submit Bound :'+doSubmit);

			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]');
					
//alert('Sendmail field exists: '+this.form.getElement('input[id=sendmail]'));

					if(!oSendMail){

//alert('Injecting Sendmail field');

						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{
//alert('Setting Sendmail field value');

						oSendMail.setProperty('value', 'true');

					}

//alert('Sendmail field value: '+this.form.getElement('input[id=sendmail]').getProperty('value'));

					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);

		}

	},



	stopkeydown: function(e){

		var event = new Event(e);

		if (event.key=='space'){

			event.stop();

		}

	},



	blurvalidate: function(el){

		el.value = this.trim(el);

		return this.validate(el, true);	

	},

	

	validate: function(el, bValidateMinLength){

		var valid = true;

		var regEmail = /^[^@]+@[^@.]+\.[^@]*\w\w$/;

		var regNum = (el.getProperty('allowblanks')=='true') ? /^[0-9 ]+$/ : /^[0-9]+$/;

		var regPhoneNum = /^[0-9 ]+$/;

		var regAlpha = (el.getProperty('allowblanks')=='true') ? /^([a-zA-Z ]+)$/ : /^([a-zA-Z]+)$/;

		var regAlphaNum = (el.getProperty('allowblanks')=='true') ? /^([a-zA-Z0-9 ]+)$/ : /^([a-zA-Z0-9]+)$/;

		// 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 regUKPostCode = /^([A-Za-z]{1,2})([0-9]{1,2})([A-Za-z]{0,1})([ ]{0,1})([0-9]{1})([A-Za-z]{2})$/;

		

		var strEmailNonValidMsg = 'Please enter a valid email address';

		var strNumNonValidMsg = 'Please enter numbers only';

		var strPhneNumNonValidMsg = 'Please enter a valid phone using only numbers and spaces';

		var strAlphaNonValidMsg = 'Please enter letters only';

		var strAlphaNumNonValidMsg = 'Please enter letters or numbers only';

		var strPostCodeNonValidMsg = 'Please enter a valid postcode';

		var strRadioBtnNonValidMsg = 'Please select an option';

		

		

		if(el.getProperty('validationrequired')=='true' || el.getProperty('validationrequired')=='false'){

			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}$/;

							if(el.value.toUpperCase().match(regEmail)){

								valid = true;

								this.clearMsg(el);

							}else if (el.getProperty('validationrequired')=='true'){

								valid = false;

								this.setMsg(el, strEmailNonValidMsg);

							}else if (el.getProperty('validationrequired')=='false'){

								valid = (el.value == '')

							}else{

								valid = true;

							}

							if (valid){

								this.clearMsg(el);

							}else{

								this.setMsg(el, strEmailNonValidMsg);

							}

						}

						

						if(el.getProperty('validationdatatype')=='numeric'){

//							var regNum = /^\d+$/;

							if(el.value.match(regNum)){

								valid = true;

								this.clearMsg(el);

							}else if (el.getProperty('validationrequired')=='true'){

//							}else{

								valid = false;

								this.setMsg(el, 'Please enter numbers only');

							}else if (el.getProperty('validationrequired')=='false'){

								valid = (el.value == '')

							}else{

								valid = true;

							}

							if (valid){

								if (bValidateMinLength){

									if(!this.validateminlength(el)){

										valid = false;

										this.setMsg(el, 'Please enter at least '+ el.getProperty('minlength') +' numerals');

									}

								}else{

									this.clearMsg(el);

								}

							}else{

								this.setMsg(el, strNumNonValidMsg);

							}

						}

	

						if(el.getProperty('validationdatatype')=='phonenumber'){

							if(el.value.match(regPhoneNum)){

								valid = true;

								this.clearMsg(el);

							}else if (el.getProperty('validationrequired')=='true'){

								valid = false;

								this.setMsg(el, 'Please enter a valid phone using only numbers and spaces');

							}else if (el.getProperty('validationrequired')=='false'){

								valid = (el.value == '')

							}else{

								valid = true;

							}

							if (valid){

								if (bValidateMinLength){

									if(!this.validateminlength(el)){

										valid = false;

										this.setMsg(el, 'Please enter at least '+ el.getProperty('minlength') +' numerals');

									}

								}else{

									this.clearMsg(el);

								}

							}else{

								this.setMsg(el, strNumNonValidMsg);

							}

						}

	

						if(el.getProperty('validationdatatype')=='alpha')

						{

							if(el.value.match(regAlpha)){

								valid = true;

							}else if (el.getProperty('validationrequired')=='true'){

								valid = false;

							}else if (el.getProperty('validationrequired')=='false'){

								valid = (el.value == '')

							}else{

								valid = true;

							}

							if (valid){

								if (bValidateMinLength){

									if(!this.validateminlength(el)){

										valid = false;

										this.setMsg(el, 'Please enter at least '+ el.getProperty('minlength') +' letters');

									}

								}else{

									this.clearMsg(el);

								}

							}else{

								this.setMsg(el, strAlphaNonValidMsg);

							}

						}

	

						if(el.getProperty('validationdatatype')=='alphanumeric'){

							if(el.value.match(regAlphaNum)){

								valid = true;

							}else if (el.getProperty('validationrequired')=='true'){

								valid = false;

							}else if (el.getProperty('validationrequired')=='false'){

								valid = (el.value == '')

							}else{

								valid = true;

							}

							if (valid){

								if (bValidateMinLength){

									if(!this.validateminlength(el)){

										valid = false;

										this.setMsg(el, 'Please enter at least '+ el.getProperty('minlength') +' letters or numbers');

									}

								}else{

									this.clearMsg(el);

								}

							}else{

								this.setMsg(el, strAlphaNumNonValidMsg);

							}

						}

						if(el.getProperty('validationdatatype')=='ukpostcode'){

							if(el.value.match(regUKPostCode)){

								valid = true;

								this.clearMsg(el);

							}else if (el.getProperty('validationrequired')=='true'){

								valid = false;

								this.setMsg(el, 'Please enter a valid postcode');

							}else if (el.getProperty('validationrequired')=='false'){

								valid = (el.value == '')

							}else{

								valid = true;

							}

							if (valid){

								this.clearMsg(el);

							}else{

								this.setMsg(el, strAlphaNumNonValidMsg);

							}

						}

						if(el.getProperty('validationdatatype')=='date'){

							var formats = new Array( this.options.dateFormat );

							var passed = false;

							if( this.options.dateFormatSeparator != null ){

								var formats = this.options.dateFormat.split( this.options.dateFormatSeparator );

							}

							for(var i = 0; i < formats.length; i++ ){

								var d = Date.parseExact(el.value, formats[i]);

								if( d!= null){

									passed = true;

									break;

								}

							}

							if(passed){

								valid = true;

								this.clearMsg(el);

							}else if (el.getProperty('validationrequired')=='true'){

								valid = false;

								var msg = 'Please enter a valid date in the format(s): ';

								for(var i = 0; i < formats.length; i++ ){

									msg += formats[i];

									if( i < formats.length -1 ) msg += ', ';

								}

								this.setMsg(el, msg.toLowerCase() );

							}else if (el.getProperty('validationrequired')=='false'){

								valid = (el.value == '')

							}else{

								valid = true;

							}

							if (valid){

								this.clearMsg(el);

							}else{

								var msg = 'Please enter a valid date in the format(s): ';

								for(var i = 0; i < formats.length; i++ ){

									msg += formats[i];

									if( i < formats.length -1 ) msg += ', ';

								}

								this.setMsg(el, msg.toLowerCase() );

							}

						}

					break;

					

				case 'checkbox':

					if(el.getProperty('validationrequired')=='true'){

						valid = el.checked;

						if (valid){

							this.clearMsg(el);

						}else{

							this.setMsg(el);

						}

						break;

					}

				case 'radio':

					if(el.getProperty('validationrequired')=='true'){

						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.clearMsg(rad.getLast());

						}else{

							this.setMsg(rad.getLast(), strRadioBtnNonValidMsg);

						}

						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);
						
						if(c < (val.length - 1))
						{
							newVal = newVal+' ';	
						}

					}

					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();

});




