var iRules = {
	name:{
		regex: /^.{3,128}$/,
		msg: 'Puede contener sólo números, letras y espacios.'
	},
	title:{
		regex: /^.{3,128}$/,
		msg: 'Puede contener números y letras.'
	},
	mail:{
		regex: /^([\w\d_\.\-])+\@(([\w\dÃ¡Ã©Ã­óúÃ±\-])+\.)+([\w\d]{2,4})+$/,
		msg: 'Ejemplo: usuario@dominio.com'
	},
	password:{
		regex: /^[\w\d]{3,18}$/,
		msg: 'Debe contener sólo números y letras.',
		notOneOf : ['123','1234567','0123456','12345678']
	},
	password_ya_reg:{
		regex: /^[\w\d]{3,18}$/,
		msg: 'Debe contener sólo números y letras.'
	},
	telephone:{
		regex: /^[\d()+\- ]{7,24}$/,
		msg: 'Ejemplos: 425-2354 , 051(511) +01 254 25402'
	},
	number:{
		regex: /^\d+$/,
		msg: 'Debe contener sólo numeros.'
	},
	character:{
		regex: /^[\w\d]$/,
		msg: 'Coincide con un caracter.'
	},
	content:{
		regex: /^(\s|.){3,}$/,
		msg: 'Mínimo 3 caracteres.'
	},
	content1:{
		regex: /^(\s|.){3,50}$/,
		msg: 'Mínimo 3 caracteres y máximo 50 caracteres.'
	},
	
	wysiwyg:{
		regex: /^(\s|.){20,}$/,
		msg: 'Mínimo 20 caracteres.'
	},
	fecha:{
		regex: /^[\d]{4}-[\d]{2}-[\d]{2}$/,
		msg: 'Ejemplo: 2001/02/10'
	},
	ruc:{
		regex: /^[\d]{11}$/,
		msg: 'Número de RUC: 50000000000'
	},
	dni:{
		regex: /^[\d]{8}$/,
		msg: 'Número de DNI: 44444444'
	},
	date:{
		regex: /^[\wÃ¡Ã©]{3,12} [\d]{1,3} [\w]{3,12} de [\d]{4}$/,
		msg: 'Ejemplo: Martes 06 Febrero de 2001'
	},
	hour:{
		regex: /^([0-9]|[0-1][0-9]|2[0-3]):[0-5]0$/,
		msg: 'Sólo intervalos de 10 minutos.<br /><b>Ejemplos</b>: 16:20, 00:40, 8:50, 13:00'
	},
	bool:{
		regex: /^0|1$/,
		msg: 'Debe elegir una de las opciones.'
	},
	image:{
		regex: /\.(jpg|jpeg|gif|png)$/i,
		msg: 'Debe elegir archivos de tipo imagen.'
	},
	multiple:{
		regex: /^\d+$/,
		msg: 'Debe agregar una o mÃ¡s opciones.'
	},
	multiple2:{
		regex: /^\d+$/,
		msg: 'Debe agregar una o mÃ¡s opciones.'
	},
	select:{
		regex: /^.+$/,
		msg: 'Debe seleccionar una de las opciones.'
	},
	radiob:{
		regex: /^.+$/,
		msg: 'Debe hacer click una de las opciones.'
	},
	radion:{
		regex: /^.+$/,
		msg: 'Debe hacer click una de las opciones.'
	},
	radiof:{
		regex: /^.+$/,
		msg: 'Debe hacer click una de las opciones.'
	},
	pdf:{
		regex: /\.pdf$/i,
		msg: 'Debe seleccionar un archivo tipo PDF.'
	}
};

var iValidator = new Class({
	Implements: Options,

	options:{
		focus: 'focus',
		valid: 'valid',
		invalid: 'invalid',
		norequired: 'norequired',
		blink: 'blink',
		maxlength: true
	},

	initialize: function(inputs,options){
		this.setOptions(options);
		this.inputs = inputs ;
		for(var i=0;i<this.inputs.length;i++){
			this.inputs[i].addEvents({focus:this.focus.bind(this),blur:this.blur.bind(this)});
			if(this.options.maxlength && this.inputs[i].getAttribute('maxlength') && this.inputs[i].getTag()=='textarea'){
				this.inputs[i].addEvent('keyup',function(){
					var maxlength = this.getAttribute('maxlength').toInt();
					if(this.value.length > maxlength){
						this.value = this.value.substr(0,maxlength);
					}
				});
			}
		}
	},

	focus: function(e){
		if(!this.disabled){
			this.stopBlink();
			this.hideTip();
			new Event(e).target.getParent().
			removeClass(this.options.blink).
			removeClass(this.options.valid).
			removeClass(this.options.invalid).
			addClass(this.options.focus);
		}
	},

	blur: function(e){
		if(!this.disabled){
			var input = new Event(e).target;
			var ruleName = input.className.split(' ')[0];
			var rule = iRules[ruleName];
			var parent = input.getParent().
			removeClass(this.options.blink).
			removeClass(this.options.focus).
			removeClass(this.options.valid).
			removeClass(this.options.invalid);
			if(input.getAttribute('multiple')){
				if(ruleName=='multiple2'){
					if(input.options.length==0 && !input.hasClass('norequired')){
						parent.addClass(this.options.invalid);
					}else{
						parent.addClass(this.options.valid);
					}
				}
			}else{
				var ok = false;
				if(rule.notOneOf && (rule.notOneOf.indexOf(input.value) < 0) && input.value.test(iRules[ruleName].regex)){
					ok = true;
				}else{ 
					if(!rule.notOneOf && input.value.test(iRules[ruleName].regex)){
						ok = true;
					}
				}
				parent.addClass((input.value=='' && input.hasClass(this.options.norequired) || ok ) ? this.options.valid : this.options.invalid);
			}
			this.stopBlink();
			this.hideTip();
		}
	},

	isChildType: function(el) {
		return ($defined(el.type) && el.type == 'radio') ? true : false;
	},
	
	validateGroup : function(el) {
		nombre = el.getProperty("name");
	 	var cbCheckeds = false
	 	
		for(var j=0;j<this.inputs.length;j++){
			if(this.inputs[j].name == nombre){
				if(this.inputs[j].checked){
					cbCheckeds = true;	
					break;
				}
			}
		}
		if(cbCheckeds == false) {
			return false;
		} else {
			return true;	
		}
		
		
	},


	
	test: function(background){
		
		if(!this.disabled){
			
			this.status = true;
			this.errors = {};
			this.stopBlink();
			this.hideTip();
			for(var i=0;i<this.inputs.length;i++){
				
				var parent = this.inputs[i].getParent();
				if(!background){
					parent.
					removeClass(this.options.blink).
					removeClass(this.options.valid).
					removeClass(this.options.invalid).
					removeClass(this.options.focus);
				}
				var ruleName = this.inputs[i].className.split(' ')[0];
				var rule = iRules[ruleName];
				if(this.isChildType(this.inputs[i])) {
					if (this.validateGroup(this.inputs[i]) == false) {
							if(!background){
								 parent.addClass(this.options.invalid);
							} 
							this.errors[this.inputs[i].name] = rule.msg;
							this.status=false;
						}

					
				}else{

					if(this.inputs[i].getAttribute('multiple')){
						if(ruleName=='multiple2'){
							if(this.inputs[i].options.length==0 && !this.inputs[i].hasClass('norequired')){
								parent.addClass(this.options.invalid);
								this.errors[this.inputs[i].name] = rule.msg;
								this.status=false;
							}else{
								parent.addClass(this.options.valid);
							}
						}
					}else{
						
						if((this.inputs[i].getProperty('invalid') && this.inputs[i].getProperty('invalid')=='1') ||(this.inputs[i].value!='' || !this.inputs[i].hasClass(this.options.norequired)) && (!this.inputs[i].value.test(rule.regex) && !rule.notOneOf) || (rule.notOneOf && rule.notOneOf.indexOf(this.inputs[i].value) >= 0)){
							if(!background){
								parent.addClass(this.options.invalid);
							}
							this.status=false;
							if(this.inputs[i].getTag()=='select' && !this.inputs[i].getAttribute('multiple')){
								this.errors[this.inputs[i].name] = 'Debe seleccionar una de las opciones.';
							}else{
								
									this.errors[this.inputs[i].name] = rule.msg;
								
							}
						}else if(!background){
							parent.addClass(this.options.valid);
						}
					}
				}
			}
			return this.status;
		}else{
			return null;
		}
	},

	showInvalid: function(blink,tip,showName){
		if(blink!=true){ blink=false; }
		if(tip!=true && $type(tip)!='object'){ tip=false; }
		for(var i=0;i<this.inputs.length;i++){
			var parent = this.inputs[i].getParent();
			if(parent.hasClass(this.options.invalid)){
				parent.
				removeClass(this.options.blink).
				removeClass(this.options.focus).
				removeClass(this.options.valid).
				removeClass(this.options.invalid);
				if(blink || tip){
					//parpadeo
					if(blink){
						parent.addClass(this.options.blink);
						this.blinker={
							index: i,
							timer: parent.toggleClass.periodical(250,parent,[this.options.blink])
						};
					}
					//tip
					if(tip){
						this.showTip(this.inputs[i],tip,showName);
					}
				}else{
					this.inputs[i].focus();
				}
				window.scrollTo(0,parent.getPosition().y-30);
				break;
			}
		}
	},
	
	showTip: function(input,pos,showName){
		pos = $merge({x:-230,y:-24},pos);
		if(input.getTag()=='select' && !input.getAttribute('multiple')){
			var msg = 'Debe seleccionar una de las opciones.';
		}else{
			var msg = iRules[input.className.split(' ')[0]].msg;
		}
		if(!$defined(showName) || showName==true){
			var title = '<h3>'+input.name.capitalize()+'</h3>';
		}else if(showName==false){
			var title = '';
		}else{
			var title = '<h3>'+(showName==true ? input.name.capitalize() : showName)+'</h3>';
		}
		//
		this.tip = new Element('div',{'class':'iVtip'}).setOpacity(0).setHTML('<div>'+title+'<p>'+msg+'</p></div><div class="foot"></div>').inject(document.body);
		var position = input.getPosition();
		this.tip.setStyles({'left':(position.x+pos.x)+'px','top':(position.y+pos.y)+'px'});
		new Fx.Tween(this.tip,'opacity').start(1);
	},

	hideTip: function(){
		if(this.tip){
			this.tip.remove();
			this.tip = false;
		}
	},

	stopBlink: function(){
		if(this.blinker){
			$clear(this.blinker.timer);
			this.inputs[this.blinker.index].getParent().removeClass(this.options.blink);
			delete this.blinker;
		}
	},
	
	displayErrors: function(box,extra){
		var error = '';
		for(var i in this.errors){
			error += '- '+i.capitalize()+': '+this.errors[i]+'\n';
		}
		if(error!=''){
			var errors = this.errors;
			if(extra){
				errors = $merge(errors,extra);
			}
			if(box){
				box.empty();
				new Element('h3').setText('Debe corregir los datos de los siguientes campos:').inject(box);
				var list = new Element('ul').inject(box);
				for(var i in errors){
					new Element('li').setHTML('<b>'+i.capitalize()+'</b>: '+errors[i]).inject(list);
				}
			}else{
				alert('Debe corregir los datos de los siguientes campos:\n\n'+error);
			}
		}
	}

});
