//Maisculo = obrigatorio, Minusculo = opcional
mMskAlpha = "L";           // A-Z,a-z 
mMskAlphaOpt = "l";
mMskAlphaNum = "A";        // A-Z,a-z,0-9 
mMskAlphaNumOpt  = "a";
mMskAscii = "C";           // qquer caracter
mMskAsciiOpt = "c";
mMskNumeric = "0";         // 0-9 
mMskNumericOpt = "9";
mMskNumSymOpt = "#";       // + ou - 

/** 
 * Retorna TRUE se o caracter na posição "pos" da máscara for um literal.
 */
function CM_getIfMaskLiteral(formato, pos) {
    charDig = formato.charAt(pos);
    if (charDig != mMskAlpha && charDig != mMskAlphaOpt &&
            charDig != mMskAlphaNum && charDig != mMskAlphaNumOpt &&
            charDig != mMskAscii && charDig != mMskAsciiOpt &&
            charDig != mMskNumeric && charDig != mMskNumericOpt &&
            charDig != mMskNumSymOpt) {
        return charDig;
    }
    return "";
}

/** 
 * Retorna TRUE se o caracter "charDig" digitado na posição "pos" for válido.
 */
function CM_isCaracterValido(formato, charDig, pos) {
        textovalido = false;
        //Verifica se o tamanho do texto é válido
        if (String(formato).length <= pos) {
            return "O tamanho do texto digitado é maior do que o tamanho " +
                "permitido. Tamanho permitido: \"" + 
                String(formato).length + "\".";
        }
        //Verifica se a máscara é válida
        mask = formato.charAt(pos);
        if ((charDig >= "A" && charDig <= "Z") || (charDig >= "a" && charDig <= "z")) {
            textovalido = (mask == mMskAlpha || mask == mMskAlphaOpt || 
                mask == mMskAlphaNum || mask == mMskAlphaNumOpt || 
                mask == mMskAscii || mask == mMskAsciiOpt);
        } else if (charDig >= "0" && charDig <= "9") {
            textovalido = (mask == mMskAlphaNum || mask == mMskAlphaNumOpt ||
                mask == mMskNumeric || mask == mMskNumericOpt || 
                mask == mMskAscii || mask == mMskAsciiOpt);
        } else if (charDig == "+") {
            textovalido = (mask == mMskNumSymOpt);
        } else if (charDig == "-") {
            textovalido = (mask == mMskNumSymOpt || charDig == mask);
        } else if (charDig == " ") {
            textovalido = (mask == mMskAlphaOpt || mask == mMskAlphaNumOpt ||
                mask == mMskAsciiOpt || mask == mMskNumericOpt ||
                mask == mMskNumSymOpt);
        } else {
            textovalido = (mask == mMskAscii || mask == mMskAsciiOpt ||
                mask == charDig);
        }
        //Retorna o resultado da verificação
        if (!textovalido) {
            return "O caracter \"" + charDig + "\" não é permitido " +
                "na posição \"" + (pos+1) + "\"";
        } else {
            return "";
        }
}

/** 
 * Retorna TRUE se o formato do "textodigitado" for igual ao formato
 * da máscara.
 */
function CM_isFormatoValido(formato, textodigitado) {
    msgformato = "";
    nPosTexto = 0;
    while (nPosTexto < String(textodigitado).length && msgformato == "") {
        msgformato = CM_isCaracterValido(formato, textodigitado.charAt(nPosTexto), nPosTexto);
        nPosTexto++;
    }
    return msgformato;  
}

/**
 * Verifica se valor digitado no campo "ctrl" é válido.
 */
function CM_verificaValor(ctrl) {
    //verifica se o texto é válido
    msgformato = CM_isFormatoValido(ctrl.getAttribute("formato"), ctrl.value);
    valordigitado = ctrl.value;
    //se não for válido, limpa o campo e mostra uma mensagem
    if (msgformato != "") {
        alert (msgformato + " Valor digitado: \"" + valordigitado + "\".");
        ctrl.focus();
        return false;
    }
    return true;
}
    
/** 
 * Tratamento de digitação no componente.
 */
function CM_KPS(ctrl, event) {
    //Verifica as teclas de controle
    if (C_getDeveInibirTeclasControle(ctrl, event)) {
        C_CancelaEvento(event);
        return;
    }
    //Nas situações abaixo não deve fazer validação não faz nada
    if (C_NaoPodeProcessarOnKeyPress(ctrl, event)) {
        return;
    }
    //pega a tecla que foi digitada
    tecla = C_TeclaDigitada(event);
    //pega os dados do texto que está sendo digitado
    pos = C_getPosTextoDigitado(ctrl);
    charDigitado = String.fromCharCode(tecla);
    textoDigitado = C_getTextoDigitado(ctrl, charDigitado);
    formato = ctrl.getAttribute("formato");
    //So permite a digitacao caso esteja no fim do campo
    if (pos < String(formato).length && pos == (String(textoDigitado).length-1)) {
        //Verifica se o formato é válido
        msgformato = CM_isFormatoValido(formato, textoDigitado);
        if (msgformato != "") {
            //Verifica se deve completar a máscara
            charMask = CM_getIfMaskLiteral(formato, pos);
            if (charMask != "" && C_getSelLength(ctrl) == 0) {
                textoDigitado = ctrl.value + charMask + charDigitado;
                if (CM_isFormatoValido(formato, textoDigitado) == "") {
                    if (F_isIExplorer()) {
                        range = ctrl.createTextRange();
                        range.move('character', pos);            
                        range.text = charMask;
                    } else {
                        ctrl.value = ctrl.value + charMask;
                        if (ctrl.onchange != null) {
                            ctrl.onchange(ctrl);
                        }
                    }
                } else {
                  C_CancelaEvento(event);
                  return;
                }
            } else {
                C_CancelaEvento(event);
                return;
            }
        }
    } else {
        //Se não tiver uma faixa de seleção ou a posição do cursor esteja
        //antes do final da mascara, sobrescreve os caracteres
        if (C_getSelLength(ctrl) > 1 || pos > String(formato).length-1) {
            C_CancelaEvento(event);
            return;
        } else {
            textoDigitado = ctrl.value.substr(0, pos) + charDigitado + 
                ctrl.value.substr(pos+1);
            if (CM_isFormatoValido(formato, textoDigitado) == "") {
                if (F_isIExplorer()) {
                    range = ctrl.createTextRange();
                    range.move('character', pos);            
                    range.moveEnd('character', 1);
                    range.select();
                } else {
                    ctrl.selectionEnd = pos+1;
                }
            } else {
                C_CancelaEvento(event);
                return;
            }
        }
    }
}

/** 
 * Trata a saída do campo para não permitir que o campo fique com valores inválidos 
 */
function CM_BLR(ctrl) {
    //Verifica se o formato do campo é válido
    CM_verificaValor(ctrl);
}

/**
 * Trata a digitação no campo.
 */
function CM_KDN(ctrl, event) {
    if (C_getDeveInibirTeclasControle(ctrl, event)) {
        C_CancelaEvento(event);
        return;
    }
}

/**
 * Passa o foco para o próximo campo.
 */
function CM_KUP(ctrl, event) {
    focoProxCampo = ctrl.getAttribute("focoProxCampo");
    //Pula para o próximo controle
    if (focoProxCampo != null) {
        formato = ctrl.getAttribute("formato");
        pos = C_getPosTextoDigitado(ctrl);
        if (formato.length == ctrl.value.length &&
           pos == ctrl.value.length) {
            ctrlFoco = FF_GetProxCtrl(ctrl);
            if (ctrlFoco != null) {
                ctrlFoco.focus();
            }
        }
    }
}