/**
 * Arredonda 'number' de acordo com o valor de 'numdec'.
 * @author Willian Fernandes (willian@visie.com.br)
 * @param number Número que sera arredondado
 * @param numdec Número de casas decimais
 * @returns {float} Número arredondado.
 */
function round_number(number, numdec)
{
    if (isNaN(numdec) || numdec == '' || parseInt(numdec, 10) < 0)
        numdec = 0;
    else
        numdec = parseInt(numdec);

    if (isNaN(number) || number == "")
    {
        if (number.indexOf(",") != -1)
            number = number.replace(",", ".");
        else
            number = 0;
    }

    return Math.round(number * Math.pow(10, numdec)) / Math.pow(10, numdec);
}

/**
 * Formata 'number' no padrão informado.
 * @author Willian Fernandes (willian@visie.com.br)
 * @param number Número que sera arredondado.
 * @param numdec Número de casas decimais.
 * @param sepmil Caracter separador de milhar.
 * @param sepdec Caracter separador decimal.
 * @returns {string} Número formatado.
 */
function format_number(number, numdec, sepmil, sepdec)
{
    //Verificando parâmetros opcionais
    if (numdec == undefined || isNaN(numdec) || numdec == "" || parseInt(numdec, 10) < 0)
        numdec = 2;
    else if (parseInt(numdec, 10) > 10)
        numdec = 10;
    if (sepmil == undefined)
        sepmil = "";
    if (sepdec == undefined || sepdec == "" || sepdec.length > 1)
        sepdec = ".";

    //Variáveis da função
    var number_round = (round_number(number, numdec).toString()).split(".");

    //Mesclando zeros com o valor decimal atual, caso exista um
    if (number_round[1] == undefined)
        number_round[1] = "";

    number_round[1] = (number_round[1] + "0000000000").substring(0, numdec);

    //Formatando os milhares
    if (sepmil != "" && number_round[0].length > 3)
    {
        var result = "";
        for (var i=0; i<number_round[0].length; i=i+3)
        {
            var index1 = number_round[0].length-i;
            var index2 = number_round[0].length-(i-1);
            var index3 = number_round[0].length-(i-2);

            if (number_round[0][index1] != undefined)
                result = number_round[0][index1] + result;
            if (number_round[0][index2] != undefined)
                result = number_round[0][index2] + result;
            if (number_round[0][index3] != undefined)
                result = "." + number_round[0][index3] + result;
        }
    }

    //Formatando o número
    return number_round[0] + sepdec + number_round[1];
}

/**
 * Verifica se o cpf está no formato válido, e se os números são válidos.
 * Aceita os formatos 012.345.678-90 ou 01234567890.
 * @author Willian Fernandes (willian@visie.com.br)
 * @param cpf String que contém o CPF que será validado
 * @returns {boolean}
 */
function verificaCPF(cpf)
{
    var oRegExp = /\d{3}\.?\d{3}\.?\d{3}\-?\d{2}/;
    var soma1 = 0;
    var soma2 = 0;
    var resto;

    //Verifica se o CPF está em um formato válido.
    if (oRegExp.test(cpf))
    {
        //Retira os pontos (.) e o traço (-).
        cpf = cpf.replace(/\.|-/gi, "");

        //Somando os 9 primeiros dígitos.
        for (var i = 0; i < 9; i++)
        {
            soma1 += parseInt(cpf.charAt(i), 10) * (10 - i);
            soma2 += parseInt(cpf.charAt(i), 10) * (11 - i);
        }
        soma2 += parseInt(cpf.charAt(9), 10) * 2;

        resto = 11 - (soma1 % 11);

        if (resto == 10 || resto == 11)
            resto = 0;

        if (resto != parseInt(cpf.charAt(9)))
            return false;

        resto = 11 - (soma2 % 11);

        if (resto == 10 || resto == 11)
            resto = 0;

        if (resto != parseInt(cpf.charAt(10)))
            return false;
    }
    else
    {
        return false;
    }
    return true;
}

/**
 * Verifica se o CNPJ está no formato válido, e se os números são válidos.
 * Aceita os formatos 01.234.567/8901-23 ou 01234567890123.
 * @author Willian Fernandes (willian@visie.com.br)
 * @param cnpj String que contém o CNPJ que será validado.
 * @returns {boolean}
 */
function verificaCNPJ(cnpj)
{
    var oRegExp = /\d{2}\.?\d{3}\.?\d{3}\/?\d{4}\-?\d{2}/;
    var soma1 = 0;
    var soma2 = 0;
    var resto;
    var digito;
    var digito1;
    var digito2;
    var digito_tmp = "";

    //Verifica se o CNPJ está em um formato válido.
    if (oRegExp.test(cnpj))
    {
        //Retira os pontos (.), as barra (/) e o traço (-).
        cnpj = cnpj.replace(/\.|\/|\-/gi, "");
        digito_tmp = cnpj.substring(cnpj.length-2, cnpj.length);

        //Calculando o primeiro dígito verificador.
        soma1 += parseInt(cnpj.charAt(0), 10) * 5;
        soma1 += parseInt(cnpj.charAt(1), 10) * 4;
        soma1 += parseInt(cnpj.charAt(2), 10) * 3;
        soma1 += parseInt(cnpj.charAt(3), 10) * 2;
        soma1 += parseInt(cnpj.charAt(4), 10) * 9;
        soma1 += parseInt(cnpj.charAt(5), 10) * 8;
        soma1 += parseInt(cnpj.charAt(6), 10) * 7;
        soma1 += parseInt(cnpj.charAt(7), 10) * 6;
        soma1 += parseInt(cnpj.charAt(8), 10) * 5;
        soma1 += parseInt(cnpj.charAt(9), 10) * 4;
        soma1 += parseInt(cnpj.charAt(10), 10) * 3;
        soma1 += parseInt(cnpj.charAt(11), 10) * 2;

        resto = soma1 % 11;
        digito1 = (resto < 2) ? 0 : 11 - resto;

        //Calculando o segundo dígito verificador.
        soma2 += parseInt(cnpj.charAt(0), 10) * 6;
        soma2 += parseInt(cnpj.charAt(1), 10) * 5;
        soma2 += parseInt(cnpj.charAt(2), 10) * 4;
        soma2 += parseInt(cnpj.charAt(3), 10) * 3;
        soma2 += parseInt(cnpj.charAt(4), 10) * 2;
        soma2 += parseInt(cnpj.charAt(5), 10) * 9;
        soma2 += parseInt(cnpj.charAt(6), 10) * 8;
        soma2 += parseInt(cnpj.charAt(7), 10) * 7;
        soma2 += parseInt(cnpj.charAt(8), 10) * 6;
        soma2 += parseInt(cnpj.charAt(9), 10) * 5;
        soma2 += parseInt(cnpj.charAt(10), 10) * 4;
        soma2 += parseInt(cnpj.charAt(11), 10) * 3;
        soma2 += parseInt(digito1, 10) * 2;

        resto = soma2 % 11;
        digito2 = (resto < 2) ? 0 : 11 - resto;

        //Calculando o dígito verificador.
        digito = (digito1 * 10) + digito2;

        //Verificando se os dígitos são diferentes aos digitados.
        if (digito != digito_tmp)
            return false;
    }
    else
    {
        return false;
    }
    return true;
}

/**
 * Permite que somente números sejam escritos no campo.
 * Para funcionar utilize da seguinte forma: onkeypress="return onlyNumbers(event);".
 * @author Willian Fernandes (willian@visie.com.br)
 * @param oEvent Objeto event, necessário para o funcionamento Cross-Browser.
 * @returns {boolean}
 */
function onlyNumbers(oEvent)
{
    var oRegExp = /[0-9]/;
    var tecla_codigo;
    var tecla_char;

    if (oEvent.keyCode)
        tecla_codigo = oEvent.keyCode;
    else if (oEvent.which)
        tecla_codigo = oEvent.which;

    tecla_char = String.fromCharCode(tecla_codigo);

    //Permite algumas teclas.
    if (tecla_codigo == 8 || tecla_codigo == 9 || (tecla_codigo == 35 && oEvent.shiftKey) || (tecla_codigo == 36 && oEvent.shiftKey) || (tecla_codigo == 37 && (oEvent.shiftKey || tecla_char != '%')) || (tecla_codigo == 39 && tecla_char != "'") || (tecla_codigo == 46 && tecla_char != '.'))
        return true;
    //Se for número.
    else if (!oRegExp.test(tecla_char))
        return false;
    //Se não for número.
    else
        return true;
}

/**
 * Altera o foco do cursor para o campo anterior ou posterior ao atual.
 * Para funcionar utilize da seguinte forma: onkeyup="autoTab(event, this, FORMULARIO);".
 * @author Willian Fernandes (willian@visie.com.br)
 * @param oEvent Objeto event, necessário para o funcionamento Cross-Browser.
 * @param oElement Objeto do elemento (campo) atual (this).
 * @param oForm Objeto do formulário que contém o elemento atual (this).
 * @param setas Indica se as setas para cima e para baixo mudarão o foco do campo.
 * @param enter Indica se a tecla Enter mudará o foco do campo.
 * @returns {void}
 */
function autoTab(oEvent, oElement, oForm, setas, enter)
{
    //Variáveis da função.
    var keyNumber = null;
    var indice = null;
    var novo_campo = 0;

    if (window.event)
        keyNumber = oEvent.keyCode;
    else if(oEvent.which)
        keyNumber = oEvent.which;

    if (setas == undefined)
        setas = false;

    if (enter == undefined)
        enter = false;

    //Recupero o índice do campo atual.
    for (var i = 0; i < oForm.length; i++)
    {
        if (oForm.elements[i].type != null)
        {
            if (oForm.elements[i].name.toUpperCase() == oElement.name.toUpperCase())
            {
                indice = i;
                break;
            }
        }
    }

    if (indice == null)
        return;

    //Se o usuário digitou a seta para cima mudamos o foco do cursor para o campo anterior.
    if (keyNumber == 38 && setas)
    {
        if (indice > 0)
            novo_campo = indice - 1;
    }
    //Se o usuário digitou a seta para baixo, ou a tecla Enter, ou se a quantidade de caracteres digitado for igual ao maxlength do campo mudamos o foco do cursor para o próximo campo.
    else if ((keyNumber == 40 && setas) || (keyNumber == 13 && enter) || (oElement.value.length == oElement.maxLength))
    {
        novo_campo = indice + 1;
        if (indice >= oForm.length)
            novo_campo = 0;
    }
    else
    {
        novo_campo = indice;
    }

    //Altera o foco do cursor para o campo correto.
    if (novo_campo != indice)
    {
        if (!oForm.elements[novo_campo].disabled)
        {
            if ((oForm.elements[novo_campo].type == 'text') || (oForm.elements[novo_campo].type == 'password') || (oForm.elements[novo_campo].type == 'textarea'))
                oForm.elements[novo_campo].select();
            oForm.elements[novo_campo].focus();
        }
    }
}
