/**
 * @constructor Construtor do objeto, pode ser configurado ou nao.
 * 
 * @param array com os objetos de configuracao
 * 
 * sepDig:	separador de digitos do numero de entrada				Padrao: ""
 * sepDec:	separador decimal do numero de entrada					Padrao: ""
 * unidade:	unidade do numero use '#' para identificar a posicao	Padrao: ""
 * 			ex: "R$#", "#Kg" , "# coisa(s)".
 * neg:		formato do numero negativo, use '#' para identificar	Padrao: "-#"
 * 			a posicao
 * pos:		formato do numero positivo, use '#' para identificar	Padrao: "#"
 * 			a posicao
 * 
 * OBS: caso algum formato seja informado sem o #, este sera trocado pelo padrao
 * 
 * @author Ataxexe
 * @version 1.0
 * 
 * Data: 26/04/2006
 */
function Parser(params) {
	/**
	 * Funcao que converte um valor em float e devolve este valor, deve ser acessada pelo
	 * objeto Parser
	 * 
	 * a funcao pode ser chamada sem que os separadores sejam configurados, caso isso
	 * ocorra, ela faz a conversao com base em estimativas a fim de deduzir os separadores
	 * utilizados (somente no caso de ponto e virgula)
	 *
	 * @param {String} valor a ser convertido
	 * @return Float do valor ou NaN se for invalido
	 * 
	 * @author Ataxexe
	 */
	function toFloat(valor){
		if(typeof valor == "undefined"){return NaN;}
		var negativo = false;
		//checa se o numero e negativo
		var auxFmtNeg = this.formatoNegativo;
		var valorAux = valor.toString();
		for(var i = auxFmtNeg.length ; i >= 0 ; i--){
			valorAux = valorAux.replace(auxFmtNeg.charAt(i),"");
		}
		//verifica se o numero e realmente negativo
		if(auxFmtNeg.replace("#",valorAux) == valor){
			valor = valorAux.toString();
			negativo = true;
		}
		//checa se o numero e positivo
		else{
			var auxFmtPos = this.formatoPositivo;
			valorAux = valor.toString();
			for(var i = auxFmtPos.length ; i >= 0 ; i--){
				valorAux = valorAux.replace(auxFmtPos.charAt(i),"");
			}
			//verifica se o numero e realmente positivo
			if(auxFmtPos.replace("#",valorAux) == valor){
				valor = valorAux.toString();
			}
			else{
				//numero invalido
				return NaN;
			}
		}
		
		var indice = this.unidade.indexOf("#");
		
		if(indice != -1){
			var unidadeAux = this.unidade;
			//se o numero for colocado antes ou apos a unidade
			if(indice == this.unidade.length - 1 || indice == 0){
				valorAux = valor.replace(this.unidade.replace("#",""),"");
			}			
			//se o numero for colocado entre a unidade
			else{
				valorAux = valor.replace(this.unidade.substring(0,indice),"");
				valorAux = valorAux.replace(this.unidade.substring(indice + 1,this.unidade.length),"");
			}
			//checa se o numero apresenta unidade valida
			if(unidadeAux.replace("#",valorAux) === valor){
				valor = valorAux.toString();
			}
			else{
				//numero invalido
				return NaN;
			}
		}
		
		if(negativo){
			valor = "-".concat(valor);
		}
		
		//se forem passados os separadores-----------------
		var flag = false;
		
		if(this.separadorDigitos != ""){
			while(valor.indexOf(this.separadorDigitos) != -1){
				valor = valor.replace(this.separadorDigitos,"");
			}
			flag = true;
		}
		if(this.separadorDecimal != ""){
			if(valor.indexOf(this.separadorDecimal) != -1){
				valor = valor.replace(this.separadorDecimal,".");
			}
			flag = true;
		}
		//--------------------------------------------------
		
		var valorConvertido = parseFloat(valor);
		if(flag)return valorConvertido;
		
		//se nao forem passados os separadores--------------
		
		//Se os tamanhos forem iguais ou o numero for invalido, nao ha necessidade de manipulacao dos separadores do valor
		if((valorConvertido.toString().length == valor.toString().length) || isNaN(valorConvertido)){
			return valorConvertido;
		}
		else{
			//faz uma comparacao para saber qual e o identificador de casas decimais
			//os indices nunca serao iguais (-1) porque caso a string nao tenha ponto
			//nem virgula a conversao padrao foi bem sucedida
			var indicePonto = valor.indexOf(".");
			var indiceVirgula = valor.indexOf(",");
			
			//o ponto foi usado como separador de digitos e a virgula como separador de casas decimais
			if(indicePonto < indiceVirgula){
				//retirando os pontos
				
				while(valor.indexOf(".") != -1){
					valor = valor.replace(".","");
				}
				//trocando a virgula por ponto
				if(valor.indexOf(",") != -1){
					valor = valor.replace(",",".");
				}
				return parseFloat(valor);
			}
			//o ponto foi usado como separador de casas decimais e a virgula como separador de digitos
			else{
				//retirando as virgulas
				while(valor.indexOf(",") != -1){
					valor = valor.replace(",","");
				}
				return parseFloat(valor);
			}
		}
		//---------------------------------------------------
	}
	//funcao para armazenar as configuracoes padrao
	function param_default(pname, value) {
		//undefined significa que o atributo nao foi configurado
		if (typeof params[pname] == "undefined" || params[pname] == ""){
			params[pname] = value;
		}
	}
	//funcao para armazenar as configuracoes padrao de formato
	function format_default(pname, value) {
		//undefined significa que o atributo nao foi configurado
		if ((typeof params[pname] == "undefined") || (params[pname] == "") || (params[pname].toString().indexOf("#") == -1)){
			params[pname] = value;
		}
	}
	//funcao que gera o alerta de erro caso a configuracao seja mal sucedida
	function erroConfiguracao(){
		var msg = "Erro de configuracao do Parser:\n\n";
		msg += this.msgErro;
		alert(msg);
	}
	//caso o construtor seja chamado sem o parametro
	if(params == null){
		var params = new Object();
	}
	
	param_default("sepDig","");
	param_default("sepDec","");
	param_default("unidade","");
	format_default("neg","-#");
	format_default("pos","#");
	
	this.separadorDigitos = params["sepDig"];
	this.separadorDecimal = params["sepDec"];
	this.unidade = params["unidade"];
	this.formatoNegativo = params["neg"];
	this.formatoPositivo = params["pos"];
	this.msgErro = "";
	
	var erro = false;
	
	//os separadores nao podem ser iguais
	if((this.separadorDecimal == this.separadorDigitos) && this.separadorDecimal != ""){
		this.msgErro += "Os separadores sao iguais\n";
		erro = true;
	}
	//os formatos devem ser diferentes
	if(this.formatoNegativo == this.formatoPositivo){
		this.msgErro += "Os formatos sao iguais\n"
		erro = true;
	}
	//se houver erro de configuracao
	if(erro){
		this.toFloat = erroConfiguracao;
		return;
	}
	
	//a funcao so sera atribuida ao objeto se nao houver erro de configuracao
	this.toFloat = toFloat;
}
