// Hecho por el Moi.

/************************************************************
 * Constructor de nuestro objeto formato, con él			*
 * podemos dar formato numérico a una cadena de texto.		*
 *															*
 * Sólo se permite el uso de números en la cadena.			*
 *															*
 * El argumento groupSymbol indica cuál es el carácter		*
 * de separador de miles ('.' por defecto).					*
 *															*
 * El argumento decimalSymbol indica cuál es el carácter	*
 * de separador de dimales (',' por defecto).				*
 *															*
 * El argumento positivo (boolean) indica si el número		*
 * permitirá el uso de signo ('false') o no ('true').		*
 ************************************************************/
function Format (groupSymbol,decimalSymbol,positivo) {
	// Valores por defecto
	if (positivo == null)
		this.positivo = true;
	else
		this.positivo = positivo;
	
	if (decimalSymbol == null)	
		this.decimal = ",";		// Separador decimal por defecto.
	else
		this.decimal = decimalSymbol;
		
	if (groupSymbol == null)
		this.group = ".";
	else
		this.group = groupSymbol;	
		
	this.numeroDecimales = -1;		// -1 = Todos los que quieras		

	this.formatString = FormatFormatString;		
	this.removeGroupSym = FormatRemoveGroupSym;
	this.validar = FormatValidateNumber;
	this.changeFormat = FormatChangeFormat;
}


/****************************************************
 * Función que da formato a una cadena, siguiendo	*
 * las especificaciones dadas en el constructor del	*
 * objeto.											*
 ****************************************************/
function FormatFormatString (cadena) {
	// Comprobamos los argumentos.
	if (cadena == null || cadena == "")
		return "";
		
	var signo;
	
	// Primeramente quitamos el signo (Si el número es marcado como no negativo).
	if (!this.positivo) {
		signo = cadena.charAt(0);
		if (signo == '+' || signo == '-')
			cadena = cadena.substring(1,cadena.length);
		else
			signo = "";
	}
	else {
		signo = "";
	}
		
	// Seguidamente eliminamos todos los caracteres de grupo, letras y otras cosas.
	var cadena_sin_caracter_grupo = "";
	var caracter;
		
	for (var i = 0; i < cadena.length; i++) {
		caracter = cadena.substring(i,i+1);
		if (((caracter >= "0") && (caracter <= "9")) || caracter == this.decimal) {
			cadena_sin_caracter_grupo += caracter;
		}
	}
	
	// Quitamos 0's iniciales.
	var continuar = true;
	while (continuar) {
		caracter = cadena_sin_caracter_grupo.charAt(0);
		if (caracter == "0") {
			// Si la cadena tiene longitud 1, lo permitimos.
			if (cadena_sin_caracter_grupo.length == 1)
				continuar = false;
			else
				cadena_sin_caracter_grupo = cadena_sin_caracter_grupo.substring(1,cadena_sin_caracter_grupo.length);
		}
		else {
			if (caracter == this.decimal) {
				cadena_sin_caracter_grupo = "0" + cadena_sin_caracter_grupo;
			}
			
			continuar = false;		
		}
		
	}
	
	
	// Damos formato a la cadena.
	var cadena_con_formato;
	var cadena_decimal = "";
	
	// Si tiene caracter decimal, vamos buscándolo.
	var indice_decimal = cadena_sin_caracter_grupo.lastIndexOf(this.decimal);
	if (indice_decimal != -1) {
		cadena_decimal = cadena_sin_caracter_grupo.substring(indice_decimal,cadena_sin_caracter_grupo.length);
	}
	else {
		indice_decimal = cadena_sin_caracter_grupo.length;
	}
	
	cadena_con_formato = cadena_decimal;	
		
	var poner_punto = 1;
	for (var j = indice_decimal; j > 0; j--,poner_punto++) {
		cadena_con_formato = cadena_sin_caracter_grupo.substring(j-1,j) 
									+ cadena_con_formato;

		if ((poner_punto == 3) && (j != 1)) {
			poner_punto = 0;
			cadena_con_formato = this.group + cadena_con_formato;
		}
	}
	
	// Añadimos el signo si lo tiene.
	if (signo != "")
		cadena_con_formato = signo+cadena_con_formato;

	// Vemos el número de decimales para la cadena.
	indice_decimal = cadena_con_formato.lastIndexOf(this.decimal);
	if (indice_decimal != -1) {
		// La cadena tiene decimales.
		if (this.numeroDecimales == 0)
			// No queremos decimales
			return cadena_con_formato.substring(0,indice_decimal);

		if (this.numeroDecimales < 0)
			// Queremos todos los decimales.
			return cadena_con_formato;

		// Hay un número determinado de decimales.
		decimalesActuales = cadena_con_formato.length - indice_decimal - 1;
		
		if (decimalesActuales <= this.numeroDecimales) {
			// Rellenamos con 0's.
			for (var i = decimalesActuales; i < this.numeroDecimales; i++)
				cadena_con_formato += "0";
				
			return cadena_con_formato;		
		}
		else
			return cadena_con_formato.substring(0,indice_decimal + this.numeroDecimales + 1);
		
	}
	else {
		// Añadimos el separador decimal.
		cadena_con_formato += this.decimal;
				
		// Rellenamos con 0's.
		for (var i = 0; i < this.numeroDecimales; i++)
			cadena_con_formato += "0";
	
		return cadena_con_formato;	
	}
	
	return cadena_con_formato;	
}

/************************************************
 * Metodo para validar números con formato.	*
 ************************************************/
function FormatValidateNumber(cadena) {
	// Comprobamos los argumentos.
	if (cadena == null ||cadena == "")
		return false;

	var signo;
	// Primeramente quitamos el signo (Si el número es marcado como no negativo).
	if (!this.positivo) {
		signo = cadena.charAt(0);
		if (signo == '+' || signo == '-')
			cadena = cadena.substring(1,cadena.length);
		else
			signo = "";
	}
	else {
		signo = cadena.charAt(0);
		if (signo == '+' || signo == '-')
			return false;	// Número no tiene que tener signo.
		else
			signo = "";

	}


	var indice_decimal = cadena.indexOf(this.decimal);
	var numero_entero = cadena.substring(0,(indice_decimal == -1) ? cadena.length : indice_decimal );
	var numero_decimal = (indice_decimal == -1) ? "" : cadena.substring(indice_decimal+1,cadena.length);
	
	if (indice_decimal != -1 && numero_decimal == "")
		return false;

	// En la cadena entera, podemos tener el separador de miles o no tenerlo.
	//  Si lo tenemos, tiene que estar en las posiciones correctas.
	var hayGrupo = "";
	var indice_simbolo = 0;
	for (var i = numero_entero.length-1; i >= 0; i--,indice_simbolo++) {
		if (indice_simbolo != 0 && (indice_simbolo % 3 == 0)) {
			if (hayGrupo == "" && numero_entero.charAt(i) == this.group)
				hayGrupo = true;
			if (hayGrupo == "" && numero_entero.charAt(i) != this.group)
				hayGrupo = false;
			if (hayGrupo && numero_entero.charAt(i) != this.group)
				return false;
			if (!hayGrupo && isNaN(numero_entero.charAt(i)))
				return false;
			
			indice_simbolo = -1;				
		}
		else {
			if (isNaN(Number(numero_entero.charAt(i))))
				return false;
		}
	}

	// En la cadena decimal, no tiene que haber ningún símbolo.
	for (i = 0; i < numero_decimal.length; i++)
		if (isNaN(Number(numero_decimal.charAt(i))))
			return false;

	// Aceptamos la cadena como con formato correcto.
	return true;
	
	
}

/****************************************************
 * Metodo para intercambiar un número de un formato	*
 * a otro, sin cambiar el estado del objeto.		*
 *													*
 * Si la cadena no es válida para el formato actual	*
 * el valor de retorno es "".						*
 ****************************************************/
 function FormatChangeFormat(cadena,groupSym,decimalSym) {
	if (!this.validar(cadena))
		return "";
		
	if (arguments.length != 3)
		return "";
		
	var resultado = "";
	
	for (var i = 0; i < cadena.length; i++) {
		if (cadena.charAt(i) == this.decimal) {
			resultado += decimalSym;
		}
		else {
			if (cadena.charAt(i) == this.group) {
				resultado += groupSym;
			}
			else {
				resultado += cadena.charAt(i);
			}
		}
	}
	
	return resultado;
 }

/********************************************************
 * Metodo que nos elimina de la cadena el carácter de	*
 * separador de miles.									*
 ********************************************************/
function FormatRemoveGroupSym(cadena) {
	// Comprobamos los argumentos.
	if (cadena == null || cadena == "")
		return "";
		
	// Primeramente quitamos el signo (Si el número es marcado como no negativo).
	if (!this.positivo) {
		signo = cadena.charAt(0);
		if (signo == '+' || signo == '-')
			cadena = cadena.substring(1,cadena.length);
		else
			signo = "";
	}
	else {
		signo = "";
	}
	
	// Seguidamente eliminamos todos los caracteres de grupo, letras y otras cosas.
	var cadena_sin_caracter_grupo = "";
	var caracter;
		
	for (var i = 0; i < cadena.length; i++) {
		caracter = cadena.substring(i,i+1);
		if (((caracter >= "0") && (caracter <= "9")) || caracter == this.decimal) {
			cadena_sin_caracter_grupo += caracter;
		}
	}
	
	// Añadimos el signo si lo tiene.
	if (signo != "")
		cadena_sin_caracter_grupo = signo+cadena_sin_caracter_grupo;
	
	return cadena_sin_caracter_grupo;			
	
}

// Información sobre el navegador.
var explorer;
if (navigator.appName == "Netscape")
	explorer = false;
else
	explorer = true;

/************************************************************
 * Función llamada cuando queramos formatear una cadena.	*
 *															*
 * En este caso estamos usando el '.' como separador de		*
 * miles y la ',' como separador decimal.					*
 *															*
 * Además no se permite el uso de signo en el campo.		*
 ************************************************************/ 
function Formatear (obj,positivo,decimales) {
	formato = new Format(".",",",positivo);	
	if (decimales != null)
		formato.numeroDecimales = decimales;
	obj.value = formato.formatString(obj.value);
}

/************************************************************
 * Función llamada para quitar los caracteres de separador	*
 * de miles, útil para Netscape.							*
 ************************************************************/
function QuitaMiles (obj,positivo) {
	formato = new Format(".",",",positivo);
	obj.value = formato.removeGroupSym(obj.value);
}

// Posicionamiento del cursor al final de la caja de texto (sólo IE).
function GotoFin(obj) {
	if (!explorer) {
		obj.blur();
		obj.focus();
		return false;
	}
	
	var cadena = obj.value;
	obj.value = cadena;
	return true;
}

/************************************************************
 * Crea un objeto input de tipo text, para el uso con el	*
 * objeto Format y dependiendo del navegador.				*
 *															*
 * Parámetros:												*
 *	nombre:		Nombre que tendrá el input. (Atributo Name).*
 *	valor:		Valor que tendrá el input. (Atributo Value).*
 *	signo:		Indica si el número aceptará signo o no.	*
 *	decimales:	Número de decimales que admite la caja.		*
 *	clase:		Valor de clase del componente.				*
 ************************************************************/
function createTextField (nombre,valor,positivo,decimales,clase,size) {
	if (!size)
		size = 10;

	document.write ("<INPUT maxlength='15' TYPE='text' ID='"+nombre+"' NAME='"+nombre+"' size='"+size+"' class='"+clase+"' VALUE='"+valor+"'\n\r");
	
		document.write ("onfocus='QuitaMiles(this,"+positivo+");this.select();'\r\n");
		document.write ("onChange='Formatear(this,"+positivo+","+decimales+");return true'\r\n");
		document.write ("onBlur='Formatear(this,"+positivo+","+decimales+");return true'>");

}

