// Dependências: str.js.
//
// Rotinas para tratamento de nºs.

var KDecSep = ","
var KThouSep = "."
var KPrecisEuro = 2
// Determinar o separador decimal usado localmente.
var local_fracsep = 0.1
local_fracsep = local_fracsep.toString ().charAt (1)
var in_fracSep = ""    // Retorna-se aqui qual o sepatador de casas decimais (se algum) do seu argumento.
var err_badnum = false // Indica se a última conversão falhou.


// Converte 'str' para um inteiro. Se não for possível retorna 'optDef' ou -1.
function cvtInt (str, optDef) {
	var res = cvtNum (str, optDef)

	return err_badnum || in_fracSep ? optDef : res
}

// Retorna o nº a que 'str' corresponde. Se falhar, a função retorna 0 e coloca 'err_badnum' a 'true'.
// A função retorna um 'array' de dois elementos - o primeiro indica se a conversão foi possível, e o
// segundo o nº resultante.
function cvtNum (str, optDef) {
	var n = optDef
	if (!(err_badnum = !(str = isNumeric (trim (str))))) {
		// Converter o separador decimal, pois o JavaScript só reconhece um.
		if (in_fracSep != "" && in_fracSep != local_fracsep) str = str.replace (in_fracSep, local_fracsep)
		// Extraír valor.
		n = parseFloat (str)
	}
	return n
}

// Retorna 'false' se 'str' não for convertível para um nº. Caso contrário retorna 'str' (possívelmente corrigido).
// 'in_fracSep' retorna o separador de nºs decimais eventualmente utilizados.
// NOTA: 'str' deve ter passado por 'trim' antes.
function isNumeric (str) {
	in_fracSep = ""
	
	var i, n1 = 0, le = str.length - 1
	if (le < 0) return false
	for (i = 0; i <= le; ++i) {
		var ch = str.charAt (i)
		switch (ch) {
		// Números.
		case "0":
		case "1":
		case "2":
		case "3":
		case "4":
		case "5":
		case "6":
		case "7":
		case "8":
		case "9":
			break
		// Casas decimais.
		case ".":
		case ",":
			if (++n1 > 1) return false
			in_fracSep = ch
			break
		// Sinais.
		case "-":
		case "+":
			if (!le || (i && i != le)) return false

			i == le && (str = str.substr (le, 1) + str.substring (0, le))
			break
		// Outros caractéres.
		default:
			in_fracSep = ""
			return false
		}
	}
	return ch != "." && ch != "," ? str : false
}

// Retorna N arredondado a 'DECPLACES' (ou 2) casas decimais.
function round (n, optDecPlaces) {
	var dp = optDecPlaces == null ? 2 : optDecPlaces, factor = Math.pow (10, dp + 1)
	n = Math.round (n * factor) / factor	// Evita problemas, em N tem uma precisão ridículamente grande.
	factor = Math.pow (10, dp)

	return Math.round (n * factor) / factor
}

// Retorna a representação textual de N devidamente formatada.
function formatInt (n) {	return formatNum (n, KDecSep, KThouSep)	}

// Retorna a representação textual de NUM com 'optDecPlaces' casas decimais. Se 'optDecPlaces' for omitido assume-se 2.
function formatReal (num, optDecPlaces) {
	if (!optDecPlaces && optDecPlaces != 0) optDecPlaces = 2

	var n = Math.floor (num)
	var r = round (num - n, optDecPlaces), s
	if (!r)
		s = KDecSep + alignLeft ("0", optDecPlaces, "0")
	else
		s = alignLeft (r.toString ().substr (1), optDecPlaces + 1, "0")

	return formatInt (n) + s
}

// Retorna 'num' como texto formatado para Euros.
function formatEuros (num) { return "&euro;" + formatReal (num, KPrecisEuro) }

// Retorna a representação textual de 'num' devidamente formatada, com 'decsep' a separar as casas decimais e 'thousep' a separar
// os milhares.
function formatNum (num, decsep, thousep) {
	var s = num.toString (), res = ""
	local_fracsep != decsep && (s = s.replace (local_fracsep, decsep))

	var l = s.length
	do {
		l -= 3
		if (l < 1) break
		res = res + thousep + s.substr (l, 3) 
	} while (true)
	res = s.substr (0, l + 3) + res

	return res != "" ? res : s
}

// Retorna 'r' num formato indicado para passar ao servidor.
// REQUERE: num.vbs.
function asServReal (r) {
	r = r.toString ()
	return local_fracsep != rem_fracsep ? r.replace (local_fracsep, rem_fracsep) : r
}
