
var mooValidate = new Class({
	
	getOptions: function(){
		return {
			validateOnBlur: true,
			errorClass: 'error',
			errorMsgClass: 'errorMessage',
			dateFormat: 'dd/MM/yy',
			onFail: false,
			onSuccess: true,
			showErrorsInline: true,
			showErrorsListClass: 'errorUL',
			label: 'please wait...',
			
			text: 'Required field',
			password: 'Required field',
			radio: 'Required field',
			checkbox: 'Required field',
			select: 'Required field',
			file: 'Required field',
			
			url: false,
			updater: 'updater'
		};
	},
	
	onSuccess: function(fm) {
		
		var button = fm.getElement('input[type=submit]');
		button.store('oldValue', button.get('value'));
		var url = (this.options.url) ? this.options.url : $('url').value;
		
		var req = new Request.HTML({
			method: 'post',
			url: url,
			data:fm.toQueryString()+'&tkn='+Math.random(),
			update:$(this.options.updater),
			onRequest: function() {
				loader.inject($('content'), 'top');
				button.setProperty('value',this.options.label);
				button.setProperty('disabled', true);
			}.bind(this),
			onComplete: function() {
				loader.dispose();
				button.setProperty('value',button.retrieve('oldValue'));
				button.setProperty('disabled', false);
			}
		}).send();
	},
	onFail: function(list) {
		
	},
	
	
	initialize: function(form, options){
		
		this.setOptions(this.getOptions(), options);
		
		this.form = $(form);
		this.elements = this.form.getElements('.required');
		this.list = [];
		
		/* on blur */
		if (this.options.validateOnBlur)
		{
			this.elements.each(function(el){
				el.addEvent('blur', function(e){
					this.validate(el);
					this.validateEqual(el);
					this.ulList();
				}.bind(this));
			}.bind(this));
		}
		
		/* on submit */
		this.form.addEvent('submit', function(e){
			
			var event = new Event(e);
			var doSubmit = true;
			this.elements.each(function(el) {
				
				if((!this.validate(el)) || (!this.validateEqual(el)))
				{
					event.stop();
					doSubmit = false;
				}
			}.bind(this));
			
			if (doSubmit)
			{
				if (this.options.onSuccess)
				{
					event.stop();
					this.onSuccess(this.form);
				}
				else
				{
					this.form.getElement('input[type=submit]').setProperty('value',this.options.label);
				}
			}
			else
			{
				this.ulList();
				if (this.options.onFail)
				{
					this.onFail(this.form);
				}
			}
			
		}.bind(this));
		
	},
	
	validateEqual: function(el) {
		
		this.valid = true;
		this.equal_val = null;
		if (el.hasClass('equal'))
		{
		$$('.equal').each(function(x){
			
			if (this.equal_val == null)
			{
				this.equal_val = x.get('value');
			}
			
			if (this.equal_val != x.get('value')) 
			{
				this.valid = false;
			}
		}.bind(this));
		
		if (!this.valid)
		{
			if (!$chk($('error-email-not-equal')))
			{
				var li = new Element('li').set('id', 'error-email-not-equal');
				var label = new Element('label').setProperty('for', el.id).set('text', 'Email addresses must match!');
				$('updater').grab(li.grab(label));
			}
		}
		else
		{
			if ($chk($('error-email-not-equal')))
			{
				$('error-email-not-equal').dispose();
			}
		}
		
		}
		return this.valid;
	},
	
	ulList: function(){
		
		if ($chk($('error-ul')))
		{
			$('error-ul').dispose();
		}
		
		if (!this.options.showErrorsInline)
		{	
			var ulList = new Element('ul').addClass(this.options.showErrorsListClass).set('id', 'error-ul');
			
			var tlist = [];
			this.list.each(function(el)
			{
				var li = new Element('li');
				var label = new Element('label').setProperty('for', el.id).set('text', this.getElementTitle(el));
				
				if (!tlist.contains(el.name))
				{
					ulList.grab(li.grab(label));
					tlist.include(el.name);
				}
				
			}.bind(this));
			
			ulList.inject(this.form, 'top');
		}
	},
	
	getElementTitle: function(el){
		if ($chk(el.title))
		{
			return el.title;
		}
		else
		{
			return this.options[el.type];
		}
	},
	
	validate: function(el){
		
		var valid = true;
		
		if (el.type == 'radio')
		{
			var lrad = $A(this.form[el.name]);
			this.clearMsg(lrad.getLast());
		}
		else
		{
			this.clearMsg(el);
		}
		
		switch(el.type){
			case 'file':
			case 'text':
			case 'password':
			case 'textarea':
			case 'select-one':
				if(el.value != ''){
					
					if(el.hasClass('email')){
						var regEmail = /^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/;
						if(el.value.toUpperCase().match(regEmail)){
							valid = true;
						}else{
							valid = false;
							this.setMsg(el, 'Please provide correct e-mail address!');
						}
					}
					
					if (el.hasClass('username')){
						var regAN = /^[A-Z0-9_]{4,20}$/;
						if (el.value.length < 4 || el.value.length > 20)
						{
							valid = false;
							this.setMsg(el, 'Username must be from 4 to 20 letters!');
						}
						else if (el.value.toUpperCase().match(regAN)){
							valid = true;
						}else{
							valid = false;
							this.setMsg(el, 'Please provide alphanumeric expression!');
						}
						
					}
					
					if (el.hasClass('aphanumeric')){
						var regAN = /^[A-Z0-9_]{0,1000}$/;
						
						if (el.value.toUpperCase().match(regAN)){
							valid = true;
						}else{
							valid = false;
							this.setMsg(el, 'Please provide alphanumeric expression!');
						}
					}
					
					if(el.hasClass('integer')){
						var regNum = /^\d+$/;
						var result = el.value.match(regNum);
						if(result){
							valid = true;
						}else{
							valid = false;
							this.setMsg(el, 'Please provide integer number!');
						}
					}
					
					
					if(el.hasClass('number')){
						var regNum = /[-+]?[0-9]*\.?[0-9]+/;
						
						if(el.value.match(regNum)){
							
							valid = true;
						}else{
							valid = false;
							this.setMsg(el, 'Please provide number!');
						}
					}
					
					if(el.hasClass('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;
						}else{
							valid = false;
							this.setMsg(el, 'Please provide correct postcode!');
						}
					}
					
					if(el.hasClass('date')){
						var d = Date.parseExact(el.value, this.options.dateFormat);
						if(d != null){
							valid = true;
						}else{
							valid = false;
							this.setMsg(el, 'Please provide correct date 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;
				}
				break;
				
			case 'radio':
				var rad = $A(this.form[el.name]);
				var ok = false;
				rad.each(function(e,i){
					if(e.checked){
						ok = true;
					}
				});
				if(!ok){
					valid = false;
					this.setMsg(rad.getLast(), 'Please select an option!');
				}else{
					valid = true;
					this.clearMsg(rad.getLast());
				}
				break;
				
		}
		
		if (!this.options.showErrorsInline) {
			if (valid) {
				this.list.erase(el);
			}
			else
			{
				this.list.include(el);
			}
		}
		return valid;
	},
	
	setMsg: function(el, msg){
		
		if (msg == undefined)
		{
			msg = this.getElementTitle(el);
		}
		if (this.options.showErrorsInline){
			
			el.error = new Element('span').addClass(this.options.errorMsgClass).set('text', msg);
			el.error.inject(el.getParent(), 'bottom');
			el.addClass(this.options.errorClass);
		}
	},
	
	clearMsg: function(el){
		
		el.removeClass(this.options.errorClass);
		if($chk(el.error)){
			el.error.dispose();
		}
	}
});

mooValidate.implement(new Options);
mooValidate.implement(new Events);


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

