//##------------------------------------------------------------------- 
// #FUNCIÓN: StrGetFront
// #CARACTERÍSTICAS: Devuelve el substring comprendido entre el principio
//                  del string y el separador buscado.
// #PARÁMETROS:	- mainStr: String dentro del cual buscamos.
//					             - searchStr: Separador que deseamos buscar.
// #DEVUELVE: El substring buscado, o null si no encontramos el separador.
//##------------------------------------------------------------------- 
function StrGetFront(mainStr,searchStr) {
var foundOffset = mainStr.indexOf(searchStr);

  foundOffset = mainStr.indexOf(searchStr);
  if (foundOffset == -1) return null
  
  return mainStr.substring(0, foundOffset)
}

//##------------------------------------------------------------------- 
// #FUNCIÓN: StrGetEnd
// #CARACTERÍSTICAS: Devuelve el substring comprendido entre el separador
//                  buscado y el final de la cadena.
// #PARÁMETROS:	- mainStr: String dentro del cual buscamos.
//								- searchStr: Separador que deseamos buscar.
// #DEVUELVE: El substring buscado, o null si no encontramos el separador.
//##------------------------------------------------------------------- 
function StrGetEnd(mainStr,searchStr) {
var foundOffset;

  foundOffset = mainStr.indexOf(searchStr);
  if (foundOffset == -1) return null
  
  return mainStr.substring(foundOffset+searchStr.length,mainStr.length)
}
//---------------------------------------------------------------------
// FUNCIÓN: BCompruebaRequerido
// CARACTERÍSTICAS: Comprueba que el objeto tenga algún valor relleno.
//		Si no es así genera el error adecuado y da el foco al elemento.
// PARÁMETROS: - obj: Objeto que queremos comprobar.
//            - str: Mensaje a mostrar
// DEVUELVE: Si el objeto tiene algo devuelve true. Sino false.
//---------------------------------------------------------------------
function BCompruebaRequerido(obj, str) {
	
	// Si el objeto no tiene ningún valor...
	if (obj.value == "") {
		// Damos el mensaje y el foco al elemento
		alert(str);
		obj.focus();
		return false;
	}
	return true;
}
//##------------------------------------------------------------------- 
// #FUNCIÓN: BValidaNumeroEnteroPos
// #CARACTERÍSTICAS: Comprueba que el valor introducido es entero.
// #PARÁMETROS: - obj: Input que contiene el valor a validar.
// #DEVUELVE: Valor booleano que indica si el valor es correcto.
//##------------------------------------------------------------------- 
function BValidaNumeroEnteroPos(obj){
var msg = "El campo debe ser un número entero"
var ch;

	// El campo puede estar vacio
	if ((obj.value.length == 0) || (obj.value == null)) 
		return true;

	// Recorremos cada caracter...
	for (var i=0; i<obj.value.length; i++) {
		ch = obj.value.substring(i, i+1);
		// Comprobamos que sea un dígito
		if (ch < "0" || ch > "9") {     
			alert(msg);
			obj.value = "";
			obj.focus();
			return false;
		}
	}
	// Asignamos el valor entero (quitar 001, p.e)
	obj.value = parseInt(obj.value, 10);
  
	return true;
}

//##------------------------------------------------------------------- 
// #FUNCIÓN: BValidaNumeroOnPress
// #CARACTERÍSTICAS: Función para ser llamada en el evento onPressDown
//                  de los INPUTS. Comprueba que el valor introducido 
//                  sea un número con las características indicadas.
// #PARÁMETROS: - obj: Input que contiene el valor a comprobar.
//             - bNegativo: Valor booleano que con true permite el 
//                          símbolo '-' como primer caracter.
//             - nDec: Número de decimales que vamos a permitir
//                     (< 0 para indicar que pueden ser infinitos).
// #DEVUELVE: Valor booleano que indica si la tecla pulsada es correcta.
//           (Sirve para evitar que se escriba la letra -> Evento onKeyDown).
// #OBSERVACIONES: OJO!!!!: La llamada se debe realizar en los eventos onKeyDown,
//          onClick y onFocus. Esto es debido a que necesitamos saber
//          la posición del cursor en cada instante dentro del INPUT.
//          Por desgracia JScript no permite saber este valor por
//          lo que hay que hacerlo a 'pelo'. Por lo tanto necesitamos saber
//          cuando se entra en el INPUT para realizar la inicialización
//          de la variable que almacena la posición del cursor.
//          ESTO SERÍA MÁS SENCILLO SI PODEMOS OBTENER LA POSICIÓN DEL
//          CURSOR A LA HORA DE APRETAR LA TECLA.
//##------------------------------------------------------------------- 
function BValidaNumeroOnPress(obj, bNegativo, nDec){
var posComa;

	// Controlamos el evento que provocó la llamada...
	if ( (event.type == "click") || (event.type == "focus") ) {
		// Seleccionamos el texto e inicializamos la posición del cursor
		obj.select();
		posCursor = -1;
		return true;
	}
  
	// Hemos pulsado una tecla...
  
	// PULSAMOS '<-'...
	if (event.keyCode == 37) {
		if (posCursor == -1) posCursor = 0;
			if (posCursor > 0) 
				posCursor--;
		return true;
	}
	// PULSAMOS '->'...
	if (event.keyCode == 39) {
		if (posCursor == -1) 
			posCursor = obj.value.length;
		if (posCursor < obj.value.length) 
			posCursor++;
		return true;
	}
	// PULSAMOS 'Inicio'...
	if (event.keyCode == 36 ) {
		posCursor = 0;
		return true;
	} 
	// PULSAMOS 'Fin'...
	if (event.keyCode == 35) {
		posCursor = obj.value.length;
		return true;
	}
	// PULSAMOS 'Supr'...
	if (event.keyCode == 46) {
		if (posCursor == -1) 
			posCursor = 0;
		return true;
	}
	// PULSAMOS 'Del'...
	if (event.keyCode == 8) {
		if (posCursor == -1) 
			posCursor = 0;
		if (posCursor > 0) 
			posCursor--;
		return true;
	}
	// PULSAMOS 'Tab'...
	if (event.keyCode == 9) 
		return true;
  
	// PULSAMOS '-'...
	if ( (event.keyCode == 189) || (event.keyCode == 109)) {
		if (posCursor == -1) {
			if (bNegativo) {
				posCursor = 1;
				return true;
			}
		}
		else {
			// Permitimos el '-' si estamos con números negativos y estamos con el cursor 
			// en la posición 0 (y no haya ya un '-')
			if ( (bNegativo) && (posCursor == 0) && (obj.value.indexOf("-") == -1) ) {
				posCursor++;
				return true;
			}
		}
	}
	// PULSAMOS ',' o '.'...
	else 
		if ( (event.keyCode  == 188) || (event.keyCode  == 190) || (event.keyCode == 110 ) ) {
			if (posCursor == -1) {
				if (nDec != 0) {
					posCursor = 1;
					return true;
				}
			}
			else {
				// Permitimos la coma si estamos con números decimales y no tenemos coma
				posComa = obj.value.indexOf(".");
				if (posComa == -1) 
					posComa = obj.value.indexOf(",");
				if ( (posComa == -1) && ( (nDec < 0) || ( (nDec > 0) && (obj.value.length - posCursor -1 < nDec) ) ) ) {
					posCursor++;
				return true;
			}
		}
	}
	// PULSAMOS UN DÍGITO...
	else 
		if ( ( (event.keyCode >= 48) && (event.keyCode <= 57) ) || ( (event.keyCode >= 96) && (event.keyCode <= 105) ) ) {
			if (posCursor == -1) {
				posCursor = 1;
				return true;
			}
			else {
				// Si estamos en la primera posición y hay un signo '-', no permitimos el dígito...
				if ( (posCursor == 0) && (obj.value.indexOf("-") != -1)) 
					return false;

				// Permitimos el dígito si...      
				// estamos en la parte entera o si estamos en la decimal y aún no tenemos el número de 
				// decimales adecuadosla coma si estamos con números decimales y no tenemos el número de decimales adecuado 
				posComa = obj.value.indexOf(".");
				if (posComa == -1) 
					posComa = obj.value.indexOf(",");
				if (posComa == -1) 
					posComa = obj.value.length;
				if ( (nDec <= 0) || ( (nDec > 0) && ( (posCursor <= posComa) || (obj.value.length - posComa -1 < nDec) ) ) ) {
					posCursor++;
				return true;
			}
		}
	}

	// Si llegamos aquí, significa que el caracter no es válido
	return false;  
}

//##------------------------------------------------------------------- 
// #FUNCIÓN: StrFormatoNumerico
// #CARACTERÍSTICAS: Pasa un número al formato especificado.
// #PARÁMETROS: - strNumber: Cadena que contiene el número al cual queremos dar formato.
//             - strFormato: Cadena que indica el formato a dar a un número.
//				- simbolo: Indica si el símbolo decimal es una coma (0) o un punto (1).
// #DEVUELVE: La cadena formateada.
// #OBSERVACIONES: * Se supone que strNumber ya tiene un formato de número
//                  (no se realiza ninguna comprobación).
//					* Si el número de enteros del número es mayor al especificado
//                  en el formato, se dejan los que tenga el número.
//					* Si el número de decimales del número es mayor al especificado
//                  en el formato, se redondea al valor especificado en el formato.
//					MEJORAS: Permitir dar formato a números negativos.
// #EJEMPLOS:
//						Ej: '000,00' --> Tres números enteros y dos decimales.
//						'00' --> Dos número enteros (si el número tiene decimales, los deja igual).
//						'00,' --> Dos número enteros (si el número tiene tiene decimales, los redondea).
//						',000' --> Tres números decimales (la parte entera se queda igual).
//						'.00' --> Dos números decimales con el símbolo a 1
//##------------------------------------------------------------------- 
function StrFormatoNumerico(strNumber, strFormato, simbolo){
var strNumber_limpio, ch;
var factor, buf;
var EnterosN, DecimalesN, nEnterosF, nDecimalesF;

	// Quitamos todos los caracteres que no sean comas, puntos o dígitos
	strNumber_Limpio = "";
	for (var i=0; i<strNumber.length; i++) {
		ch = strNumber.charAt(i);
		if ( (ch == ",") || (ch == ".") || ( (ch >= "0") && (ch <= "9") ) ) 
			strNumber_Limpio += ch;
	}
	strNumber = strNumber_Limpio;

	// Si no hay nada, salimos sin dar formato
	if (strNumber == "") 
		return "";


	// Comprobamos si queremos que el símbolo decimal sea coma o punto
	if (simbolo == 0)  {
		// ¡¡¡ COMAS !!!
		// Cambiamos los puntos por comas
		while (strNumber.indexOf(".") != -1) 
			strNumber = strNumber.replace(".", ",");
	  
		// Quitamos todos las comas que están después de la primera (si la hay)...
		if (strNumber.indexOf(",") != -1) {
			buf = StrGetEnd(strNumber, ",");
			while (buf.indexOf(",") != -1) 
				buf = buf.replace(",", "");
			strNumber = StrGetFront(strNumber, ",") + "," + buf;
		}

		// Buscamos el número de enteros y decimales especificado en el número
		if (StrGetFront(strNumber, ",") == null) {
			// No se ha especificado el número de decimales
			DecimalesN = "";
			EnterosN = String(parseInt(strNumber, 10));
		} 
		else {
			// Se ha especificado el separador decimal
			if (StrGetFront(strNumber, ",") == "") 
				strNumber = "0" + strNumber;
			EnterosN = String(parseInt(StrGetFront(strNumber, ","), 10));
			DecimalesN = StrGetEnd(strNumber, ",");
		}

		// Buscamos el número de enteros y decimales especificado en el formato
		if (StrGetFront(strFormato, ",") == null) {
			// No se ha especificado números decimales
			nDecimalesF = 0
			nEnterosF = Math.max(strFormato.length, EnterosN.length);
		}
		else {
			// Se ha especificado el separador decimal
			nDecimalesF = StrGetEnd(strFormato, ",").length;    
			nEnterosF = Math.max(StrGetFront(strFormato, ",").length, EnterosN.length);
		}

		// Damos el formato adecuado a la parte entera...
		// Si el número de valores a poner es mayor al actual...
		if (nEnterosF > EnterosN.length) {
			// Insertamos el resto del tamaño con ceros
			buf = "";
			for (var i=0; i<(nEnterosF-EnterosN.length); i++) 
				buf += "0";
			EnterosN = buf + EnterosN;
		}

		// Damos el formato adecuado a la parte decimal...
		if (StrGetEnd(strFormato, ",") != null) {
			// Si el número de decimales es mayor al indicado en el formato...
			if (DecimalesN.length > nDecimalesF) {
				// Redondeamos al número de decimales indicado
				factor = Math.pow(10, DecimalesN.length - nDecimalesF);
				DecimalesN = String(Math.round(eval(DecimalesN) / factor));
				// Por si acaso no queremos poner decimales (sumar a la parte entera el redondeo)...
				if (nDecimalesF == 0) {
					EnterosN = String(parseInt(EnterosN, 10) + parseInt(DecimalesN, 10));
					DecimalesN = 0;
				}
			} 
			else {
				// El número de decimales actual es menor o igual al indicado (rellenamos el resto con ceros)
				buf = "";
				for (var i=0; i<(nDecimalesF-DecimalesN.length); i++) 
					buf += "0";
				DecimalesN += buf;
			}    
		}
	  
		// Devolvemos la composición del número
		if (DecimalesN.length > 0) 
			buf = EnterosN + "," + DecimalesN;
		else 
			buf = EnterosN;
	}
	else  {
	// ¡¡¡ PUNTOS !!!
		// Cambiamos las comas por los puntos
		while (strNumber.indexOf(",") != -1) 
			strNumber = strNumber.replace(",", ".");
	  
		// Quitamos todos los puntos que estén después del primero (si los hay)...
		if (strNumber.indexOf(".") != -1) {
			buf = StrGetEnd(strNumber, ".");
			while (buf.indexOf(".") != -1) 
				buf = buf.replace(".", "");
			strNumber = StrGetFront(strNumber, ".") + "." + buf;
		}

		// Buscamos el número de enteros y decimales especificado en el número
		if (StrGetFront(strNumber, ".") == null) {
			// No se ha especificado el número de decimales
			DecimalesN = "";
			EnterosN = String(parseInt(strNumber, 10));
		} 
		else {
			// Se ha especificado el separador decimal
			if (StrGetFront(strNumber, ".") == "") 
				strNumber = "0" + strNumber;
			EnterosN = String(parseInt(StrGetFront(strNumber, "."), 10));
			DecimalesN = StrGetEnd(strNumber, ".");
		}

		// Buscamos el número de enteros y decimales especificado en el formato
		if (StrGetFront(strFormato, ".") == null) {
			// No se ha especificado números decimales
			nDecimalesF = 0
			nEnterosF = Math.max(strFormato.length, EnterosN.length);
		}
		else {
			// Se ha especificado el separador decimal
			nDecimalesF = StrGetEnd(strFormato, ".").length;    
			nEnterosF = Math.max(StrGetFront(strFormato, ".").length, EnterosN.length);
		}

		// Damos el formato adecuado a la parte entera...
		// Si el número de valores a poner es mayor al actual...
		if (nEnterosF > EnterosN.length) {
			// Insertamos el resto del tamaño con ceros
			buf = "";
			for (var i=0; i<(nEnterosF-EnterosN.length); i++) 
				buf += "0";
			EnterosN = buf + EnterosN;
		}

		// Damos el formato adecuado a la parte decimal...
		if (StrGetEnd(strFormato, ".") != null) {
			// Si el número de decimales es mayor al indicado en el formato...
			if (DecimalesN.length > nDecimalesF) {
				// Redondeamos al número de decimales indicado
				factor = Math.pow(10, DecimalesN.length - nDecimalesF);
				DecimalesN = String(Math.round(eval(DecimalesN) / factor));
				// Por si acaso no queremos poner decimales (sumar a la parte entera el redondeo)...
				if (nDecimalesF == 0) {
					EnterosN = String(parseInt(EnterosN, 10) + parseInt(DecimalesN, 10));
					DecimalesN = 0;
				}
			} 
			else {
				// El número de decimales actual es menor o igual al indicado (rellenamos el resto con ceros)
				buf = "";
				for (var i=0; i<(nDecimalesF-DecimalesN.length); i++) 
					buf += "0";
				DecimalesN += buf;
			}    
		}
	  
		// Devolvemos la composición del número
		if (DecimalesN.length > 0) 
			buf = EnterosN + "." + DecimalesN;
		else 
			buf = EnterosN;
	}
	return buf;
}

//##------------------------------------------------------------------- 
// #FUNCIÓN: replaceSubstring
// #CARACTERÍSTICAS: Reemplaza subcadenas de una cadena por otra subcadena
//##------------------------------------------------------------------- 
function replaceSubstring(inputString, fromString, toString) {
   // Goes through the inputString and replaces every occurrence of fromString with toString
   var temp = inputString;
   if (fromString == "") {
      return inputString;
   }
   if (toString.indexOf(fromString) == -1) { // If the string being replaced is not a part of the replacement string (normal situation)
      while (temp.indexOf(fromString) != -1) {
         var toTheLeft = temp.substring(0, temp.indexOf(fromString));
         var toTheRight = temp.substring(temp.indexOf(fromString)+fromString.length, temp.length);
         temp = toTheLeft + toString + toTheRight;
      }
   } else { // String being replaced is part of replacement string (like "+" being replaced with "++") - prevent an infinite loop
      var midStrings = new Array("~", "`", "_", "^", "#");
      var midStringLen = 1;
      var midString = "";
      // Find a string that doesn't exist in the inputString to be used
      // as an "inbetween" string
      while (midString == "") {
         for (var i=0; i < midStrings.length; i++) {
            var tempMidString = "";
            for (var j=0; j < midStringLen; j++) { tempMidString += midStrings[i]; }
            if (fromString.indexOf(tempMidString) == -1) {
               midString = tempMidString;
               i = midStrings.length + 1;
            }
         }
      } // Keep on going until we build an "inbetween" string that doesn't exist
      // Now go through and do two replaces - first, replace the "fromString" with the "inbetween" string
      while (temp.indexOf(fromString) != -1) {
         var toTheLeft = temp.substring(0, temp.indexOf(fromString));
         var toTheRight = temp.substring(temp.indexOf(fromString)+fromString.length, temp.length);
         temp = toTheLeft + midString + toTheRight;
      }
      // Next, replace the "inbetween" string with the "toString"
      while (temp.indexOf(midString) != -1) {
         var toTheLeft = temp.substring(0, temp.indexOf(midString));
         var toTheRight = temp.substring(temp.indexOf(midString)+midString.length, temp.length);
         temp = toTheLeft + toString + toTheRight;
      }
   } // Ends the check to see if the string being replaced is part of the replacement string or not
   return temp; // Send the updated string back to the user
}


