var oValidaciones=new CValidaciones();

function CValidaciones() {
	this.eltos = new Array();
	this.add = addElto;
	this.validar  = validacion;
        this.limpiar = limpieza;
        this.limpiarValidaciones = limpiarElementoValidaciones;
}

function addElto (objeto, descripcion, obligatorio, tipo, longitud) {
	this.eltos[this.eltos.length] = new CElto (objeto, descripcion, obligatorio, tipo, longitud);
}


function CElto (objeto, descripcion, obligatorio, tipo, longitud) {
	this.objeto = objeto;
	this.descripcion = descripcion;
	this.obligatorio =obligatorio;
	this.tipo =tipo;
	this.longitud = longitud;
	this.validar = validacionElto;
	this.error = errorValidar;
        this.limpiar = limpiarElto;
//        this.limpiarEltoValidaciones = limpiarElementoValidaciones;
}

function limpiarElementoValidaciones(){
  this.eltos = new Array();
  return true;
}

//function limpiarValidaciones(){
//  for(i=0;i<this.eltos.length;i++){
//    this.eltos[i].limpiar();
//  }
//  return true;
//}

function limpieza(){
  for(i=0;i<this.eltos.length;i++){
    this.eltos[i].limpiar();
  }
  return true;
}

function limpiarElto(){
  if (this.tipo=='check'){    this.objeto.checked=false;  }
  else if  (this.tipo=='radio') {    this.objeto.checked=false;  }
  else if (this.tipo=='combo'){    this.objeto[0].selected=true; }
  else{    this.objeto.value="";  }
  return true;
}

function  validacion() {
	for(i=0;i<this.eltos.length;i++){
		if(!this.eltos[i].validar())
			return false;
	}
	return true;
}

//ES MUY IMPORTANTE EL ORDEN EN QUE ESTAN COLOCADAS LAS FUNCIONES, -NO CAMBIAR ESE ORDEN-.
function  validacionElto() {
        if(this.tipo=='dato'){
          var valor = this.objeto.value;

          if (valor.toUpperCase().indexOf("INSERT") != -1 || valor.toUpperCase().indexOf("UPDATE")!=-1 || valor.toUpperCase().indexOf("DELETE")!=-1){
             alert("El campo " +this.objeto.value + " contiene cadena incorrecta");
             return this.error();


          }
	}
	if(this.tipo=='entero'){
          var valor = this.objeto.value;
          for (i=0; i<valor.length; i++){
            var aux = valor.substring(i,i+1);
            if(isNaN(aux)){
                alert("El campo "+this.descripcion+" debe ser un número entero, sin comas ni puntos.");
                return this.error();
            }
          }
	}
	if(this.tipo=='check'){
		var check=this.objeto;
		var chequeados = 0;
		for(var i=0; i<check.length; i++){
			if(check[i].checked)
				chequeados++;
		}
		if(this.longitud<=chequeados){
			return true;
		}
		if(this.longitud==1)
			alert("El campo "+this.descripcion+" necesita al menos "+this.longitud+" registro seleccionado.");
		else
			alert("El campo "+this.descripcion+" necesita al menos "+this.longitud+" registros seleccionados.");
		return false;
	}
	if(this.tipo=='radio'){
		if(isNaN(this.objeto.length)){
			if(this.objeto.checked){
				return true;
			}
		}else{
			for(var i=0; i<this.objeto.length; i++){
				if(this.objeto[i].checked){
					return true;
				}
			}
		}
		alert("Es obligatorio seleccionar una "+this.descripcion);
		return false;
	}
	if(this.tipo=='combo'){
                if(this.objeto[0].selected==true && this.obligatorio ){
                  alert("El campo "+this.descripcion+" es obligatorio.");
                  return false;
                }
		if(this.objeto.length){
                  return true;
		}
		for(var i=0; i<this.objeto.length; i++){
                      if(this.objeto[i].selected){
                              if(this.objeto[i].value=='' || this.objeto[i].value=='-1'){
                                      alert("El campo "+this.descripcion+" es obligatorio.");
                                      return false;
                              }
                      }
		}
		return true;
	}

	if(this.tipo=='periodoFecha'){
		var fecha=this.objeto;
		if(vacio(fecha[0].value) && vacio(fecha[1].value) ){
			if(this.obligatorio){
				alert("El campo "+this.descripcion+" es obligatorio.");
				fecha[0].select();
				fecha[0].focus();
				return false;
			}
		}else{
			return periodoValido(fecha[0],fecha[1]);
		}
		return true;
	}

	if(this.tipo=='fecha'){
		if(vacio(this.objeto.value)){
			if(this.obligatorio){
				alert("El campo "+this.descripcion+" es obligatorio.");
				return this.error();
			}
		}else{
			var fecha=formatoFecha(this.objeto.value);

			if(fecha=="false"){
				alert("El formato de la fecha "+this.descripcion+" no es correcto.");
				return this.error();
			}
		}
		return true;
	}
	if(vacio(this.objeto.value)){
		if(this.obligatorio){
			alert("El campo "+this.descripcion+" es obligatorio.");
			return this.error();
		}
	}

	if(this.tipo=='numero'){
		if(isNaN(this.objeto.value)){
			alert("El campo "+this.descripcion+" debe ser numérico.");
			return this.error();
		}
	}

	if (this.objeto.value.length>this.longitud){
		alert("La longitud máxima permitida del campo "+this.descripcion+" es de "+this.longitud+".");
		return this.error();
	}


       if ( (this.tipo=='email') && (this.objeto.value.length>0)){
          var i = this.objeto.value.indexOf ('@',0);
          var j = this.objeto.value.lastIndexOf ('.',this.objeto.value.length);
          //Que aparezca @ , siendo mayor que 0 indica que hay algo antes
          // que el punto vaya después de @,
          if ( ( i<1 )||(j == -1)||(i > j)){
              alert("El email no es valido.");
              return false;
          }
          //Si j-1>=i, hay algo entre @ y. Y después de j tiene que haber algo
          if ( (i==j-1) || (j>(this.objeto.value.length-2)) ){
              alert("El email no es valido.");
              return false;
         }
       }
       if (this.tipo=='cif'){
        if(this.obligatorio || this.objeto.value.length>0){
          if (this.objeto.value.length>3 && this.objeto.value.length<10){
            var i= 0;
            validCIFchars="ABCDEFGHKLMPQSX";
            var letter = this.objeto.value.charAt(i).toUpperCase();
            if ( !isDigit(this.objeto.value.charAt(i)) ){
              //Si es una letra, debe ser válida
              if (validCIFchars.indexOf(letter)==-1){
                alert("El CIF no es válido");
                return false;
              }else{
                for (i=1; i < this.objeto.value.length; i++){
                  if (!isDigit(this.objeto.value.charAt(i)) ){
                    alert("El CIF no es válido");
                    return false;
                  }
                }
              }
            }
            else{
              for (i=1; i < this.objeto.value.length-1; i++){
                if (!isDigit(this.objeto.value.charAt(i)) ){
                  alert("El CIF no es válido");
                  return false;
                }
              }
              //i==this.objeto.value.length-1
              //Permite una letra al final del cif
              if ( !isDigit(this.objeto.value.charAt(i)) ){
                letter = this.objeto.value.charAt(i).toUpperCase();
                if (validCIFchars.indexOf(letter)==-1){
                  alert("El CIF no es válido");
                  return false;
                }
              }else{
                  alert("El CIF no es válido");
                  return false;

              }
            }
          }else{
            alert("El CIF no es válido");
            return false;
          }
        }
       }

       if (this.tipo=='nif'){
        if(this.obligatorio || this.objeto.value.length>0){
         var i=0;
         //Ongitus entre 4 y 10 carac, y el primero un número siempre
         if (this.objeto.value.length>3 && this.objeto.value.length<10 && isDigit(this.objeto.value.charAt(i)) ){
          var letter = this.objeto.value.charAt(i).toUpperCase();
          //El resto de los char menos el último deben ser dígitos
            for (i=1; i < (this.objeto.value.length)-1; i++) {
              if (!isDigit(this.objeto.value.charAt(i)) ){
                alert("El NIF no es válido");
                return false;
              }
            }
            validNIFchars="ABCDEFGHJKLMNPQRSTVWXYZ";
            letter = this.objeto.value.charAt(i).toUpperCase();
            if (validNIFchars.indexOf(letter) == -1){
              alert("El NIF no es válido");
              return false;
            }
         }
         else{
           alert("El NIF no es válido");
           return false;
         }
        }
       }

       return true;
}

function isDigit(char){
        return ( char>="0") && (char<="9");
}

function  errorValidar() {
	this.objeto.select();
	this.objeto.focus();
	return false;
}

function  vacio(cadena) {
	if(cadena==null || cadena.length==0)
		return true;
	for(var index=0; index<cadena.length;index++){
		if( (cadena.charAt(index))!=' '  && (cadena.charAt(index))!='\t'  && (cadena.charAt(index))!='\n'  && (cadena.charAt(index))!='\r' )
			return false;
	}
	return true;
}

function  periodoValido(oDesde,oHasta) {
	if( formatoFecha(oDesde.value)!="false"){
		if(formatoFecha(oHasta.value)!="false"){
			if(oDesde.value>oHasta.value){
				alert("La fecha del campo desde no puede ser superior a la del hasta.");
				oDesde.select();
				oDesde.focus();
				return false;
			}
		}else{
			alert("El formato de la fecha hasta es incorrecto");
			oHasta.select();
			oHasta.focus();
			return false;
		}
	}else{
		alert("El formato de la fecha desde es incorrecto");
		oDesde.select();
		oDesde.focus();
		return false;
	}
	return true;
}
function formatoFecha(fecha) {
	fecha=fecha.split("/");
	if(fecha.length!=3){
		return "false";
	}else if(fecha[2].length==4 && fecha[1].length==2 && fecha[0].length==2 &&!isNaN(fecha[2]) && !isNaN(fecha[1]) && !isNaN(fecha[0])){
		if(fecha[1]>0 && fecha[1]<=12 && fecha[0]>0 && fecha[0]<=31){
			return fecha[2]+fecha[1]+fecha[0];
		}
	}
	return "false";
}

function  limTexto(obj, lon, contObj) {
	if(obj.value.length>lon){
		obj.value = obj.value.substring(0,lon);
		alert("La longitud máxima permitida es de "+lon+" caracteres.");
	}
	contObj.disabled=true;
	if(contObj!="")
		contObj.value=lon-obj.value.length;
}


///////////////////////////////////////////////////////////////////////////////
//////////     CALCULO DE FECHA Y VALIDACION EN CAMPOS MULTIPLES     //////////
///////////////////////////////////////////////////////////////////////////////
/*
Se incluyen funciones para realizar las comporbaciones de fechas asi como
funciones para calcular automaticamente periodos de fechas y rellenar
campos en los formularios.

cFechas --> calculaFecha --> getCompleteYear
    |                               ^
    |_______________________________|

Para calcular automáticamente periodos de fechas se debe llamar a la funcion
"cFechas" desde el evento "onChange", bien desde un radio o combo. Se le deben
pasar los siguientes parametros: el objeto fecha_desde, el objeto fecha_hasta,
el objeto de control (el radio o el combo) y el tipo de calculo. Si el
tipo es '-' calculará la fecha hacia atrás y será en la fecha hasta donde
ponga la fecha de hoy, si el tipo es '+' calculará hacia delante y pondrá
la fecha de hoy en el campo desde.

"calculaFecha(periodo,valor,destino)" obtiene una fecha a partir de la fecha
actual del sistema. Dependiendo de "valor" suma o resta "periodo" a la fecha
del sitema y lo escribe con formato dd/mm/yyyy en "destino".

"getCompleteYear(fecha)" obtiene el año completo con cuatro cifras. Recibe la
fecha y devuelve el año con cuatro cifras.

checkDate

"checkDate(desde,hasta,nombre)" comprueba que las fechas indicadas por "desde" y
por "hasta" cumplan los siguientes requisitos: Existan las dos fechas y que la
fecha "hasta" >= "desde". El parametro "nombre" sirve para mostrar un mensaje
al usuario. Es el nombre que identifica el campo que se comprueba.
*/

/**
 * Calcula las fechas en función de la selección de un "radio button".
 * @return actualiza los campos de las fechas.
 */
function cFechas(desde,hasta,control,tipo){

  var today = new Date();
  var dia =  parseInt(today.getDate()).toString();
  dia = (dia.length==1 ? "0" : "") + dia;
  var mes = parseInt(today.getMonth() + 1).toString();
  mes = (mes.length==1 ? "0" : "") + mes;

  for (i=0; i < control.length; i++){

    if (control[i].checked == true){
      if (control[i].value == 'mes'){
        if (tipo == '-'){
          //calculaFecha(30,'-',desde);
          //hasta.value = dia + "/" + mes + "/" + getCompleteYear(today);
          calculaFecha(30,'+',hasta);
          desde.value = dia + "/" + mes + "/" + getCompleteYear(today);
        }else{
          calculaFecha(30,'+',hasta);
          desde.value = dia + "/" + mes + "/" + getCompleteYear(today);
        }
        return;
      }else if (control[i].value == 'semana'){
        if (tipo == '-'){
          calculaFecha(7,'+',hasta);
          desde.value = dia + "/" + mes + "/" + getCompleteYear(today);
          //calculaFecha(7,'-',desde);
          //hasta.value = dia + "/" + mes + "/" + getCompleteYear(today);
        }else{
          calculaFecha(7,'+',hasta);
          desde.value = dia + "/" + mes + "/" + getCompleteYear(today);
        }
        return;
      }
    }
  }//for
}

/**
 * Recibe dos objetos que contienen fechas. Se realizan las siguientes comprobaciones:
 * 1) Deben estar las dos fechas.
 * 2) La segunda fecha es posterior a la primera.
 * @return true si las fechas son correctas, false si no cumplen algun requisito.
 */
function checkDate(desde,hasta,nombre){
//  alert('checkDate: ' + desde.name + ";" + hasta.name + ";" + nombre);
  if (((desde.value != '')&&(hasta.value == ''))||((hasta.value != '')&&(desde.value == ''))) {
      alert('Los campos ' + nombre + ' deben rellenarse.');
      return false;
  }
//  if (Date.parse(desde.value) > Date.parse(hasta.value)) {
//      alert('La fecha de fin debe ser posterior a la de incio en los campos de ' + nombre + '.');
//      return false;
//  }
  //dd/mm/yyyy
  //0123456789
  var fromDate = new Date();
  var toDate = new Date();
  fromDate.setDate(parseInt(desde.value.substring(0,2),10));
  fromDate.setMonth(parseInt(desde.value.substring(3,5),10)-1);
//  fromDate.setYear(parseInt(desde.value.substring(6,desde.length),10));
  fromDate.setYear(parseInt(desde.value.substring(6,10)));
  from =  fromDate.getTime();
  toDate.setDate(parseInt(hasta.value.substring(0,2),10));
  toDate.setMonth(parseInt(hasta.value.substring(3,5),10)-1);
//  toDate.setYear(parseInt(hasta.value.substring(6,desde.length),10));
  toDate.setYear(parseInt(hasta.value.substring(6,10)));
  to =  toDate.getTime();
  if (from > to) {
      alert('La fecha de fin debe ser posterior a la de inicio en los campos de ' + nombre + '.');
      return false;
  }
  return true;
}

/**
 * Calcula una fecha a partir de hoy. Le suma o resta ("valor")
 * tantos dias como indique "periodo". Parametro "destino" es opcional y
 * apunta al objeto donde se quiere asignar la nueva fecha calculada.
 * @return Actualiza en "destino" el valor de la nueva fecha, además devuelve
 * como un String la cadena asignada.
 */
function calculaFecha(periodo,valor,destino){
  //Comprobaciones de los parametros
  if (periodo == 0){ return fecha.value;}
  if (valor != '-' && valor != '+') { return null;}

  //Fecha de hoy en miliseg.
  var newDate = new Date();
  var ms = newDate.getTime();
  i = parseInt(periodo);
  //86.400.000 son los miliseg de un dia
  if (valor == "+") ms += (86400000 * i);
  else  ms -= (86400000 * i);
  newDate.setTime(ms);
  //Formateamos la fecha a dd/mm/yyyy
  var dia =  parseInt(newDate.getDate()).toString();
  dia = (dia.length==1 ? "0" : "") + dia;
  var mes = parseInt(newDate.getMonth() + 1).toString();
  mes = (mes.length==1 ? "0" : "") + mes;
  var fecha = dia + "/" + mes + "/" + getCompleteYear(newDate);
  //Asignamos el nuevo valor al campo y devolvemos el String
  if (destino != null) destino.value = fecha;
  return fecha;
}

/**
 * Obtiene el año completo de una fecha. Realizamos las distintas comprobaciones
 * de los años de las fechas para devolver un año de 4 digitos.
 * @return
 */
function getCompleteYear(fecha) {
  var year = "";
  if (fecha.getFullYear() != null){
    year = fecha.getFullYear();
    if (year < 1970) year+= 100;
  }
  else{
    year = fecha.getYear();
    if (year > 69  && year < 100) year += 1900;
    if (year < 1000) year += 2000;
  }
  return year;
}

/**
 * Actualiza el objeto radio[indice] marcándolo como cheked.
 * Se utiliza para indicar que se requiere un periodo determinado
 * de fechas. Por ejemplo si hemos seleccionado "ultima semana" y modificamos
 * una fecha de las dos, se llama antes a esta función para actualizar el
 * checkbox a "periodo" o similar.
 */
function actualizaRadio(radio,indice){
  radio[indice].checked = true;
}

/**
 * Recibe un objeto del formulario con una hora. La hora debe estar en
 * el siguiente formato HH:mm, con formato 24H. "nombre" es la descripcion
 * del campo con la hora para poder mostrar mensajes personalizados al
 * usuario.
 * hh:mm
 * 01234
 * @return true si la hora es correcta y false si no lo es.
 */
function validateTime(hora,nombre){
  if (hora.value.length != 5){
    alert (' En el campo ' + nombre + ' el formato es incorrecto. El formato debe ser el siguiente: "hh:mm" (24h).' );
    return false;
  }
  if (hora.value.substring(2,3) != ':' && hora.value.substring(2,3) != '-'){
    alert (' En el campo ' + nombre + ' el formato es incorrecto. El formato debe ser el siguiente: "hh:mm" (24h). Los separadores válidos son ":" y "-"' );
    return false;
  }
  if (isNaN(parseInt(hora.value.substring(0,2),10))){
    alert(' En el campo ' + nombre + ' sólo se permiten valores numéricos' );
    return false;
  }
  if (isNaN(parseInt(hora.value.substring(3,5),10))){
    alert(' En el campo ' + nombre + ' sólo se permiten valores numéricos' );
    return false;
  }
  var Hora = parseInt(hora.value.substring(0,2),10);
  if ( Hora < 0 || Hora > 23 ){
    alert (' En el campo ' + nombre + ' las horas no son validas. Las horas válidas son 0 a 23.' );
    return false;
  }
  var minuto = parseInt(hora.value.substring(3,5),10);
  if ( minuto < 0 || minuto > 59 ){
    alert (' En el campo ' + nombre + ' los minutos no son validos. Los minutos válidos son 0 a 59.');
    return false;
  }
  return true;
}

/**
 * Esta función comprueba si se ha seleccionado un radio buton del conjunto.
 * Se utiliza principalmente para comprobar que el usuario ha seleccionado un
 * registro del listado antes de trabajar con él.
 * @return true si ha seleccionado un registro o muestra un mensaje por pantalla
 * advirtiendo del problema y devuelve false
 */
function seleccionado(objeto){
  var seleccionado=false;
  if(isNaN(objeto.length)){
    if(objeto.checked){
      return true;
    }
  }
  for(var i=0; i<objeto.length; i++){
    if(objeto[i].checked){
      return true;
    }
  }
  if (!seleccionado){
    alert ('Debe seleccionar un registro del listado para poder realizar la función seleccionada.');
    return false;
  }
}
