/*
TODO:
	Revisar las validaciones que hay en real y añadirlas a mis validaciones

*/
Base.ValidadorFormulario = Class.create();
Base.ValidadorFormulario.prototype  = {
	constantes: {
		listaValidaciones: new Array(),
		listadoErrores: new Array()
	},
	initialize: function(controladorInterfaz){ with(this) {
		this.controladorInterfaz = controladorInterfaz;
	}},
	enCamposDeFormulario: function (formulario) { with(this) {
		recorreValidacionesDeCadaCampoDeFormulario(formulario);
		return this;
	}},
	enBotonDeEnvioDeFormulario: function (formulario) { with(this) {
		return this;
	}},
	recorreValidacionesDeCadaCampoDeFormulario: function (formulario) { with(this) {
		var reglasValidacion = $$(generaSelectorDeReglasDeValidacion(formulario));
		reglasValidacion.each( function (regla) {
			almacenaListaDeValidaciones(regla).Y().almacenaErroresPorDefecto(regla).insertaValidacionEnCadaCampo(sacaCampo(regla))
			
		},this);
		reglasValidacion = null;
		return this;
		//recorro las regals de validacion y voy insertando la validacion en sus campos
	}},
	generaSelectorDeReglasDeValidacion: function (formulario) { with(this) {
		return (Base.Selectores.Validaciones.General + ' ' + '.'+formulario.id + ' ' + Base.Selectores.Validaciones.ReglaValidacion);
	}},
	almacenaListaDeValidaciones: function (regla) { with(this) {
		constantes.listaValidaciones.push({
			campo: regla.getElementsByTagName('h2')[0].getElementsByTagName("span")[0].innerHTML,
			validaciones: sacaValidaciones(regla)
		})
		return this;
	}},
	sacaValidaciones: function(regla) { with(this) {
		var validaciones = new Array();
		var opcionesValidacion;
		$A(regla.getElementsByTagName('li')).each( function (tipoValidacion) {
			validaciones.push(sacaOpcionesDeValidacion(tipoValidacion));
		},this)
		return validaciones;
	}},
	sacaCampo: function(regla) { with(this) {
		return ($(regla.getElementsByTagName('h2')[0].getElementsByTagName("span")[0].innerHTML));
	}},
	sacaOpcionesDeValidacion: function (tipoValidacion) { with(this) {
		var opcionesValidacion = {};
		opcionesValidacion.tipoValidacion = tipoValidacion.getElementsByTagName('span')[0].getElementsByTagName('span')[0].className;
		opcionesValidacion.valores = sacaValoresMaximoYMinimoDeValidacion(tipoValidacion)//tipoValidacion.getElementsByTagName('span')[1].getElementsByTagName('span');
		
		//TODO CUANDO EL TIPO DE VALIDACION SEA DE ESTAR COMPRENDIDO ENTRE DOS VALORES
		return opcionesValidacion;
	}},
	sacaValoresMaximoYMinimoDeValidacion: function (tipoValidacion) { with(this) {
		var valores = {};
		if (tipoValidacion.getElementsByTagName('span')[2]){
			if(tipoValidacion.getElementsByTagName('span')[2]){
				if(Element.hasClassName(tipoValidacion.getElementsByTagName('span')[2], Base.Clases.Validaciones.Valores)){
					$A(tipoValidacion.getElementsByTagName('span')[2].getElementsByTagName("span")).each ( function (valor) {
					if (Element.hasClassName(valor,'menor'))
						valores.menor = valor.innerHTML;
					else
						valores.mayor = valor.innerHTML;
				});
			}
			}
		}
		return valores;
	}},
	almacenaErroresPorDefecto: function (regla) { with(this) {
		var campo = sacaCampo(regla);
		var validacionesDelCampo = sacaValidaciones(regla);
		almacenaError(validacionesDelCampo, campo);
		return this;
	}},
	almacenaError: function (validacionesDelCampo, campo) { with(this) {
		var error = {
			nombreCampo: campo.id,
			validacionesDelCampo: validacionesDelCampo
		};
		almacena().errorEnListadoDeErrores(constantes.listadoErrores, error);
	}},	almacenaError: function (validacionesDelCampo, campo) { with(this) {
		var error = {
			nombreCampo: campo.id,
			validacionesDelCampo: validacionesDelCampo
		};
		almacena().errorEnListadoDeErrores(constantes.listadoErrores, error);
	}},
	insertaValidacionEnCadaCampo: function (campo) { with(this) {
		if (esUnCampoSelect(campo))
			Event.observe(campo, 'change', validaCampo.bind(this), false);
		else
			Event.observe(campo, 'keyup', validaCampo.bind(this), false);
		return this;
	}},
	esUnCampoSelect: function (campo) { with(this) {
		return (campo.tagName == "SELECT");
	}},
	validaCampo: function (event){ with(this) {
		Event.stop(event);
		var campo = Event.element(event);
		var validacionesDelCampo = busca().validacionesDelCampo(campo.id, constantes.listaValidaciones);
		if (validaElCampo(validacionesDelCampo, campo)){
			informaDeQueElCampoHaValidado(validacionesDelCampo, campo);
		}
		else {
			informaDeQueElCampoNoHaValidado(validacionesDelCampo, campo);
		}
		return this;
	}},
	validaElCampo: function (validacionesDelCampo,campo) { with(this) {
		return (valida().campoDeFormulario(validacionesDelCampo,campo));

	}},
	informaDeQueElCampoNoHaValidado: function (validacionesDelCampo, campo) { with(this) {
		almacenaError(validacionesDelCampo, campo);
		muestra().campoErroneo(campo).Y().errorSinTachar(campo.id);
	}},
	informaDeQueElCampoHaValidado: function (validacionesDelCampo, campo) { with(this) {
		borra().errorEnListadoDeErrores(campo.id)
		muestra().campoValido(campo).Y().errorTachado(campo.id);
	}},
	enBotonDeEnvioDeFormulario	: function (formulario) { with(this) {
		this.formulario = formulario;
		var boton = $$('#'+ formulario.id + ' ' + Base.Selectores.Formulario.BotonEnvio)[0];
		Event.observe(boton, 'click', validaFormulario.bind(this), false);
	
	}},
	validaFormulario: function (event) { with(this) {
		var boton = Event.element(event);
		if (hayErroresDeValidacion()){
			muestra().erroresDeFormulario(constantes.listadoErrores, formulario).Y().camposErroneos(constantes.listadoErrores, formulario);
			Event.stop(event);
		}
		
	}},
	hayErroresDeValidacion: function () {with(this) {
		return (busca().numeroDeErroresDeValidacion(constantes.listadoErrores) > 0)
	}},
	muestra: function () {
		return this.controladorInterfaz.muestra();
	},
	busca: function () {
		return this.controladorInterfaz.busca();
	},
	valida: function () {
		return new Base.Validaciones(this);
	},
	almacena: function () {
		return this.controladorInterfaz.almacena();
	},	
	borra: function () {
		return this.controladorInterfaz.borra(this);
	},
	Y: function () {
		return this;
	}
}

Base.Validaciones = Class.create();
Base.Validaciones.prototype = {
	initialize: function (ValidadorFormulario) {
		this.ValidadorFormulario = ValidadorFormulario;
	},
	campoDeFormulario: function (validaciones,campo) { with(this) {
		return lanzaValidaciones(validaciones,campo);
	}},
	lanzaValidaciones: function (validaciones,campo) { with(this) {
		var esValido = true;
		validaciones.each( function (validacion) {
			switch(validacion.tipoValidacion) {
				case Base.Contantes.TiposValidaciones.Obligatorio:
				  esValido = validaCampoObligatorio(campo);
					break;    
				case Base.Contantes.TiposValidaciones.Texto:
					esValido = validaCampoTexto(campo);
					break;    
				case Base.Contantes.TiposValidaciones.Numerico:
					esValido = validaCampoNumero(campo);
					break;    
				case Base.Contantes.TiposValidaciones.Fecha:
					esValido = validaCampoFecha(campo);
					break;
				case Base.Contantes.TiposValidaciones.EntreValores:
					esValido = validaCampoEntreValores(campo, validacion.valores);
					break;
			}
			if (!esValido)
				throw $break;
		},this)
		return esValido;
		return this;
	}},
	validaCampoObligatorio: function (campo) { with(this) {
		if(esUnCampoSelect(campo)){
			return (campo.selectedIndex != 0);
		}else{
			return (campo.value != "");
		}
		
	}}, 
	esUnCampoSelect: function (campo) { with(this) {
		return (campo.tagName == "SELECT");
	}},
	validaCampoTexto: function (campo) {
		return (isNaN(campo.value));
	}, 
	validaCampoNumero: function (campo) { with(this) {
		if (esUnNumeroDecimal(campo))
			return true;
		else
			return (!isNaN(campo.value));
	}}, 
	esUnNumeroDecimal: function (campo) { with(this) {
		if (campo.value.indexOf(",") != -1 && campo.value.indexOf(",") != 0 && campo.value.split(",").length < 3){
			var validado = true;
			campo.value.split(",").each( function (cadenaNumeros) {
				if (isNaN(cadenaNumeros)){
					validado =  false;
					throw $break;
				}
			})
			return validado;
		}else
			return false;
	}},
	validaCampoFecha: function (campo) {
		//TODO VALIDACION FECHA
		return (campo.value != "");
	},
	validaCampoEntreValores: function (campo, valores) { with(this) {
		if (validaCampoNumero(campo)){
			if (valores.mayor && valores.menor)
				return ((parseInt(campo.value) < parseInt(generaValor(valores.mayor))) && (parseInt(campo.value) > parseInt(generaValor(valores.menor))))
			else if (valores.mayor)
				return (parseInt(campo.value) < parseInt(generaValor(valores.mayor)));
			else if (valores.menor)
				return (parseInt(campo.value) > parseInt(generaValor(valores.menor)));
		}
		else
			return false
	
	}},
	generaValor: function (valor) { with(this) {
		if (esUnIdentificadorDeCampo(valor))
			return $(valor).value;
		else
			return valor;
	}},
	esUnIdentificadorDeCampo: function (id) {
		return ($(id));
	}
}

/*
1.	Existe un microformato con un div class="validacionesDeFormulario" que engloba las validaciones del formulario
2. 	El Id del formulario se encuentra dentro de la etiqueta span del H1
3. 	Cada regla de validacion esta comprendida entre divs con clase "reglaValidacion"
4. 	El nombre del campo al que se aplica la regla se encuentra en la etiqueta span del H2
5. 	Los tipos de validacion de los campos se encuentra en las etiquetas LI de la lista ul de validaciones
6. 	El tipo de validación en concreto de cada lista se encuentra en la etiqueta span con clase tipoValidacion
7. 	Caso de tipos de validaciones complejas:
		a)	Tipo de validación "Comprendido entre dos valores":
				Los dos valores entre los que tiene que estar comprendido son menor y mayor y estos se encuentran en las etiqueta span con clase "valores"
					a)	el valor menos esta en la etiqueta span con clase "menor"
					b)	el valor mayo está en la etiqueta span con clase "mayor"




*/
