/*
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ---- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
   Validación de formularios
   version:  d08-m06-a06
//  -- -- -- -- -- -- -- -- --
//  Mauricio F. Tolezano (www.acuataller.com)
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- ---- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
// 
//
*/


com.acuataller.ValidarFormulario = function( rv, ef ) 
{
	this.reglasValidacion	= rv;
	this.errorEnvio			= ef;
	
	// Bandera para pasar por alto la validacion
	this.anularValidacion	= false;	
	
	// Bandera para evitar recursion exesiva
	// cuando se valida un grupo de campos
	this.revalidandoGrupo	= false;
	
	// Guarda los id de los campos que se han 
	// validado y contienen datos invalidos.
	
	this.camposInvalidos	= [];	
	
	
	this._asignarEventos();
}


com.acuataller.ValidarFormulario.prototype._asignarEventos = function() 
{
	var eventoSubmit = false;
	for (var idCampo in this.reglasValidacion) 
	{
		var campo = document.getElementById( idCampo ); 
		if(campo)
		{
			this._asignarEvento(campo, 'blur', this._validarCampo, false);
			this._asignarEvento(campo, 'focus', this._validarCampo, false);
			if(!eventoSubmit){
				var formulario = campo.form;
				this._asignarEvento(formulario, 'submit', this._validarCampos, false);
				// PARCHE para recuoerar el Scope de esta clase
				campo.form.vf = this;
				eventoSubmit = true;
			}
		}
	}	
}


com.acuataller.ValidarFormulario.prototype._validarCampo = function( e, c ) 
{
	var campo = (c)? c : window.event ? window.event.srcElement : e ? e.target : null;  
	if (!campo) return;
	
	
	// PARCHE
	var vf 	= campo.form.vf; // PARCHE Scope, recuperando el scope de esta clase.	
	
	// Bandera para validar tambien en el evento focus del campo.
	// var validarOnFocus = false;
	
	
	var evento = (e)? e : window.event;
	if(	evento 
		&& 
		evento.type == 'focus'
		&&
	  	!vf.camposInvalidos[campo.id]
	   	)
	{
		if (e && e.stopPropagation && e.preventDefault) {
			e.stopPropagation();
			e.preventDefault();
		}
		if (window.event) {
			window.event.cancelBubble = true;
			window.event.returnValue = false;			
		}
		return false;
	};
	
	var campoValido;	
	var campoObligatorio = vf._comprobarCampoObligatorio(campo);	
	if(!campoObligatorio){ 	//  && !validarOnFocus
		vf._errorCampoObligatorio(campo);				
		campoValido = false;
	}else{ 
		var campoValido = vf._comprobarValorCampo(campo);
		if(!campoValido){
			vf._errorCampoInvalido(campo);
		}else{
			vf._borrarError(campo);
		}		
	}
	
	vf._campoInvalido( campo.id, !campoValido ); 
	if( !campoValido ){
		if (e && e.stopPropagation && e.preventDefault) {
			e.stopPropagation();
			e.preventDefault();
		}
		if (window.event) {
			window.event.cancelBubble = true;
			window.event.returnValue = false;		
		}
	}
	return campoValido;
}



com.acuataller.ValidarFormulario.prototype._comprobarCampoObligatorio = function( campo ) 
{
	var idCampo = campo.id;
	var reglaCampo = this.reglasValidacion[idCampo];

	if(reglaCampo && reglaCampo['obligatorio'] ) {
		 return !this._comprobarCampoVacio(campo.value);
	}
	return true;
}


com.acuataller.ValidarFormulario.prototype._comprobarCampoVacio = function( dato ) 
{
	// No permite estar vacio o contener sólo carcteres de espacios en blanco o contenier numeros.
	//return dato.match( /^\d*$|^\s+$/ ) != null;
	// Permite estar vacio o contener sólo carcteres de espacios en blanco o contenier numeros.
	//return dato.match( /^[a-zA-Z]+$|^[0-9]+$/ ) == null;
	// Campo sin datos
	if(!dato) return true;
	// No permite sólo caracteres de espacio.	
	return dato.match( /^\s+$/ ) != null;
}


com.acuataller.ValidarFormulario.prototype._comprobarValorCampo = function( campo ) 
{
	var idCampo = campo.id;
	var reglaCampo = this.reglasValidacion[idCampo];

	if(reglaCampo && reglaCampo['regla'])
	{						
		if( 
		   		reglaCampo['obligatorio']	// Campo obligatorio											
				||
				(
					!reglaCampo['obligatorio'] 	&& 			// Campo opcional. 	
					!this._comprobarCampoVacio(campo.value)	// Se valida sólo si contiene datos.
				)
			)			
		{			
			return campo.value.match(reglaCampo['regla']) != null;	
		}else{
			// Campo opcional vacio.
			return true;			
		}
	}else{
		// No existe regla de validacióm para el campo y se pasa por alto.
		return true;		
	}	
}


com.acuataller.ValidarFormulario.prototype._errorCampoObligatorio = function( campo ) 
{
	var idCampo 				= campo.id;
	var reglaCampo 				= this.reglasValidacion[idCampo];

	if(reglaCampo && reglaCampo['obligatorio']){
		this._mostrarMensaje(campo,reglaCampo['obligatorio']);	
	}
}


com.acuataller.ValidarFormulario.prototype._errorCampoInvalido = function( campo ) 
{
	var idCampo 				= campo.id;
	var reglaCampo 				= this.reglasValidacion[idCampo];

	if(reglaCampo && reglaCampo['error']){
		this._mostrarMensaje(campo,reglaCampo['error']);	
	}
}


com.acuataller.ValidarFormulario.prototype._mostrarMensaje = function( campo, mensaje ) 
{
	var idCampo 			 = campo.id;
	var idMensajeError 		 = this._idMensajeError(idCampo);
	var elementoMensajeError =  document.getElementById( idMensajeError );

	if(!elementoMensajeError) 
	{		
		elementoMensajeError = this._createElement('span');
		elementoMensajeError.id = idMensajeError;
		elementoMensajeError.className = 'mensaje';	
		var limpieza = document.createTextNode(mensaje);
		elementoMensajeError.appendChild( document.createTextNode(mensaje) );
		
		// Elemento HTML label asociado al campo .
		var etiquetaCampo = this._etiquetaCampo(campo);
		this._asignarEstilo(etiquetaCampo, 'error');
		etiquetaCampo.appendChild(elementoMensajeError);	
	}
	else if( 	elementoMensajeError.firstChild
				&&
				mensaje != elementoMensajeError.firstChild.nodeValue )
	{		
		elementoMensajeError.replaceChild( document.createTextNode( mensaje ), elementoMensajeError.firstChild );
	}
	else if( !elementoMensajeError.firstChild )
	{			
		elementoMensajeError.appendChild( document.createTextNode( mensaje ) );		
	}
	
	if(elementoMensajeError) 
	{
		this._asignarEstilo(campo, 'error')
	}
}


com.acuataller.ValidarFormulario.prototype._borrarError = function( campo ) 
{
	var idCampo 			 		  = campo.id;
	var idMensajeError 		 		  = this._idMensajeError(idCampo);	
	if( this.reglasValidacion[idCampo] ) {
		var idElementoMensajePersonaliado = this.reglasValidacion[idCampo]['idMostrar'];		
	}

	
	var elementoMensajeError =  document.getElementById( (idElementoMensajePersonaliado)?
														  	idElementoMensajePersonaliado
															: 
															idMensajeError
															);
	if(elementoMensajeError) 
	{		
		// Mensaje de error personalizado
		if( idElementoMensajePersonaliado )
		{			
			//Eliminando todo los childNodes.
			for( var i=elementoMensajeError.childNodes.length - 1; i > -1; i-- ){
				elementoMensajeError.removeChild(elementoMensajeError.childNodes[i]);
			}
			if(!this.revalidandoGrupo) this._revalidarGrupo( idElementoMensajePersonaliado );
		}
		// Mensaje de error asociado al elemento label.
		else 
		{
			var etiquetaCampo = this._etiquetaCampo(campo);	
			etiquetaCampo.removeChild(elementoMensajeError);
			this._eliminarEstilo(etiquetaCampo, 'error');				
		}
		this._eliminarEstilo(campo, 'error');
	}
}


com.acuataller.ValidarFormulario.prototype._idMensajeError = function( idCampo ) 
{
	var reglaCampo = this.reglasValidacion[idCampo];

	if(reglaCampo && reglaCampo['idMostrar'] ) 
	{
		 return reglaCampo['idMostrar'];
	}
	else
	{
		return 'vf_error_'+idCampo;
	}
}


com.acuataller.ValidarFormulario.prototype._etiquetaCampo = function(campo) 
{
	var etiquetaCampo = false;	
	var idCampo = campo.id;	
	var formulario = campo.form;	
	var etiquetas = formulario.getElementsByTagName('label');
	
	// Buscando etiqueta asociada al campo mediante "for".
	for (var i=0; i<etiquetas.length; i++) {
		if(etiquetas[i].htmlFor == idCampo){
			return etiquetas[i];
			break;			
		}		
	}	
	// Buscando etiqueta alrededor del campo.
	var elemntoHTML = campo;
	while(elemntoHTML.parentNode) {
		elemntoHTML = elemntoHTML.parentNode;	
		if(elemntoHTML.tagName.toLowerCase() == 'label'){
			return elemntoHTML;
			break;
		}
	}	
}



com.acuataller.ValidarFormulario.prototype._validarCampos = function(e) 
{
	var formulario = window.event ? window.event.srcElement : e ? e.target : null;   
	if (!formulario) return;
	// PARCHE
	var vf 	= formulario.vf; // Scope, recuperando esta clase.	
	
	if(vf.anularValidacion) return;
	
	var r = true;
	var etiquetas = formulario.getElementsByTagName('label');	
	for (var idCampo in vf.reglasValidacion) 
	{
		var campo = document.getElementById( idCampo ); 
		if(campo){
			if(r) r = vf._validarCampo(false, campo);
			if(!r) {
				campo.focus(); 
				break;
			}
		}
	}	

	if(!r){
		alert(vf.errorEnvio);		
		if (e && e.stopPropagation && e.preventDefault) {
			e.stopPropagation();
			e.preventDefault();
		}
		if (window.event) {
			window.event.cancelBubble = true;
			window.event.returnValue = false;
			return false;
		}
	}

	return r;
}

com.acuataller.ValidarFormulario.prototype._createElement = function (element) {
  if (typeof document.createElementNS != 'undefined') {
    return document.createElementNS('http://www.w3.org/1999/xhtml', element);
  }
  if (typeof document.createElement != 'undefined') {
    return document.createElement(element);
  }
  return false;
}


com.acuataller.ValidarFormulario.prototype._asignarEstilo = function(target, classValue) 
{	
	var pattern = new RegExp("(^| )" + classValue + "( |$)");	
	if (!pattern.test(target.className)) {
		if (target.className == ""){
		  target.className = classValue;
		}else{
		  target.className += " " + classValue;
		}
	}	
	return true;
}


com.acuataller.ValidarFormulario.prototype._eliminarEstilo = function(target, classValue) 
{
	var removedClass = target.className;
	var pattern = new RegExp("(^| )" + classValue + "( |$)");
	
	removedClass = removedClass.replace(pattern, "$1");
	removedClass = removedClass.replace(/ $/, "");
	
	target.className = removedClass;
	
	return true;
}	


com.acuataller.ValidarFormulario.prototype._asignarEvento = function(target, eventType, functionRef, capture) 
{
	if (typeof target.addEventListener != "undefined") {
		target.addEventListener(eventType, functionRef, capture);
	} else if (typeof target.attachEvent != "undefined") {
		target.attachEvent("on" + eventType, functionRef);
	}else{
		eventType = "on" + eventType;
	
		if (typeof target[eventType] == "function") {
			var oldListener = target[eventType];
		
			target[eventType] = function() {
				oldListener();				
				return  functionRef();
			}
		}else{
		  target[eventType] = functionRef;
		}
	}  
}


com.acuataller.ValidarFormulario.prototype._revalidarGrupo = function( idElementoMensajePersonaliado ) 
{
	// Los mensajes de error personalizados para mostrarlos en un elemento html definido
	// cuando mustran mas de un error en el mismo elemento hay que revisar al borrar el error 
	// que los demas campos esten validos. Para comprobar se comprueban todos los campos que utilizan 
	// ese espacio de mensaje.
	
	this.revalidandoGrupo = true;
	
	var rv = this.reglasValidacion;
	for( var idCampo in rv ) 
	{		
		if(
		   rv[idCampo]['idMostrar']
		   &&
		   rv[idCampo]['idMostrar'] == idElementoMensajePersonaliado
		   &&
		   this.camposInvalidos[idCampo]
		   )
		{
			r = this._validarCampo( false, document.getElementById( idCampo ) );
			if(!r) break;
		}
		
	}
	this.revalidandoGrupo = false;
}	


com.acuataller.ValidarFormulario.prototype._campoInvalido = function( idCampo, invalido ) 
{
	if(invalido){		
		this.camposInvalidos[idCampo] = true;
	}else{
		if(this.camposInvalidos[idCampo]){
			this.camposInvalidos[idCampo] = null;
		}
	}
}



