var genAnyoNoValido = "El año introducido no es válido";
var genMesNoValido = "El mes introducido no es válido";
var genDiaNoValido = "El dia introducido no es válido";
var genFormatoFechaIncorrecto = "Formato de fecha incorrecto, utilice alguno de los siguientes: dia/mes/año o dia-mes-año.";
var genFormatoAnyo = "El valor de año debe indicarse con 4 digitos.";
var genFormatoFecha = "El formato de la fecha debe ser: dd/mm/aaaa.";
var genFechaAnteriorAHoy = "La fecha introducida no puede ser anterior al dia de hoy.";
var genIntroducirNumEntero = "Debe introducir un valor numerico entero.";
var genIntroducirNumEnteroPositivo = "Debe introducir un valor numerico entero positivo.";
var genValorNumerico = "El valor debe ser numérico.";
var genEMailIncorrecto = "La dirección de E-mail no es correcta.";
var genNumCaracteresCifNif = "Introduzca 9 caracteres para el campo CIF/NIF.";
var genCifNoValido = "No es un CIF válido.";
var genNifNoValido = "No es un NIF válido.";
var satIntroducirCPValido = "Debe introducir un código postal válido";
var satRellenarCampo = "Debe rellenar algún campo";

function MM_reloadPage(init) {  //reloads the window if Nav4 resized
  if (init==true) with (navigator) {if ((appName=="Netscape")&&(parseInt(appVersion)==4)) {
    document.MM_pgW=innerWidth; document.MM_pgH=innerHeight; onresize=MM_reloadPage; }}
  else if (innerWidth!=document.MM_pgW || innerHeight!=document.MM_pgH) location.reload();
}

function popupPosition(ancho, alto){
	if (document.all) var xMax = screen.width, yMax = screen.height;
	else
		if (window.outerWidth){
			var xMax = window.outerWidth, yMax = window.outerHeight;
		}
		else{
			var xMax = 800, yMax=600;
		}
	var xOffset = (xMax - ancho)/2, yOffset = (yMax - alto)/2;
	var retorno = 'width='+ancho+',height='+alto+',top='+yOffset+',left='+xOffset;
	return retorno;
}

function MM_openBrWindow(theURL,winName,features) { //v2.0
  	window.open(theURL,winName,features);
}

function abrir_ventanaSinScroll(url,ancho,alto,nombre) {
	var posicion = popupPosition(ancho, alto);
	var parametros = 'scrollbars=no,status=no,toolbar=no,location=no,directories=no,menubar=no,resizable=0,' + posicion;
	window.open(url,nombre,parametros);
}

function abrir_ventanaConScroll(url,ancho,alto,nombre) {
	var posicion = popupPosition(ancho, alto);
	var parametros = 'scrollbars=yes,status=no,toolbar=no,location=no,directories=no,menubar=no,resizable=0,' + posicion;
	window.open(url,nombre,parametros);
}

/* PARAMETROS: 	  url, url que queremos que se cargue en la ventana a la que llamamos
		  ancho, ancho que queremos que tenga la ventana flotante a la cual llamamos
		  alto, altura que queremos que tenga la ventana flotante a la cual llamamos
   FUNCIONALIDAD: llama a una pantalla flotante con los parametros indicados
*/
function abrir_ventana(url,ancho,alto) {
	var posicion = popupPosition(ancho, alto);
	var parametros = 'scrollbars=yes,status=no,toolbar=no,location=no,directories=no,menubar=no,resizable=0,' + posicion;
	window.open(url,"Ventana",parametros);
}

/* PARAMETROS: 	  url, url que queremos que se cargue en la ventana a la que llamamos
		  winName, nombre de la ventana que vamos a abrir
		  ancho, ancho que queremos que tenga la ventana flotante a la cual llamamos
		  alto, altura que queremos que tenga la ventana flotante a la cual llamamos
   FUNCIONALIDAD: llama a una pantalla flotante con los parametros indicados
*/
function abrir_ventana2(url,winName,ancho,alto) {
	var posicion = popupPosition(ancho, alto);
	var parametros = 'scrollbars=yes,status=no,toolbar=no,location=no,directories=no,menubar=no,resizable=0,'+posicion;
	window.open(url,winName,parametros);
}

/* PARAMETROS: 	  formu, formulario al que llamamos
		  ancho, ancho que queremos que tenga la ventana flotante a la cual llamamos
		  alto, altura que queremos que tenga la ventana flotante a la cual llamamos
   FUNCIONALIDAD: llama a la flotante enviandole los parametros en el submit
*/
function openWindowWithSetTimeOut(formu, ancho, alto){
	var posicion = popupPosition(ancho, alto);
	setTimeout('document.' + formu + '.submit()',1000);
	var param = 'scrollbars=yes,status=no,toolbar=no,location=no,directories=no,menubar=no,resizable=no,' + posicion;
	window.open('','ventana',param);
}

/* PARAMETROS:    nombrePantalla
   FUNCIONALIDAD: hace el href a la url que indicamos con el parametro nombrePantalla
*/
/* PARAMETROS: 	  formu, formulario al que llamamos
		  ancho, ancho que queremos que tenga la ventana flotante a la cual llamamos
		  alto, altura que queremos que tenga la ventana flotante a la cual llamamos
   FUNCIONALIDAD: llama a la flotante enviandole los parametros en el submit
*/
function abrirVentanaMenuIzqSinControles(accion){
	//eval('document.' + formu + '.target = "' + formu + 'ventana"');
	//setTimeout('document.' + formu + '.submit()',1000);

	var posicion = popupPosition(ancho, alto);
	var param = 'scrollbars=yes,status=no,toolbar=no,location=no,directories=no,menubar=no,resizable=no,'+posicion;
	window.open(accion,'ventana',param);
}

function abrirVentanaMenuIzq(formu){
	var ancho = 840;
	var alto = 550;
	var retorno = popupPosition(ancho, alto);
	eval('document.' + formu + '.target = "' + formu + 'ventana"');
	var param = '';
	if (formu == 'formPersonal_TECNICLUBPROF') {
		param = 'scrollbars=no,status=yes,toolbar=no,location=no,directories=no,menubar=no,resizable=yes,'+retorno;
	} else {
		param = 'scrollbars=yes,status=yes,toolbar=yes,location=yes,directories=yes,menubar=yes,resizable=yes,'+retorno;
	}
	
	setTimeout('document.' + formu + '.submit()',1000);
	window.open('',formu + 'ventana',param);
}

/* PARAMETROS:    nombrePantalla
   FUNCIONALIDAD: hace el href a la url que indicamos con el parametro nombrePantalla
*/
function abrirPantalla(nombrePantalla) {
	window.document.location = nombrePantalla;
}

/* PARAMETROS:    nombrePantalla
   FUNCIONALIDAD: hace el href a la url que indicamos con el parametro nombrePantalla
*/
function irPantalla(formu, nombrePantalla) {
	formu.action = nombrePantalla;
	formu.submit();
}

function MM_goToURL() { //v3.0
	var i, args=MM_goToURL.arguments; document.MM_returnValue = false;
	for (i=0; i<(args.length-1); i+=2) eval(args[i] + ".location='" + args[i+1] + "'");
}

function busquedaAvanzada(){
	/*valorBusqueda = document.formBusquedaAvanzada.textCampoABuscar.value;
	document.location.href = "BusqAvanzada.jsp?descripcion=" + valorBusqueda + "&;primeraVez=si&;desdeModulo=si";*/
	if(document.formBusquedaAvanzada.textCampoABuscar.value == "buscar...")
		document.formBusquedaAvanzada.textCampoABuscar.value = "";
	document.formBusquedaAvanzada.descripcion.value = document.formBusquedaAvanzada.textCampoABuscar.value;
	document.formBusquedaAvanzada.submit();
}

function busquedaAvanzada2(){
	if(document.all){
		if(event.keyCode == 13){
			busquedaAvanzada();
		}
	}
}

/*PARAMETROS:   formu es el nombre del formulario al que queramos añadir el parametro,
		nombre es el nombre del parametro que queramos crear,
		valor es el valor del parametro que estamos creando
FUNCIONALIDAD:	a la hora de añadir un nuevo parametro al formulario se comprueba si ya
		existe y si es asi se le da el valor que queremos que tenga en este momento
		y si no existe se crea
RETURN:	 	no devuelve nada */
function addNewParameter(formu,nombre,valor){
	var existe = "no";
	for(var i=0; i<eval(formu + '.elements.length'); i++){
		if(eval(formu).elements[i].name == nombre){
			eval(formu).elements[i].disabled = false;
			eval(formu).elements[i].value = valor;
			existe = "si";
		}
	}
	if(existe == "no"){
		var input1 = document.createElement('INPUT');
		input1.type = "hidden";
		input1.value = valor;
		input1.name = nombre;
		eval(formu).appendChild(input1);
	}
}

/* PARAMETROS: 	  formu, es el nombre del formulario que queremos enviar
		  seleccion, es el valor del parametro que vamos a crear en caso necesario
   FUNCIONALIDAD: envía el formulario formu que pasamos como parametro
   		  con el parametro SELECCION si no está en el formulario
   NOTA:	  el parametro SELECCION es el que me indica que menu tengo en el
   	 	  menu de la izquierda, asi como su submenu seleccionado correspondiente
*/
function addSeleccion(formu, seleccion){
	addNewParameter(formu,'SELECCION',seleccion);
	eval(formu).submit();
}

/* PARAMETROS: 	  formu, es el nombre del formulario que queremos enviar
		  seleccion, es el valor del parametro que vamos a crear en caso necesario
   FUNCIONALIDAD: envía el formulario formu que pasamos como parametro
   		  con el parametro SELECCION si no está en el formulario
   NOTA:	  el parametro SELECCION es el que me indica que menu tengo en el
   	 	  menu de la izquierda, asi como su submenu seleccionado correspondiente
   ADVERTENCIA:   ponerlo en el onload del body para  que añada desde el principio el
   		  parametro SELECCION  a cada formulario
*/
function addParameterSeleccion(valor){
	var formu;
	var existe;
	var formu2;
	var i;
	var j;
	var input1;
	var coll = document.getElementsByTagName("form");
	for(i=0;i<coll.length;i++){
		existe = "no";

		if(coll[i].elements.length !=0){
			for(j=0;j<coll[i].elements.length;j++){
				if(coll[i].elements[j].name == "SELECCION"){
					existe = "si";
				}
			}
		}
		if(existe == "no"){
			input1 = document.createElement('INPUT');
			input1.type = "hidden";
			input1.value = valor;
			input1.name = "SELECCION";
			input1.id = "SELECCION";
			coll[i].appendChild(input1);
		}
	}
}

function getNumericDate()
{
	var mydate = new Date();
	var year = mydate.getYear();
	var month = mydate.getMonth();
	var day = mydate.getDate();
	if (day < 10)
		day = "0" + day;
	month = month + 1;
	if(month < 10)
		month = '0' + month;
	var now = year.toString() + month.toString() + day.toString();
	return now;
}

function fechas(caja){
   if (caja != "dd/mm/aaaa"){
      borrar = caja;
      if ((caja.substr(2,1) == "/") && (caja.substr(5,1) == "/"))
      {
        for (i=0; i<10; i++)
        {
		if (((caja.substr(i,1)<"0") || (caja.substr(i,1)>"9")) && (i != 2) && (i != 5)){
			borrar = "";
            		break;
		}
        }
	if (borrar){
		a = caja.substr(6,4);
		m = caja.substr(3,2);

		d = caja.substr(0,2);
		if((a < 1900) || (a > 2050) || (m < 1) || (m > 12) || (d < 1) || (d > 31)){
			borrar = "";
		}
		else
		{
			if((a%4 != 0) && (m == 2) && (d > 28)){
				borrar = "";
			}
			else
			{
				if ((((m == 4) || (m == 6) || (m == 9) || (m==11)) && (d>30)) || ((m==2) && (d>29))){
					borrar = "";
				}
				else if(((m == 1) || (m == 3) || (m == 5) || (m==7) || (m==8) || (m==10) || (m==12)) && (d>31)){
					borrar = "";
				}
			// Si las fechas son correctas: ANTES se comprobaba si la fecha era mayor que la actual
			/*	else
				{
					var fechaActual = getNumericDate() + '';
					var fechaCaja = a + m + d;

					if (fechaCaja < fechaActual)
					{
						borrar = "";
					}
				}*/
			}
		}
	}
      }
      else{
		borrar = "";
	}

	if (borrar == "")
		return "NOT_OK";
	else
	{
		return "OK";
	}
   }
	else{
		return "OK"
	}
}

function dateCompare(fechaD,fechaH){
	if(fechaD != "dd/mm/aaaa" && fechaH != "dd/mm/aaaa"){
		var resultado = "completa";

		if (fechas (fechaD) == "OK" && fechas (fechaH) == "OK"){
			var yearone = fechaD.charAt(6) + fechaD.charAt(7) + fechaD.charAt(8) + fechaD.charAt(9);
			var monthone = fechaD.charAt(3) + fechaD.charAt(4);
			var dayone = fechaD.charAt(0) + fechaD.charAt(1);

			var yeartwo = fechaH.charAt(6) + fechaH.charAt(7) + fechaH.charAt(8) + fechaH.charAt(9);
			var monthtwo = fechaH.charAt(3) + fechaH.charAt(4);
			var daytwo = fechaH.charAt(0) + fechaH.charAt(1);

			var fechaDNumeric = (yearone + monthone + dayone) * 1;
			var fechaHNumeric = (yeartwo + monthtwo + daytwo) * 1;

			if(fechaDNumeric > fechaHNumeric)
				resultado = "";
		}else
			resultado = "";

		if (resultado == "")
			return "NOT_OK";
		else
			return "OK";
		}
	else{
		if (fechas (fechaD) == "OK" && fechas (fechaH) == "OK"){
			return "OK"
	        }else{
		        return "NOT_OK"
	        }
	}
}

var valorAnterior=1;

function validarFecha(objdia, objmes, objanyo){
	var dia = objdia.value;
	var mes = objmes.value;
	var anyo = objanyo.value;


	//vemos si la fecha es válida
       //Si el año no es valido
       if (anyo<0)
       {
           alert(genAnyoNoValido);
           objanyo.focus();
           return false;
       }
	if(anyoBisiesto(anyo))
           febrero=29;
       else
           febrero=28;
       //Miramo si el mes introducido es erroneo
       if ((mes<1) || (mes>12))
       {
           alert(genMesNoValido);
           objmes.focus();
           return false;
       }
       //Si el mes es febrero miramos si está bien introducido el dia
       if ((mes==2) && ((dia<1) || (dia>febrero)))
       {
           alert(genDiaNoValido);
           objdia.focus();
           return false;
       }
       //si es un mes de 31 días
       if (((mes==1) || (mes==3) || (mes==5) || (mes==7) || (mes==8) || (mes==10) || (mes==12)) && ((dia<1) || (dia>31)))
       {
           alert(genDiaNoValido);
           objdia.focus();
           return false;
       }
       //Si el mes tiene 30 días
       if (((mes==4) || (mes==6) || (mes==9) || (mes==11)) && ((dia<1) || (dia>30)))
       {
           alert(genDiaNoValido);
           objdia.focus();
           return false;
       }
       return true;
}

function validarFechaString(fecha){
	if(trim(fecha)=='') return true;
	numGuiones=0;
	numBarras=0;
	numSeparadores=0;
	numCaracAnyo=0;
	var dia = "";
	var mes = "";
	var anyo = "";
	for(a=0;a<fecha.length;a++){
		caracter=fecha.charAt(a);
		if(caracter=='/'){
			numBarras++;
			numSeparadores++;
		}
		if(caracter=='-'){
			numGuiones++;
			numSeparadores++;
		}
		if(caracter!='/' && caracter!='-'){
			if(numSeparadores==0) dia=dia+caracter;
			if(numSeparadores==1) mes=mes+caracter;
			if(numSeparadores==2){ anyo=anyo+caracter;numCaracAnyo++ }
		}

	}
	if(numGuiones!=2 && numBarras!=2){
		 alert(genFormatoFechaIncorrecto);
		 return false;
	}
	if(!esNumeroValidoSinAlert(dia) || !esNumeroValidoSinAlert(mes) || !esNumeroValidoSinAlert(anyo)){
		 alert(genFormatoFechaIncorrecto);
		 return false;
	}
	if(numCaracAnyo!=4){
		alert(genFormatoAnyo);
		return false;
	}

	//vemos si la fecha es válida
       	//Si el año no es valido
       if (anyo<0)
       {
           alert(genAnyoNoValido);
           return false;
       }
	if(anyoBisiesto(anyo))
           febrero=29;
       else
           febrero=28;
       //Miramo si el mes introducido es erroneo
       if ((mes<1) || (mes>12))
       {
           alert(genMesNoValido);
           return false;
       }
       //Si el mes es febrero miramos si está bien introducido el dia
       if ((mes==2) && ((dia<1) || (dia>febrero)))
       {
           alert(genDiaNoValido);
           return false;
       }
       //si es un mes de 31 días
       if (((mes==1) || (mes==3) || (mes==5) || (mes==7) || (mes==8) || (mes==10) || (mes==12)) && ((dia<1) || (dia>31)))
       {
           alert(genDiaNoValido);
           return false;
       }
       //Si el mes tiene 30 días
       if (((mes==4) || (mes==6) || (mes==9) || (mes==11)) && ((dia<1) || (dia>30)))
       {
           alert(genDiaNoValido);
           return false;
       }
       return true;
}

function validarFechaStringSep(fecha){
	if(trim(fecha)=='') return true;
	numGuiones=0;
	numBarras=0;
	numSeparadores=0;
	numCaracAnyo=0;
	var dia = "";
	var mes = "";
	var anyo = "";
	if ( fecha.length != 10){
		alert(genFormatoFecha);
		return false;
	}
	for(a=0;a<fecha.length;a++){
		caracter=fecha.charAt(a);
		if(caracter=='/'){
			numBarras++;
			numSeparadores++;
		}
		if(caracter!='/'){
			if(numSeparadores==0) dia=dia+caracter;
			if(numSeparadores==1) mes=mes+caracter;
			if(numSeparadores==2){ anyo=anyo+caracter;numCaracAnyo++ }
		}
	}
	if( numBarras!=2){
		 alert(genFormatoFecha);
		 return false;
	}
	if(!esNumeroValidoSinAlert(dia) || !esNumeroValidoSinAlert(mes) || !esNumeroValidoSinAlert(anyo)){
		 alert(genFormatoFecha);
		 return false;
	}
	if(numCaracAnyo!=4){
		alert(genFormatoAnyo);
		return false;
	}

 	//vemos si la fecha es válida
       	//Si el año no es valido
      	if (anyo<0)
       	{
           alert(genAnyoNoValido);
           return false;
       	}
	if(anyoBisiesto(anyo))
           febrero=29;
       	else
           febrero=28;
       	//Miramo si el mes introducido es erroneo
       	if ((mes<1) || (mes>12))
       	{
           alert(genMesNoValido);
           return false;
       	}
       	//Si el mes es febrero miramos si está bien introducido el dia
       	if ((mes==2) && ((dia<1) || (dia>febrero)))
       	{
           alert(genDiaNoValido);
           return false;
       	}
       	//si es un mes de 31 días
       	if (((mes==1) || (mes==3) || (mes==5) || (mes==7) || (mes==8) || (mes==10) || (mes==12)) && ((dia<1) || (dia>31)))
       	{
           alert(genDiaNoValido);
           return false;
       	}
       	//Si el mes tiene 30 días
       	if (((mes==4) || (mes==6) || (mes==9) || (mes==11)) && ((dia<1) || (dia>30)))
       	{
           alert(genDiaNoValido);
           return false;
       	}
       	return true;
}

function diaDeFecha(fecha){
	dia='';
	for(a=0;a<fecha.length;a++){
		caracter=fecha.charAt(a);
		if(caracter!='/' && caracter!='-') dia=dia+caracter;
		if(caracter=='/' || caracter=='-') a=fecha.length;
	}
	return dia;
}

function mesDeFecha(fecha){
	mes='';
	numSeparadores=0;
	for(a=0;a<fecha.length;a++){
		caracter=fecha.charAt(a);
		if(numSeparadores==1 && caracter!='/' && caracter!='-') mes=mes+caracter;
		if(caracter=='/' || caracter=='-') numSeparadores++
		if(numSeparadores==2) a=fecha.length;
	}
	return mes;
}

function anyoDeFecha(fecha){
	anyo='';
	numSeparadores=0;
	for(a=0;a<fecha.length;a++){
		caracter=fecha.charAt(a);
		if(numSeparadores==2 && caracter!='/' && caracter!='-') anyo=anyo+caracter;
		if(caracter=='/' || caracter=='-') numSeparadores++
	}
	return anyo;
}

function anyoBisiesto(anyo){
        if (anyo % 4 != 0)
            return false;
        else
        {
            if (anyo % 100 == 0)
            {
                //año bisiesto
                if (anyo % 400 == 0)
                {
                    return true;
                }
                //año NO bisiesto
                else
                {
                    return false;
                }
            }
            //año bisiesto
            else
            {
                return true;
            }
        }
}

//Mira si la fecha1 es anterior o igual a la fecha2
function antes(fecha1, fecha2){
    	if (fecha1.getFullYear() > fecha2.getFullYear()){
    		return false;
    	}else{
    		if (fecha1.getFullYear() < fecha2.getFullYear()){
    			return true;
    		}else{
    			//es el mismo año
    			if (fecha1.getMonth() > fecha2.getMonth()){
    				return false;
    			}else{
    				if (fecha1.getMonth()<fecha2.getMonth()){
    					return true;
    				}else{
    				//son el mismo mes
    					if (fecha1.getDate() <=fecha2.getDate()){
    						return true;
    					}else{
    						return false;
    					}
    				}
    			}
    		}
	}
}

function validarFechaConActual(objdia, objmes, objanyo,diaHoy,mesHoy,anyoHoy){
	var dia = objdia.value;
	var mes = objmes.value;
	var anyo = objanyo.value;

	//vemos si la fecha es válida
	if(anyoBisiesto(anyo))
           febrero=29;
       	else
           febrero=28;
       	//Miramo si el mes introducido es erroneo
       	if ((mes<1) || (mes>12))
       	{
           alert(genMesNoValido);
           objmes.focus();
           return false;
       	}
       	//Si el año no es valido
       	if (anyo<0 || anyo=='')
       	{
           alert(genAnyoNoValido);
           objanyo.focus();
           return false;
       	}
       	//Si el mes es febrero miramos si está bien introducido el dia
       	if ((mes==2) && ((dia<1) || (dia>febrero)))
       	{
           alert(genDiaNoValido);
           objdia.focus();
           return false;
       	}
       	//si es un mes de 31 días
       	if (((mes==1) || (mes==3) || (mes==5) || (mes==7) || (mes==8) || (mes==10) || (mes==12)) && ((dia<1) || (dia>31)))
       	{
           alert(genDiaNoValido);
           objdia.focus();
           return false;
       	}
       	//Si el mes tiene 30 días
       	if (((mes==4) || (mes==6) || (mes==9) || (mes==11)) && ((dia<1) || (dia>30)))
       	{
           alert(genDiaNoValido);
           objdia.focus();
           return false;
       	}

       	if(anyo<anyoHoy){
       		alert(genFechaAnteriorAHoy);
       		objanyo.focus();
       		return false;
       	}
       	else{
		if(anyo==anyoHoy&&mes<mesHoy){
			alert(genFechaAnteriorAHoy);
			objmes.focus();
       			return false;
		}
		else{
			if(anyo==anyoHoy && mes==mesHoy && dia<diaHoy){
       				alert(genFechaAnteriorAHoy);
       				objdia.focus();
       				return false;
       			}
       			else	{
       				return true;
       			}
		}
       	}
       	return true;
}


/*PARAMETROS: 	 objeto
  FUNCIONALIDAD: chequea que el CP de portugal sea del tipo: números - 3 números (Ej: 1111-222).
  RETURN: 	 La función devuelve el mensaje de error si es incorrecto y nada si es correcto.
*/
function checkCP_PT(obj){
	if (obj.value != ""){
		var filter  = /^([0-9]{4})+(\-)+([0-9]{3})+$/;
		if (filter.test(obj.value)) return("");
		else{
			return("El Código Postal de Portugal debe ser del tipo [4 números - 3 números].");
		}
	}
}

function validarTelefono(obj,valor,texto,numDigitos){
   		//intento convertir a entero.
   		//si era un entero no le afecta, si no lo era lo intenta convertir
   		 valorNum = parseInt(valor)
   		prefijo=trim(document.formulario.prefTfno.value);
   		//Compruebo si es un valor numérico
   		if (isNaN(valorNum)||valor!=valorNum) {
   		   	//entonces (no es numero) devuelvo el valor cadena vacia
  			obj.value='';
   		   	alert(texto);
   		   	obj.focus();
   		}
   		else{
   			if((prefijo=='' || prefijo=='34') && valor.length!=numDigitos){
   				obj.focus();
  				obj.value='';
   		   		alert("Debe introducir un valor de "+numDigitos+" dígitos");
   		   		obj.focus();
   			}
   		}
}

//**********************************************************************************************************
// * Función: validarEntero ()									   	   *
// * Autor: Alvaro V.S.								                           *
// * Fecha Creación: 1/7/2004									           *
// * Objetivo:   Evalua si el número recibido es un entero, si no lo es lanza un aviso.			   *
// * Parámetros: valor - contiene el valor que se quiere comprobar si es un numero entero.		   *
//**********************************************************************************************************//
function validarEntero(obj,valor){
	//intento convertir a entero.
	//si era un entero no le afecta, si no lo era lo intenta convertir

       	valorNum = parseInt(valor)

	//Compruebo si es un valor numérico
	if (isNaN(valorNum)||valor!=valorNum) {
         //entonces (no es numero) devuelvo el valor cadena vacia
         obj.focus();
	 obj.value=valorAnterior;
         alert(genIntroducirNumEntero);
      	}else{
         //En caso contrario (Si era un número) devuelvo el valor
         return valor
      	}
}

function validarEntero2(valor){
	//intento convertir a entero.
	//si era un entero no le afecta, si no lo era lo intenta convertir
	valorAnt = valor;
	valor = parseInt(valor)

	//Compruebo si es un valor numérico
	if (isNaN(valor) || valor != valorAnt) {
		//entonces (no es numero) devuelvo el valor cadena vacia
	   	return "";
	}else{
	   	//En caso contrario (Si era un número) devuelvo el valor
	   	return valor;
	}
}


function validarEntero3(obj,valor,texto,numDigitos,campo){
	if(valor != ''){
		valorAux='';
	    encontradoCero='si';

	    //Quito los ceros por delante
	    if(valor=='00000') return true;
	    for(a=0;a<valor.length;a++){
	    	if(!(valor.charAt(a)==0 && encontradoCero=='si')){
				encontradoCero='no'
		 		valorAux=valorAux+valor.charAt(a);
			}
	    }

		//intento convertir a entero.
		//si era un entero no le afecta, si no lo era lo intenta convertir
	 	valorNum = parseInt(trim(valorAux))

		//Compruebo si es un valor numérico
		if (isNaN(valorNum)||valor!=valorNum) {
		   	//entonces (no es numero) devuelvo el valor cadena vacia
		   	obj.focus();
			obj.value='';
		   	alert(texto);
			return false;
		}
		else{
			if(valor.length!=numDigitos){
				obj.focus();
				obj.value='';
		   		alert("Debe introducir un valor de "+numDigitos+" dígitos en el campo " + campo);
				return false;
			}
			return true;
		}
	}else{
		return true;
	}
}

function validarEntero4(obj,valor,texto,numDigitos){
  		//intento convertir a entero.
  		//si era un entero no le afecta, si no lo era lo intenta convertir
  		 valorNum = parseInt(valor);
  		//Compruebo si es un valor numérico
  		if (isNaN(valorNum)||valor!=valorNum) {
  		   	//entonces (no es numero) devuelvo el valor cadena vacia
 			obj.value='';
  		   	alert(texto);
  		   	obj.focus();
  		}
  		else{
  			if(valor.length!=numDigitos){
  				obj.focus();
 				obj.value='';
  		   		alert("Debe introducir un valor de "+numDigitos+" dígitos");
  		   		obj.focus();
  			}
  		}
}

function validarEntero5(obj,valor,texto,numDigitos){
	valorAux='';
   	encontradoCero='si';

   	//Quito los ceros por delante
   	if(valor=='00000') return true;
	if(valor=='000000000') return true;

   	for(a=0;a<valor.length;a++){
   		if(valor.charAt(a)==0 && encontradoCero=='si'){
		}
		else{
			encontradoCero='no'
			valorAux=valorAux+valor.charAt(a);
		}
  	}

	//intento convertir a entero.
	//si era un entero no le afecta, si no lo era lo intenta convertir
	valorNum = parseInt(trim(valorAux))

	//Compruebo si es un valor numérico
	if (isNaN(valorNum)||valor!=valorNum) {
	   	//entonces (no es numero) devuelvo el valor cadena vacia
	   	obj.focus();
		obj.value='';
	   	alert(texto);
	   	obj.focus();
	}
	else{
		if(valor.length!=numDigitos){
			obj.focus();
			obj.value='';
	   		alert("Debe introducir un valor de "+numDigitos+" dígitos");
	   		obj.focus();
		}
	}
}

function validarEntero6(obj,valor,texto,numDigitos){
  		//intento convertir a entero.
  		//si era un entero no le afecta, si no lo era lo intenta convertir
  		 valorNum = parseInt(valor);
  		//Compruebo si es un valor numérico
  		if (isNaN(valorNum)) {
  		   	//entonces (no es numero) devuelvo el valor cadena vacia
 			obj.value='';
  		   	alert(texto);
  		   	obj.focus();
  		}
  		else{
  			if(valor.length!=numDigitos){
  				obj.focus();
 				obj.value='';
  		   		alert("Debe introducir un valor de "+numDigitos+" dígitos");
  		   		obj.focus();
  			}
  		}
}


//**********************************************************************************************************
// * Función: validarEnteroSinAlert ()									   	   *
// * Autor: Alvaro V.S.								                           *
// * Fecha Creación: 1/7/2004									           *
// * Objetivo:   Evalua si el número recibido es un entero, si no lo es lanza un aviso.			   *
// * Parámetros: valor - contiene el valor que se quiere comprobar si es un numero entero.		   *
//**********************************************************************************************************//
function validarEnteroSinAlert(obj,valor){
	//intento convertir a entero.
	//si era un entero no le afecta, si no lo era lo intenta convertir

       	valorNum = parseInt(valor)

	//Compruebo si es un valor numérico
	if (isNaN(valorNum)||valor!=valorNum) {
         //entonces (no es numero) devuelvo el valor cadena vacia
         obj.focus();
	 obj.value=valorAnterior;
         return(genIntroducirNumEntero);
      	}else{
         //En caso contrario (Si era un número) devuelvo el valor
         return "";
      	}
}

function validarEnteroSinAlert2(obj,valor,texto,numDigitos){
	valorAux='';
   	encontradoCero='si';

   	//Quito los ceros por delante
   	if(valor=='00000') return true;
	if(valor=='000000000') return true;

   	for(a=0;a<valor.length;a++){
   		if(valor.charAt(a)==0 && encontradoCero=='si'){
		}
		else{
			encontradoCero='no'
			valorAux=valorAux+valor.charAt(a);
		}
  	}

	//intento convertir a entero.
	//si era un entero no le afecta, si no lo era lo intenta convertir
	valorNum = parseInt(trim(valorAux))

	//Compruebo si es un valor numérico
	if (isNaN(valorNum)||valor!=valorNum) {
	   	//entonces (no es numero) devuelvo el valor cadena vacia
	   	obj.focus();
		obj.value='';
	   	return(texto);
	   	obj.focus();
	}
	else{
		if(valor.length!=numDigitos){
			obj.focus();
			obj.value='';
	   		return("Debe introducir un valor de "+numDigitos+" dígitos");
	   		obj.focus();
		}else{
			return "";
		}
	}
}

function validarEnteroABlanco(obj){
      	//intento convertir a entero.
      	//si era un entero no le afecta, si no lo era lo intenta convertir
       	valor = trim(obj.value);
       	valorNum = parseInt(trim(obj.value));

	if(valorNum=="0"){
		valorNum = trim(obj.value).substring(1);
		valorNum = parseInt(valorNum);
	}
      	//Compruebo si es un valor numérico valido.
      	if ((isNaN(valorNum)||valor!=valorNum || valorNum<0)&&valor!='') {
		//entonces (no es numero) devuelvo el valor cadena vacia
		obj.focus();
		obj.value='';
		alert(genIntroducirNumEnteroPositivo);
		obj.focus();
		return -1;
      	}else{
		//En caso contrario (Si era un número) devuelvo el valor
		return obj.value;
      	}
}

function compruebaValidoEntero(objeto){
    valor = trim(objeto.value);
    if(valor != ''){
    	enteroValidado = validarEntero2(valor);
    	if (enteroValidado == ""){
    	   //si era la cadena vacía es que no era válido. Lo aviso
    	   alert ("Debe introducir un valor numérico entero mayor que 0.")
    	   //selecciono el texto
    	   objeto.value = '';
    	   objeto.select();
    	   //coloco otra vez el foco
    	   objeto.focus();
    	}
    }
}

function esNumeroValido (valor){
	noNumero = eval('isNaN("' + valor + '")');
	if (noNumero){
		alert(genValorNumerico);
		return false;
	}else{
		return true;
	}
}

/* funcion que mira si el numero es valido
   y quita los ceros que aparecen por delante
*/
function esNumeroValidoSinAlert(valor){
       	valorAux='';
       	encontradoCero='si';

       	//Quito los ceros por delante
       	for(a=0;a<valor.length;a++){
		if(valor.charAt(a)==0 && encontradoCero=='si'){

		}
		else{
			encontradoCero='no'
			valorAux=valorAux+valor.charAt(a);
		}
       	}

       	valorNum = parseInt(trim(valorAux))
       	//Compruebo si es un valor numérico
	if (isNaN(valorNum)||valor!=valorNum) {
		return false;
	}
	else{
		return true;
	}
}

function trim(inputString) {
   // Removes leading and trailing spaces from the passed string. Also removes
   // consecutive spaces and replaces it with one space. If something besides
   // a string is passed in (null, custom object, etc.) then return the input.
   if (typeof inputString != "string") { return inputString; }
   var retValue = inputString;
   var ch = retValue.substring(0, 1);
   while (ch == " ") { // Check for spaces at the beginning of the string
      retValue = retValue.substring(1, retValue.length);
      ch = retValue.substring(0, 1);
   }
   ch = retValue.substring(retValue.length-1, retValue.length);
   while (ch == " ") { // Check for spaces at the end of the string
      retValue = retValue.substring(0, retValue.length-1);
      ch = retValue.substring(retValue.length-1, retValue.length);
   }
   while (retValue.indexOf("  ") != -1) { // Note that there are two spaces in the string - look for multiple spaces within the string
      retValue = retValue.substring(0, retValue.indexOf("  ")) + retValue.substring(retValue.indexOf("  ")+1, retValue.length); // Again, there are two spaces in each of the strings
   }
   return retValue; // Return the trimmed string back to the user
} // Ends the "trim" function

/*PARAMETROS: 	 Nombre del formulario.
  FUNCIONALIDAD: Comprueba que el string introducido por el usuario contenga una @ y un punto.
  RETURN: 	 La función no devuelve nada.
*/
function checkMail(nombre){
	if(nombre.value!=""){
		var emailStr = nombre.value;
		var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
		if (filter.test(emailStr)) return true;
		else{
			alert(genEMailIncorrecto);
			nombre.value="";
			return false;
		}
	}
}

/*
PARAMETROS:	campo --> Se pasa el campo para coger su value y poder hacer el focus().
FUNCIONALIDAD:	Comprueba que un campo sea o un CIF o un NIF. Para ello llama a las siguientes dos funciones: verificarCIF y verificarNIF.
RETURN:		Devuelve las alertas correspondientes a que no se trata de un CIF o NIF.
RECOMENDABLE:   El uso de esta función se hace sobre el evento onblur()
*/
function checkCIFOrNIF(campo){
if(campo.value!=""){
   var valor = campo.value.toUpperCase();
   if (valor.length != 9 && valor.length != 0){
   	alert(genNumCaracteresCifNif)
   	campo.focus();
   }
}
   /*else if(valor.length == 9){
	var toWork = new String(valor.substring(0,9));
	var first = toWork.substring(0,1);
	var letraCIF = new String ('ABCDEFGHPQS');

	if (letraCIF.indexOf (first) >=0){
	   var letraOrg = new String('PQS');
	   var isOrg = (letraOrg.indexOf (first) >=0);
	   return verificaCIF(toWork, isOrg,campo);
	}else
	   return verificaNIF(toWork,campo);
   }*/
}

/*
PARAMETROS:	vienen de la función checkCIFOrNIF.
FUNCIONALIDAD:	Comprueba que un campo sea o un CIF.
RETURN:		Devuelve las alertas correspondientes a que no se trata de un CIF.
*/
function verificaCIF(toWork, isOrg,campo){
	if(toWork!=""){
		var ultimaLetra  = new Array ('J','A','B','C','D','E','F','G','H','I');
		var ultimoNumero = new Array ('0','1','2','3','4','5','6','7','8','9');

		var numValue = new String(toWork.substring(1,8));

		var sumaPar = 0;
		for(i=1; i<numValue.length; i+=2){
			sumaPar += parseInt(numValue.substring(i,i+1));
		}

		var sumaImpar = 0;
		var stVal = '';
		for(i=0; i<numValue.length; i+=2){
			var val = parseInt(numValue.substring(i,i+1)) * 2;
			if (val > 9)
				val = val - 9;
			stVal = new String(val);
			for (j=0; j<stVal.length; j++){
				sumaImpar += parseInt(stVal.substring(j,j+1));
			}
		}

		var sumaTotal = sumaImpar + sumaPar;
		var num = (10 - (sumaTotal % 10));
		if (num == 10)
			num = 0;

		var ultimo = toWork.substring(8, 9);
		if (isOrg){
			if (ultimo != ultimaLetra[num]){
				alert(genCifNoValido);
				campo.focus();
				return false;
			}
		}else{
			if ((ultimo != ultimaLetra [num]) && (ultimo != ultimoNumero[num])){
				alert(genCifNoValido);
				campo.focus();
				return false;
			}
		}
	}
	return true;
}

/*
PARAMETROS:	vienen de la función checkCIFOrNIF.
FUNCIONALIDAD:	Comprueba que un campo sea o un NIF.
RETURN:		Devuelve las alertas correspondientes a que no se trata de un NIF.
*/
function verificaNIF(toWork,campo)
{
	if(toWork!=""){
		var valids  = new Array('T','R','W','A','G','M','Y','F','P','D','X','B','N','J','Z','S','Q','V','H','L','C','K','E');
		var spanish = new Array('0','1','2','3','4','5','6','7','8','9');

		var last = toWork.charAt( toWork.length - 1 );
		var ver  = toWork.charAt(0);
		var toConvert = new String('A');
		var tipo = 0;
		for(i=0; i<spanish.length; i++){
			if( ver == spanish[i] ){
					 toConvert = toWork.substring(0,8);
					 break;
			}
		}
		if( ver == 'L' || ver == 'K')
			toConvert = toWork.substring(3,8);
		else if(ver == 'X')
			toConvert = toWork.substring(1,8);

		tipo = toConvert;
		var num = tipo % 23;
		if(valids[num] != last){
			alert(genNifNoValido);
			campo.focus();
			return false;
		}
	}
	return true;
}

/*
PARAMETROS:	vienen de la función checkCIFOrNIF.
FUNCIONALIDAD:	Comprueba que un campo sea o un NIF.
RETURN:		Devuelve las alertas correspondientes a que no se trata de un NIF.
*/
function verificaNIFMayusYMinus(toWork,campo)
{
	if(toWork!=""){
		var valids  = new Array('T','R','W','A','G','M','Y','F','P','D','X','B','N','J','Z','S','Q','V','H','L','C','K','E');
		var spanish = new Array('0','1','2','3','4','5','6','7','8','9');

		var last = toWork.charAt( toWork.length - 1 );
		last = last.toUpperCase();
		var ver  = toWork.charAt(0);
		var toConvert = new String('A');
		var tipo = 0;
		for(i=0; i<spanish.length; i++){
			if( ver == spanish[i] ){
					 toConvert = toWork.substring(0,8);
					 break;
			}
		}
		if( ver == 'L' || ver == 'K')
			toConvert = toWork.substring(3,8);
		else if(ver == 'X')
			toConvert = toWork.substring(1,8);

		tipo = toConvert;	
		var num = tipo % 23;	
		if(valids[num] != last){
			alert(genNifNoValido);
			campo.focus();
			return false;
		}
	}
	return true;
}


/*
PARAMETROS:		campo --> Se pasa el campo para coger su value y poder hacer el focus().
FUNCIONALIDAD:	Comprueba que un campo sea o un CIF o un NIF. Para ello llama a las siguientes dos funciones: verificaNIF2 y verificaNIF3.
RETURN:			Devuelve las alertas correspondientes a que no se trata de un CIF o NIF.
RECOMENDABLE:   El uso de esta función se hace sobre el evento onblur()
*/
function checkCIFOrNIF2(campo){
	var valor = campo.value.toUpperCase();
	if (valor.length != 9 && valor.length != 0){
		alert(alertaCIFNIF);
		campo.focus();
	}else if(valor.length == 9){
		var toWork = new String(valor.substring(0,9));
		toWork2 = toWork.substring(8,9) + toWork.substring(0,8);
		toWork3 = toWork.substring(1,9) + toWork.substring(0,1);
		
	/*	alert(verificaNIFMayusYMinus(toWork,campo));
		alert(verificaNIF(toWork,campo));
		alert(verificaNIFMayusYMinus(toWork2,campo));
		alert(verificaNIF(toWork2,campo));
		alert(verificaNIFMayusYMinus(toWork3,campo));
		alert(verificaNIF(toWork3,campo));
		*/
		if(verificaNIF3(toWork) || verificaNIF2(toWork) || verificaNIF3(toWork2) || verificaNIF2(toWork2) || verificaNIF3(toWork3) || verificaNIF2(toWork3)){
			return true;
		}else{
			alert("No es un CIF/NIF válido.");
			campo.value="";
			campo.focus();
			return false;
		}
	}
}
/*
PARAMETROS:		toWork --> valor a comprobar
FUNCIONALIDAD:	Comprueba que un campo sea o un NIF.
RETURN:			false / true
*/
function verificaNIF2(toWork)
{
	var valids  = new Array('T','R','W','A','G','M','Y','F','P','D','X','B','N','J','Z','S','Q','V','H','L','C','K','E');
	var spanish = new Array('0','1','2','3','4','5','6','7','8','9');

	var last = toWork.charAt( toWork.length - 1 );
	var ver  = toWork.charAt(0);
	var toConvert = new String('A');
	var tipo = 0;
	for(i=0; i<spanish.length; i++){
		if( ver == spanish[i] ){
		         toConvert = toWork.substring(0,8);
		         break;
		}
	}
	if( ver == 'L' || ver == 'K')
		toConvert = toWork.substring(3,8);
	else if(ver == 'X')
		toConvert = toWork.substring(1,8);

	tipo = toConvert;
	var num = tipo % 23;
	if(valids[num] != last){
		return false;
	}
	return true;
}

/*
PARAMETROS:		toWork --> valor a comprobar
FUNCIONALIDAD:	Comprueba que un campo sea o un NIF.
RETURN:			false / true
*/
function verificaNIF3(texto){
	var pares = 0;
	var impares = 0;
	var suma;
	var ultima;
	var unumero;
	var uletra = new Array("J", "A", "B", "C", "D", "E", "F", "G", "H", "I");
	var xxx;
	
	texto = texto.toUpperCase();
	
	var regular = new RegExp(/^[ABCDEFGHKLMNPQS]\d\d\d\d\d\d\d[0-9,A-J]$/g);
	 if (!regular.exec(texto)) return false;
		 
	 ultima = texto.substr(8,1);

	 for (var cont = 1 ; cont < 7 ; cont ++){
		 xxx = (2 * parseInt(texto.substr(cont++,1))).toString() + "0";
		 impares += parseInt(xxx.substr(0,1)) + parseInt(xxx.substr(1,1));
		 pares += parseInt(texto.substr(cont,1));
	 }
	 xxx = (2 * parseInt(texto.substr(cont,1))).toString() + "0";
	 impares += parseInt(xxx.substr(0,1)) + parseInt(xxx.substr(1,1));
	 
	 suma = (pares + impares).toString();
	 unumero = parseInt(suma.substr(suma.length - 1, 1));
	 unumero = (10 - unumero).toString();
	 if(unumero == 10) unumero = 0;
	 
	 if ((ultima == unumero) || (ultima == uletra[unumero]))
		 return true;
	 else{
		return false;
	 }
}

function validarNumeroConDecimales (valor,mensajeDeError){
	valorAux="";
	for(a=0;a<valor.length;a++){
		if(valor.charAt(a)=='.')
			valorAux=valorAux;
		else
			valorAux=valorAux+valor.charAt(a);
	}

	valor=valorAux;
	valorAux="";
	for(a=0;a<valor.length;a++){
		if(valor.charAt(a)==',')
			valorAux=valorAux+'.';
		else
			valorAux=valorAux+valor.charAt(a);
	}

	miFloat = parseFloat(valorAux);

	noNumero = eval('isNaN("'+miFloat+'")');
	if ( noNumero||miFloat!=valorAux){
		alert(mensajeDeError);
		return false;
	}else{
		return true;
	}
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
};

function MM_jumpMenu(targ,selObj,restore){ //v3.0
	eval(targ+".location='"+selObj.options[selObj.selectedIndex].value+"'");
	if (restore) selObj.selectedIndex=0;
}

function MM_jumpMenuGo(selName,targ,restore){ //v3.0
  var selObj = MM_findObj(selName); if (selObj) MM_jumpMenu(targ,selObj,restore);
}

function irAPagina(pagina){
	document.form1.action=pagina;
	document.form1.submit();
}

/* **** STRING EXTENSION FOR PUNCTUATION **** */
String.fromKeyCode = function(keyCode,evtType) {
	if (!evtType || !evtType.length)
		evtType = "keyDown";
	else if (evtType.toLowerCase() == "keypress")
		return String.fromCharCode(keyCode);
	var keyDownChars = new Array(16);
		keyDownChars[8] = '[Bksp]';
		keyDownChars[9] = '[Tab]';
		keyDownChars[12] = '[N5+shift]';
		keyDownChars[13] = '[Enter]';
		keyDownChars.push('[Shift]','[Ctrl]','[Alt]','[Pause]','[CapsLock]');
		for (i=11;i;--i) keyDownChars.push('undefined');
		keyDownChars[27] = '[Esc]';
		keyDownChars.push(' ','[PgUp]','[PgDn]','[End]','[Home]','[Left]','[Up]','[Right]','[Down]');
		for (i=7;i;--i) keyDownChars.push('undefined');
		keyDownChars[45] = '[Ins]';
		keyDownChars[46] = '[Del]';
		keyDownChars.push(['0',')'],['1','!'],['2','@'],['3','#'],['4','$'],['5','%'],['6','^'],['7','&'],['8','*'],['9','(']);
		for (i=7;i;--i) keyDownChars.push('undefined');
		keyDownChars.push('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','[WinKey]');
		for (i=4;i;--i) keyDownChars.push('undefined');
		keyDownChars.push('0','1','2','3','4','5','6','7','8','9','*','+','undefined','-','.','/','[F1]','[F2]','[F3]','[F4]','[F5]','[F6]','[F7]','[F8]','[F9]','[F10]','[F11]','[F12]');
		for (i=62;i;--i) keyDownChars.push('undefined');
		keyDownChars[144] = '[NumLock]';
		keyDownChars[145] = '[ScrollLock]';
		keyDownChars.push([';',':'],['=','+'],[',','<'],['-','_'],['.','>'],['/','?'],['`','~']);
		for (i=26;i;--i) keyDownChars.push('undefined');
		keyDownChars.push(['[','{'],['\\','|'],[']','}'],["'",'"']);
	return keyDownChars[keyCode];
}

/* **** COMBOBOX CODE **** */
/**************************************************
Original Version (1.0):
Glenn G. Vergara
http://www21.brinkster.com/gver/
glenngv AT yahoo DOT com
Makati City, Philippines

Object-Based Version:
Eric C. Davis
http://www.10mar2001.com/
eric AT 10mar2001 DOT com
Atlanta, GA, US

(Keep the above intact if you want to use it! Thanks.)

Current Version: 2.3
Last Update: 11 September 2003

********
Change Log:
New in version 2.3a:
	- Added accepting of non-existent option

New in version 2.2:
	- Many properties made private
	- Getters and setters for nearly all properties

New in version 2.0:
	- Object-oriented properties and methods using prototype
	- Constructor can accept a select element object or a select element object's ID string
	- Invocation reduced to single line of script: varName = new TypeAheadCombo('selectElementID');

New in version 1.4:
	- Allowable character set ranges use dynamic evaluation
	- Display of typed characters in status bar can be disabled

New in version 1.2:
	- Replaced major if/elseif/.../else statement with switch/case
	- Correction of characters typed on the numpad, reassigning to actual character values
********

********
API:
Constructor:
	new TypeAheadCombo(someSelectElement) // as an object or object reference
	new TypeAheadCombo('someSelectElementID') // as a string
	new TypeAheadCombobox('someSelectElementID', true) // to allow an undefined value

Priviledged Methods: (these interact with private properties and act as helper functions)
	getTyped()
		- returns the string typed by the user since the last timeout
	setTyped(str)
		- argument "str" - string which will replace the value in the type buffer
	type(str)
		- argument "str" - string which will be appended to the type buffer
	resetTyped()
		- clears what has been typed from the buffer
	getIndex()
		- returns the location of the option currently selected
	setIndex(val)
		- stores the location of the option being selected
	getPrev()
		- returns the location of the option previously selected
	setPrev(val)
		- stores the location of the option previously selected
	setResetTime(val)
		- sets the timeout interval for the reset timers
	getResetTime()
		- returns the timeout interval for the reset timers
	setResetTimer()
		- sets the timeout for the reset of the typed buffer
	clearResetTimer()
		- clears the timeout of the reset of the typed buffer
	validChar(charCode)
		- validates that the charCode passed is acceptable to the typed buffer
	setDisplayStatus(bool)
		- set whether to display the typed buffer in the status bar
	getDisplayStatus()
		- returns the current setting for status bar display of the typed buffer

Public Methods:
	detectKey()
		- detects the keyCode, parses whether it is acceptable, and adds it to the typed buffer if so
	selectItem()
		- finds the first option that matches the typed buffer and selects it
	reset()
		- clears the typed buffer and the status display
	updateIndex()
		- handles the onclick and onblur events
	elementFocus()
		- handles the onfocus event
	elementKeydown()
		- handles the onkeydown event
***********************************************************/

function TypeAheadCombo(anElement,acceptNewValue) {
	// VALIDATION
	if (!anElement) {
		return false;
	}
	if (typeof anElement == "string") { // try for the ID
		anElement = document.getElementById ? document.getElementById(anElement) : document.all ? document.all[anElement] : document.layers ? document.layers[anElement] : anElement;
	}
	if (typeof anElement == "string") { // the grab failed: typeof null yields "object"
		return false;
	}
	// ASSOCIATION
	this.element = anElement;
	this.element.combo = this;
	// ELEMENT EVENT HANDLERS
	this.element.onkeydown = this.elementKeydown;
	this.element.onfocus = this.elementFocus;
	this.element.onclick = this.updateIndex;
	this.element.onblur = this.updateIndex;
	this.element.reset = this.reset;
	// PRIVATE PROPERTIES
	var self = this,	// corrects privatization bug
		typed = "",
		index = prev = 0,
		displayStatus = true,
		resetter, nullStarter, acceptNew,
		resetTime = 1600,
		numberRangeStart = 48,
		numberRangeEnd = 57,
		charRangeStart = 65,
		charRangeEnd = 90,
		punctRangeStart = 146,
		punctRangeEnd = 223;
	if (this.element.options[0].text.length == 0 && (this.element.options[0].value.length == 0) || this.element.options[0].value == 0){
		nullStarter = true;
	} else {
		nullStarter = false;
	}
	if (typeof acceptNewValue != 'undefined' && acceptNewValue) {
		acceptNew = true;
		resetTime = 2400;
	} else {
		acceptNew = false;
	}
	// PRIVATE METHODS
	var getResetTime = function getResetTime() {
		return resetTime;
	}
	var charInRanges = function charInRanges(charCode) {
		if ((charCode >= numberRangeStart && charCode <= numberRangeEnd) || (charCode >= charRangeStart && charCode <= charRangeEnd) || (charCode >= punctRangeStart && charCode <= punctRangeEnd)) {
			return true;
		} else {
			return false;
		}
	}
	// PRIVILEDGED METHODS
	this.hasNullStarter = function() {
		return nullStarter;
	}
	this.getAcceptsNew = function() {
		return acceptNew;
	}
	this.getTyped = function () {
		return typed;
	}
	this.setTyped = function (str) {
		typed = str;
		return true;
	}
	this.resetTyped = function () {
		typed = "";
		return true;
	}
	this.type = function (str) {
		typed += str;
		return true;
	}
	this.getIndex = function () {
		return index;
	}
	this.setIndex = function (val) {
		if (!isNaN(val)) {
			index = val;
		}
	}
	this.getPrev = function () {
		return prev;
	}
	this.setPrev = function (val) {
		if (!isNaN(val)) {
			prev = val;
		}
	}
	this.setResetTime = function (val) {
		if (!isNaN(val)) {
			prev = val;
		}
	}
	this.setTimer = function () {
		resetter = setTimeout("document.forms['"+self.element.form.name+"'].elements['"+self.element.name+"'].reset();", getResetTime());
	}
	this.clearTimer = function () {
		clearTimeout(resetter);
	}
	this.validChar = function (evt, charCode) {
		if ((evt.ctrlKey) || (evt.altKey)) {
			return false;
		} else if ((evt.shiftKey) && charInRanges(charCode)) {
			return true;
		} else if (evt.shiftKey) {
			return false;
		} else {
			return charInRanges(charCode);
		}
	}
	this.setDisplayStatus = function (bool) {
		if (bool == true || bool == false) {
			displayStatus = bool;
		}
	}
	this.getDisplayStatus = function () {
		return displayStatus;
	}
}

/*
PUBLIC METHODS
*/

TypeAheadCombo.prototype.detectKey = function (evt){
	this.clearTimer();
	var combo_letter = "";
	var combo_code = (document.all) ? window.event.keyCode : evt.which;
	var event = (document.all) ? window.event : evt;
	if (combo_code <= 105 && combo_code >= 96) { // make up for numPad typing
		combo_code = combo_code - 48;
	}
	switch (combo_code) {
		case 27:	//ESC key
			this.reset();
			this.setIndex(this.getPrev());
			// Put a little delay to override NS6/Mozilla's built-in behavior of ESC inside select element
			setTimeout("document.forms['"+this.element.form.name+"'].elements['"+this.element.name+"'].selectedIndex = document.forms['"+this.element.form.name+"'].elements['"+this.element.name+"'].index",0);
			return false;
			break;
		case 13:	//ENTER key
			this.reset();
			if (this.element.onchange) {
				this.element.onchange();
			}
		case 9:		//TAB key	(don't break from ENTER - all TAB needs to do is return true. ENTER needs above and return true.
			return true;
			break;
		case 8:		//BACKSPACE key
			this.setTyped(this.getTyped().substring(0,this.getTyped().length-1));
			if (this.getAcceptsNew()) {
				this.makeNewValue();
			}
			if (this.getTyped() == "") {
				this.reset();
				this.setIndex(this.getPrev());
				this.element.selectedIndex = this.getIndex();
				return false;
			} else {
				this.setTimer();
			}
			break;
		case 33:	//PAGEUP key
		case 34:	//PAGEDOWN key
		case 35:	//END key
		case 36:	//HOME key
		case 38:	//UP arrow
		case 40:	//DOWN arrow
			this.reset();
			return true;
			break;
		case 37:	//LEFT arrow	(translates to %)
		case 39:	//RIGHT arrow	(translates to ')
			this.reset();
			return false;
			break;
		case 32:	//SPACE key	(not in accepted ranges)
			combo_letter = " ";
			this.setTimer();
			break;
		default:
			if (this.validChar(event, combo_code)) {
				combo_letter = String.fromKeyCode(combo_code);
				if (combo_letter.length > 1) {
					if (event.shiftKey) {
						combo_letter = combo_letter[1];
					} else {
						combo_letter = combo_letter[0];
					}
				}
				this.setTimer();
			} else {
				return true;
			}
			break;
	}
	this.type(combo_letter);
	if (this.getDisplayStatus()) {
		window.status = this.getTyped();
	}
	return this.selectItem();
}

TypeAheadCombo.prototype.selectItem = function (){
	for (var i=0; i<this.element.options.length; i++){
		if (this.element.options[i].text.toUpperCase().indexOf(this.getTyped()) == 0){
			this.element.selectedIndex = i;
			this.setIndex(i);	//remember selected index
			return false;
		}
	}
	if (this.getAcceptsNew()) {
		this.makeNewValue();
	} else {
		this.element.selectedIndex = this.getIndex();	//re-select previously selected option even if there's no match
	}
	return false;  //always return false
}

TypeAheadCombo.prototype.makeNewValue = function () {
	this.removeNewValue();
	if (this.hasNullStarter()) {
		newOption = this.element.options[0];
	} else {
		newOption = document.createElement("option");
		this.element.insertBefore(newOption, this.element.firstChild);
		this.newOption = newOption;
	}
	var tmpText = this.getTyped(),tmpStart = tmpEnd = "",tmpArr,i;
	tmpArr = tmpText.split(" ");
	i = tmpArr.length;
	if (tmpText.indexOf(" ") >= 0) {
		do {
			tmpStart = tmpArr[--i].substring(0,1);
			tmpEnd = tmpArr[i].substring(1,tmpArr[i].length);
			tmpArr[i] = tmpStart.toUpperCase() + tmpEnd.toLowerCase();
		} while (i);
		tmpText = tmpArr.join(" ");
	} else {
		tmpStart = tmpText.substring(0,1);
		tmpEnd = tmpText.substring(1,tmpText.length);
		tmpText = tmpStart.toUpperCase() + tmpEnd.toLowerCase();
	}
	newOption.value = tmpText;
	newOption.text = tmpText;
	this.element.selectedIndex = 0;
	this.setIndex(0);
}

TypeAheadCombo.prototype.removeNewValue = function () {
	if (this.hasNullStarter()) {
		this.element.options[0].text = '';
		this.element.options[0].value = '';
	} else if (this.newOption) {
		this.element.remove(this.newOption);
	}
}

TypeAheadCombo.prototype.reset = function () {
	theCombo = this;
	if (this.combo) {
		theCombo = this.combo;
	}
	theCombo.resetTyped();
	if (theCombo.getDisplayStatus()) {
		window.status = window.defaultStatus ? window.defaultStatus : '';
	}
}

TypeAheadCombo.prototype.updateIndex = function (){
	this.combo.setIndex(this.selectedIndex);
	this.combo.setPrev(this.combo.getIndex);
	this.combo.reset();
}

TypeAheadCombo.prototype.elementFocus = function () {
	this.combo.setIndex(this.selectedIndex);
}

TypeAheadCombo.prototype.elementKeydown = function (event) {
	return this.combo.detectKey(event);
}

//*******************************************************************************
// * Función: validateGenericNumber()
// * Autor: Alvaro Vaquero
// * Fecha Creación: 15/4/2003      Fecha Ultima Creación:
// * Objetivo: Este método valida un campo de texto con dato numerico
// * Parámetros: obj: identificador del objeto campo de texto
// *			 bolRequerido: boolean que indica si el campo es obligatorio o no
// *			 bolAvisar: boolean que indica si ha de sacarse un mensaje al usuario o no
// *			 bolPermitirCero: boolean que indica si el cero es un valor valido o no
// *			 intNumeroDecimales: int con el numero de decimales que se muestran
// *			 intMinimo: int con el valor minimo que ha de tener
// *			 intMaximo: int con el valor maximo que ha de tener
// *			 strMensajeError: Mensaje que se muestra al usuario cuando el valor no es correcto
// *			 strMensajeRequerido: Mensaje que se muestra al usuario cuando el valor es obligatorio pero se
// *								 ha dejado vacio
// *			 strMensajeLimite: Mensaje que se muestra al usuario cuando el valor esta fuera del rango permitido
// *			 strSeparadorDecimal: separador decimal que se utiliza
// *			 bolUsarFormatoMiles: boolean que indica si se ha de usar el formato de miles
// * Retorno:Boolean: indica si la cadena es correcta o no
//*******************************************************************************

function validateGenericNumber(obj, bolRequerido, bolAvisar, bolPermitirCero, intNumDecimales, intMinimo, intMaximo, strMensajeError,strMensajeRequerido,strMensajeLimite, strSeparadorDecimal, bolUsarFormatoMiles)
{
	var varNumero;
	var varCadena;
	var varCadenaParteEntera;
	var varCadenaParteEnteraFormateada;
	var varCadenaParteDecimal;
	var varI;
	var varSeparadorMiles;
	var varSigno;

	if(document.getElementById(obj))
		obj=document.getElementById(obj);
	else
		if(document.all)obj=eval('document.all.'+obj);
									//Tendrá "-" si es negativo y "" si es positivo

	//Asignar los valores por defecto a los parámetros
	if (bolRequerido == null) bolRequerido = false;
	if (bolAvisar == null) bolAvisar = false;
	if (bolPermitirCero == null) bolPermitirCero = true;
	if (intNumDecimales == null) intNumDecimales = 0;
	if (strSeparadorDecimal == null) strSeparadorDecimal = ".";
	if (bolUsarFormatoMiles == null) bolUsarFormatoMiles = false;

	//Si no es requerida se admite un valor vacio
	if (obj.value == "" && bolRequerido == false){
		bolRdoOnChange=true;
		return true;
	}

	//Si es requerida no se admite un valor vacio
	if (obj.value == "" && bolRequerido == true){
		if (bolAvisar)	alert(strMensajeRequerido);
		bolRdoOnChange=false;
		return false;
	}

	if (strSeparadorDecimal == ",") {
		varSeparadorMiles = ".";
	}
	else {
		varSeparadorMiles = ",";
	}

	//Dejar en varCadena el número sin separador de miles
	varCadena = obj.value;
	while (varCadena.indexOf(varSeparadorMiles) != -1 ) {
		varCadena = varCadena.replace(varSeparadorMiles, "");
	}

	//En varCadena utilizar como separador decimal el punto
	if (strSeparadorDecimal == ",") {
		varCadena = varCadena.replace(",", ".");
	}

	//Convertir a un número
	if (intNumDecimales == 0){
		varNumero = parseInt(varCadena,10);
		if (isNaN(varNumero) || varNumero!= varCadena){
			if (bolAvisar)	alert(strMensajeError);
			bolRdoOnChange=false;
			return false;
		}
	}
	else{
		varNumero = parseFloat(varCadena);

		if (isNaN(varNumero)){
			if (bolAvisar)	alert(strMensajeError);
			bolRdoOnChange=false;
			return false;
		}
	}

	//Mirar si se permite el 0
	if (bolPermitirCero == false && varNumero == 0){
		if (bolAvisar)	alert(strMensajeError);
		bolRdoOnChange=false;
		return false;
	}



	var strMinimo=intMinimo;
	var strMaximo=intMaximo;

	if(intNumDecimales==0){
		intMinimo=parseInt(intMinimo,10);
	}else{
		if (strSeparadorDecimal == ",") {
			intMinimo = intMinimo.replace(",", ".");
		}
		intMinimo=parseFloat(intMinimo);
	}

	if(intNumDecimales==0){
		intMaximo=parseInt(intMaximo,10);
	}else{
		if (strSeparadorDecimal == ",") {
			intMaximo = intMaximo.replace(",", ".");
		}
		intMaximo=parseFloat(intMaximo);
	}

	//Si hay valor mínimo comprobar que no es menor, y
	//si hay valor máximo comprobar que no es mayor
	if ((intMinimo != null && intMinimo!="") || intMinimo==0) {

		if (varNumero < intMinimo) {
			alert(strMensajeLimite );
			bolRdoOnChange=false;
			return false;
		}
	}
	if (intMaximo != null && intMaximo!="") {

		if (varNumero > intMaximo) {
			alert(strMensajeLimite );
			bolRdoOnChange=false;
			return false;
		}
	}



	//varNumero contiene un número válido
	//Ajustar el número de decimales
	varCadena = varNumero + "";	//Para convertir un número en una cadena

	//En varCadena no se incluirá el signo
	if (varCadena.charAt(0) == "-") {
		varSigno = "-";
		varCadena = varCadena.substr(1);
	}else if(varCadena.charAt(0) == "+"){
		varSigno = "";
		varCadena = varCadena.substr(1);
	}else{
		varSigno = "";
	}

	//Coger la parte entera y decimal
	varI = varCadena.indexOf(".");
	if (varI == -1){
		varCadenaParteEntera = varCadena;
		varCadenaParteDecimal = "";
	}
	else{
		//Hay un punto
		varCadenaParteEntera = varCadena.substr(0, varI);
		varCadenaParteDecimal = varCadena.substr(varI +1, intNumDecimales);
	}

	//Añadir los ceros que hagan falta
	if (intNumDecimales > 0){
		while (varCadenaParteDecimal.length < intNumDecimales)
		{
			varCadenaParteDecimal = varCadenaParteDecimal + "0";
		}
	}

	//varCadena tiene el número sin formatear
	if (bolUsarFormatoMiles == true) {
		if (varCadenaParteEntera.length > 3) {
			varCadenaParteEnteraFormateada = varCadenaParteEntera.substr(varCadenaParteEntera.length - 3);
			for (varI = varCadenaParteEntera.length - 6; varI >= 0; varI = varI - 3) {
				varCadenaParteEnteraFormateada = varCadenaParteEntera.substr(varI, 3) + varSeparadorMiles + varCadenaParteEnteraFormateada;
			}
			if (varI > -3) {
				varCadenaParteEnteraFormateada = varCadenaParteEntera.substr(0, varI + 3) + varSeparadorMiles + varCadenaParteEnteraFormateada;
			}
			varCadenaParteEntera = varCadenaParteEnteraFormateada;
		}
	}

	if (intNumDecimales > 0){
		varCadena = varSigno + varCadenaParteEntera + strSeparadorDecimal + varCadenaParteDecimal;
	}
	else {
		varCadena = varSigno + varCadenaParteEntera;
	}

	obj.value = varCadena;


	bolRdoOnChange=true;
	return true;
}

// Recibe un string con el formato 99999,999999 y lo devuelve con el formato 99.999,99
function formatPuntos(cadena){

 var parteEnteraFormateada = "";
 var resultado = "";

 if (cadena.indexOf(",") == -1) {
  var parteEntera = cadena;
  var parteDecimal = ",00";
 }
 else {
  var parteEntera = cadena.substring(0,cadena.indexOf(","));
  var parteDecimal = cadena.substring(cadena.indexOf(","),cadena.length);
  while (parteDecimal.length < 3){
   parteDecimal = parteDecimal + "0";
  }
 }

 while (parteEntera.length > 3){
  parteEnteraFormateada = "." + parteEntera.substring(parteEntera.length - 3, parteEntera.length) + parteEnteraFormateada;
  parteEntera = parteEntera.substring(0, parteEntera.length - 3);
 }
 resultado = parteEntera + parteEnteraFormateada + parteDecimal.substring(0,3);
 return(resultado);

}

function MM_validateForm() { //v4.0
  var i,p,q,nm,test,num,min,max,errors='',args=MM_validateForm.arguments;
  for (i=0; i<(args.length-2); i+=3) { test=args[i+2]; val=MM_findObj(args[i]);
    if (val) { nm=val.name; if ((val=val.value)!="") {
      if (test.indexOf('isEmail')!=-1) { p=val.indexOf('@');
        if (p<1 || p==(val.length-1)) errors+='- '+nm+' must contain an e-mail address.\n';
      } else if (test!='R') { num = parseFloat(val);
        if (isNaN(val)) errors+='- '+nm+' must contain a number.\n';
        if (test.indexOf('inRange') != -1) { p=test.indexOf(':');
          min=test.substring(8,p); max=test.substring(p+1);
          if (num<min || max<num) errors+='- '+nm+' must contain a number between '+min+' and '+max+'.\n';
    } } } else if (test.charAt(0) == 'R') errors += '- '+nm+' is required.\n'; }
  } if (errors) alert('The following error(s) occurred:\n'+errors);
  document.MM_returnValue = (errors == '');
}


/*
* Función que valida que el código postal sea correcto
* y envía el formulario con los datos de la búsqueda
*/
function buscarSAT_MD(){
	var enviar="";
	if ( document.form_sat_MD.codigoPostal.value != ''){
		if(!esNumeroValido(document.form_sat_MD.codigoPostal.value)){
			return;
		}else{
			if (document.form_sat_MD.codigoPostal.value.length!=5){
				alert(satIntroducirCPValido);
				return;
			}
		}
	}
	

		if(document.form_sat_MD.actividad){
			if(document.form_sat_MD.actividad.value=="3"){
				var input1 = document.createElement('INPUT');
				input1.type = "hidden";
				input1.value = "3";
				input1.name = "aire";
				document.form_sat_MD.appendChild(input1);
			}else if(document.form_sat_MD.actividad.value=="1"){
				var input2 = document.createElement('INPUT');
				input2.type = "hidden";
				input2.value = "1";
				input2.name = "calefaccion";
				document.form_sat_MD.appendChild(input2);
			}else if(document.form_sat_MD.actividad.value=="2"){
				var input3 = document.createElement('INPUT');
				input3.type = "hidden";
				input3.value = "2";
				input3.name = "ACS";
				document.form_sat_MD.appendChild(input3);
			}
			
		
		}
		if(document.form_sat_MD.codigoPostal && document.form_sat_MD.codigoPostal.value!=""){
			document.form_sat_MD.action = ayudaPath + "sat_busqueda.jsp";
		}
		
		var seleccion = document.form_sat_MD.SELECCION;
		if (seleccion != null) {
			seleccion.value = "SERVICIOTECNICOPROF";
		} else {
			var input = document.createElement('INPUT');
			input.type = "hidden";
			input.value = "SERVICIOTECNICOPROF";
			input.name = "SELECCION";
			document.form_sat_MD.appendChild(input);
		}	
		document.form_sat_MD.submit();
	
}

/*	para evitar escribir target="_blank" en el html y que siga siendo accesible
	ejem: <a href="url" rel="external" title="title">enlace</a>
	llamada: window.onload=externalLinks;
*/
function externalLinks() {
	if (!document.getElementsByTagName) return;
	var anchors = document.getElementsByTagName("a");
	for (var i=0; i<anchors.length; i++) {
	   var anchor = anchors[i];
	   if (anchor.getAttribute("href") &&
	       anchor.getAttribute("rel") == "external")
	       anchor.target = "_blank";
	}
}