//<script>

//**************************************************************************************************
//                                                                                                 *
//                                    OBJETO MÁSCARA DE EDIÇÃO                                     *
//                                     VERSÃO 10.03.30.15.00                                       *
//                                                                                                 *
//**************************************************************************************************
//                                                                                                 *
//                                          DEPENDÊNCIAS                                           *
//                                                                                                 *
//=================================================================================================*
//                                                                                                 *
// cltdom.js                                                                                       *
// cltdat.js                                                                                       *
// cltstr.js                                                                                       *
// cltnbr.js (para os tipos "INT" e "DEC")                                                         *
// clttim.js (para os tipos "DAT", "HOR" e "TIM")                                                  *
//                                                                                                 *
//**************************************************************************************************
//                                                                                                 *
//                                     PARÂMETROS DE ENTRADA                                       *
//                          (B) = boolean / (S) = string / (N) = number                            *
//                                                                                                 *
//=================================================================================================*
//      id: (S) Obrigatório                                                                        *
//          Propriedade 'id' do elemento "SPAN" a ser utilizado como máscara.                      *
//-------------------------------------------------------------------------------------------------*
//    type: (S) Opcional                                                                           *
//          Indica o tipo de máscara. Será convertido para "TXT", caso não                         *
//          nenhum dos valores abaixo:                                                             *
//          "TXT" - Aceita qualquer caractere, com exceção de "|", "\" e """.                      *
//          "NOM" - Aceita caracteres alfa-numéricos, " ", "'", "-".                               *
//          "END" - Aceita caracteres alfa-numéricos, " ", "'", "-" e ".".                         *
//          "PWD" - Aceita caracteres alfa-numéricos.                                              *
//          "EML" - Aceita caracteres alfa-numéricos, "@", ".", "-" e "_".                         *
//          "INT" - Aceita qualquer caractere numérico e "-"                                       *
//          "DEC" - Aceita qualquer caractere numérico, "-" e ","                                  *
//          "DAT" - Aceita qualquer caractere numérico (DD/MM/YYYY)                                *
//          "HOR" - Aceita qualquer caractere numérico (HH:NN)                                     *
//          "TIM" - Aceita qualquer caractere numérico (HH:NN:SS)                                  *
//          "CEP" - Aceita qualquer caractere numérico (00000-000)                                 *
//          "TEL" - Aceita qualquer caractere numérico (0000 0000)                                 *
//          "CPF" - Aceita qualquer caractere numérico (000.000.000-00)                            *
//          "CPJ" - Aceita qualquer caractere numérico (00.000.000/0000-00)                        *
//          "CBO" - Combobox (deve ser carregado com o método "load").                             *
//          "CHK" - Checkbox (deve ser carregado com o método "load").                             *
//          "MEM" - Textarea (para campos memorando)                                               *
//-------------------------------------------------------------------------------------------------*
//   label: (S) Opcional                                                                           *
//          Rótulo a ser exibido à esquerda do controle de edição da máscara. Se um asterisco for  *
//          fornecido no início da string, indicará obrigatoriedade de preenchimento da máscara.   *
//-------------------------------------------------------------------------------------------------*
//  offset: (N) Opcional                                                                           *
//          Distância, em pixels, à esquerda da máscara, entre 0 e 1024. Se omitido ou inválido,   *
//          assumirá 0.                                                                            *
//-------------------------------------------------------------------------------------------------*
//   width: (N) Opcional                                                                           *
//          Largura, em pixels, do controle de edição, entre 0 e 1024. Se  omitido, assumirá um    *
//          valor correspondente ao tipo da máscara.                                               *
//-------------------------------------------------------------------------------------------------*
//   fSize: (N) Opcional                                                                           *
//          Tamanho da fonte a ser utilizada na máscara, entre 8 e 255 pixeis.                     *
//          Se omitido, assumirá 12 pixels.                                                        *
//-------------------------------------------------------------------------------------------------*
//    var1: (N) Opcional                                                                           *
//          - Para máscaras de texto, será o máximo de caracteres da máscara, entre 1 e 255. Se    *
//            omitido, assumirá 255 ("MEM" sempre assumirá 65535).                                 *
//          - Para "MEM", será o altura, em pixels, do campo de edição, entre 1 e 500. Se omitido, *
//            assumirá 100.                                                                        *
//          - Para "INT", será o número de zeros à esquerda do valor. Se omitido, assumirá 0.      *
//          - Para "DEC", será o número de casas decimais. Se omitido, assumirá 2.                 *
//-------------------------------------------------------------------------------------------------*
//    var2: (S) Opcional                                                                           *
//          - Para máscaras de texto, indica a conversão dos caracteres para maiúsculos ou         *
//            minúsculos. Será convertido para "U" ("PWD" e "EML" para "L"), caso não seja:        *
//            - "N" - Nenhuma conversão será realizada.                                            *
//            - "U" - Caracteres serão convertidos para maiúsculos.                                *
//            - "L" - Caracteres serão convertidos para minúsculos.                                *
//          - Para "INT", "DEC", "DAT", "HOR", "TIM" será o valor mínimo possível para a máscara.  *
//-------------------------------------------------------------------------------------------------*
//    var3: (S) Opcional                                                                           *
//          - Para "TXT", "NOM" e "END", indica o tipo de exclusão de espaços. Será convertido     *
//            para "T", caso não seja nenhum dos valores:                                          *
//            - "N" - Nenhum exclusão de espaços será realizada.                                   *
//            - "L" - Exclusão de espaços à esquerda.                                              *
//            - "R" - Exclusão de espaços à direita.                                               *
//            - "T" - Exclusão à esquerda, à direita e espaços duplicados.                         *
//          - Para "INT", "DEC", "DAT", "HOR", "TIM" será o valor máximo possível para a máscara.  *
//-------------------------------------------------------------------------------------------------*
//  change: (S) Opcional                                                                           *
//          Nome da função a ser executada quando o valor da máscara é alterado.                   *
//-------------------------------------------------------------------------------------------------*
//    help: (B) Opcional                                                                           *
//          Para máscaras numéricas, indica se será exibida a ajuda para preenchimento.            *
//                                                                                                 *
//**************************************************************************************************
//                                                                                                 *
//                                     PROPRIEDADES PÚBLICAS                                       *
//                                                                                                 *
//=================================================================================================*
//                                                                                                 *
// caption: rótulo da máscara.                                                                     *
// enabled: indica o estado de habilitação da máscara.                                             *
// obliged: indica a obrigatóriedade de preenchimento da máscara.                                  *
//                                                                                                 *
//**************************************************************************************************
//                                                                                                 *
//                                        MÉTODOS PÚBLICOS                                         *
//                                                                                                 *
//=================================================================================================*
//                                                                                                 *
// enable: Habilita ou desabilita a máscara.                                                       *
//  focus: Move o foco para a máscara.                                                             *
// getMsk: Obtém o valor formatado da máscara.                                                     *
// getSQL: Obtém o valor SQL da máscara.                                                           *
// getVal: Obtém o valor nativo da máscara.                                                        *
//   load: Carrega máscaras do tipo "CBO" e "CHK".                                                 *
// oblige: Obriga ou desobriga a máscara.                                                          *
// setVal: Atribui um valor à máscara.                                                             *
//                                                                                                 *
//**************************************************************************************************
//                                                                                                 *
//                                TABELA DE UTILIZAÇÃO DE EVENTOS                                  *
//                                                                                                 *
//=================================================================================================*
//                                                                                                 *
//    -----------------------------------------------------------------------------------------    *
//    |   EVENTO      |     FIREFOX     |      OPERA      | SAFARI / CHROME |    EXPLORER     |    *
//    -----------------------------------------------------------------------------------------    *
//    | onactivate    |                 |             NUM |             NUM |             NUM |    *
//    | onblur        | TXT CBO     NUM | TXT CBO     NUM | TXT         NUM | TXT         NUM |    *
//    | onchange      | TXT         NUM |                 |     CBO         |     CBO         |    *
//    | onclick       |     CBO CHK     |     CBO CHK     |         CHK     |         CHK     |    *
//    | oncontextmenu | PWD             |                 |                 |                 |    *
//    | oncut         |                 | TXT         NUM | TXT         NUM | TXT         NUM |    *
//    | onfocus       | TXT CBO     NUM | TXT CBO     NUM | TXT CBO     NUM | TXT CBO     NUM |    *
//    | onkeydown     | PWD             | TXT         NUM | TXT         NUM | TXT         NUM |    *
//    | onkeypress    | TXT         NUM | TXT         NUM | TXT         NUM | TXT         NUM |    *
//    | onkeyup       | TXT CBO     NUM |     CBO         |     CBO         |     CBO         |    *
//    | onpaste       |                 | TXT         NUM | TXT         NUM | TXT         NUM |    *
//    -----------------------------------------------------------------------------------------    *
//                                                                                                 *
//**************************************************************************************************

//**************************************************************************************************
function mask(id, type, label, offset, width, fSize, var1, var2, var3, change, help) {
    try {
        // VALIDAÇÃO DOS PARÂMETROS DE ENTRADA =====================================================
        if (!isTag(id, "span")) throw "O parâmetro (id='" + "" + id + "') não é uma tag 'span' válida!";
        type = isString(type, "TXT", "NOM", "END", "PWD", "EML", "CBO", "CHK", "MEM", "INT", "DEC", "DAT", "HOR", "TIM", "CEP", "TEL", "CPF", "CPJ") ? type.toUpperCase() : "TXT";
        this.type = type;
        this.isTxt = (type == "TXT") || (type == "NOM") || (type == "END") || (type == "PWD") || (type == "EML") || (type == "MEM");
        this.isSel = (type == "CBO") || (type == "CHK");
        this.isNum = (type == "INT") || (type == "DEC") || (type == "DAT") || (type == "HOR") || (type == "TIM") || (type == "CEP") || (type == "TEL") || (type == "CPF") || (type == "CPJ");
        label = isString(label) ? label.noWrap() : "";
        this.obliged = false;
        if ((label.substr(0, 1) == "*")) {
            this.obliged = true;
            label = label.substr(1);
        }
        offset = isInteger(offset, 0, 1024) ? offset : 0;
        var height;
        if (this.isTxt) {
            if (type == "MEM") height = isInteger(var1, 1, 500) ? var1 : 100;
            else var1 = isInteger(var1, 0, 255) ? var1 : 255;
            var2 = !isString(var2, "L", "N", "U") ? (((type == "PWD") || (type == "EML")) ? "L" : ((type == "MEM") ? "N" : "U")) : var2.toUpperCase();
            var3 = !isString(var3, "N", "L", "R", "T") ? "T" : var3.toUpperCase();
        }
        if ((type == "INT") || (type == "DEC")) var1 = isInteger(var1, 0, 15) ? var1 : ((type == "DEC") ? 2 : 0);
        var title = "";
        var minTitle = "";
        var maxTitle = "";
        var min = null;
        var max = null;
        if (type == "INT") {
            if (isInteger(var2)) {
                min = var2;
                minTitle = "*";
            }
            else min = Number.MIN_INT;
            if (isInteger(var3)) {
                max = var3;
                maxTitle = "*";
            }
            else max = Number.MAX_INT;
            if ((min < 0) || (max < 0)) {
                var1 = 0;
            }
            if (var1 > 0) {
                if (("" + min).length > var1) min = 0;
                if (("" + max).length > var1) max = parseInt("9".replicate(var1), 10);
            }
            if (minTitle == "*") minTitle = (var1 > 0) ? min.leading(var1) : min.currency(0);
            if (maxTitle == "*") maxTitle = (var1 > 0) ? max.leading(var1) : max.currency(0);
        }
        else if (type == "DEC") {
            if (isDecimal(var2)) {
                min = var2;
                minTitle = var2.currency(var1);
            }
            else min = Number.MIN_DEC;
            if (isDecimal(var3)) {
                max = var3;
                maxTitle = var3.currency(var1);
            }
            else max = Number.MAX_DEC;
        }
        else if (type == "DAT") {
            var mask = "DATE";
            if (isDate(var2)) {
                min = var2.format(mask);
                minTitle = "*"
            }
            else if (isDateString(var2)) {
                min = var2;
                minTitle = "*";
            }
            if (min == null) min = Date.MIN_VALUE.format(mask);
            if (isDate(var3)) {
                max = var3.format(mask);
                maxTitle = "*";
            }
            else if (isDateString(var3)) {
                max = var3;
                maxTitle = "*";
            }
            if (max == null) max = Date.MAX_VALUE.format(mask);
            if (minTitle == "*") minTitle = min;
            if (maxTitle == "*") maxTitle = max;
        }
        else if (type == "HOR") {
            var mask = "HOUR";
            if (isDate(var2)) {
                min = var2.format(mask);
                minTitle = "*"
            }
            else if (isHourString(var2)) {
                min = var2;
                minTitle = "*";
            }
            if (min == null) min = "00:00";
            if (isDate(var3)) {
                min = var3.format(mask);
                maxTitle = "*"
            }
            else if (isHourString(var3)) {
                max = var3.format(mask);
                maxTitle = "*";
            }
            if (max == null) max = "23:59";
            if (minTitle == "*") minTitle = min;
            if (maxTitle == "*") maxTitle = max;
        }
        else if (type == "TIM") {
            var mask = "TIME";
            if (isDate(var2)) {
                min = var2.format(mask);
                minTitle = "*"
            }
            else if (isTimeString(var2)) {
                min = var2;
                minTitle = "*";
            }
            if (min == null) min = "00:00:00";
            if (isDate(var3)) {
                min = var3.format(mask);
                maxTitle = "*"
            }
            else if (isTimeString(var3)) {
                max = var3.format(mask);
                maxTitle = "*";
            }
            if (max == null) max = "23:59:59";
            if (minTitle == "*") minTitle = min;
            if (maxTitle == "*") maxTitle = max;
        }
        this.minTitle = minTitle;
        this.maxTitle = maxTitle;
        if (!isInteger(fSize, 8, 255)) fSize = 12;
        if (!isInteger(width, 0, 1024)) {
            if (type == "INT") width = this.sizer(id, (minTitle || min.currency(0)), (maxTitle || max.currency(0)), fSize);
            else if (type == "DEC") width = this.sizer(id, (minTitle || min.currency(var1)), (maxTitle || max.currency(var1)), fSize);
            else if ((type == "DAT") || (type == "HOR") || (type == "TIM")) width = this.sizer(id, (minTitle || min), (maxTitle || max), fSize);
            else if (type == "CEP") width = this.sizer(id, "00000-000", "", fSize);
            else if (type == "TEL") width = this.sizer(id, "0000 0000", "", fSize);
            else if (type == "CPF") width = this.sizer(id, "000.000.000-00", "", fSize);
            else if (type == "CPJ") width = this.sizer(id, "00.000.000/0000-00", "", fSize);
            else width = "*";
        }
        minTitle = (minTitle != "") ? "Valor mínimo: " + minTitle : "";
        maxTitle = (maxTitle != "") ? "Valor máximo: " + maxTitle : "";
        var title = minTitle + (((minTitle != "") && (maxTitle != "")) ? " | " : "") + maxTitle;
        this.change = isString(change) ? change : null;
        this.helper = (help == true) ? true : false;
        // DEFINIÇÃO DAS PROPRIEDADES E INCLUSÃO DOS ELEMENTOS HTML ================================
        this.caption = label.wrap();
        this.enabled = true;
        var strHTM = "";
        var height;
        if (type == "CBO") {
            height = fSize + 7;
            var capSty = "style='font-size:" + fSize + "px" + ((label.length > 0) ? "" : ";display:none") + ";position:relative;top:2px;vertical-align:top'";
            var selSty = "style='font-size:" + (fSize - ((browser.sa || browser.ie6 || browser.ie7) ? 2 : 0)) + "px" + ";vertical-align:top" + ";height:" + (height + ((browser.ie6 || browser.ie7) ? 1 : 0)) + "px" + ((width == "*") ? "" : ";width:" + width + "px") + "'";
            strHTM = "<span style='font-size:1px;padding-left:" + offset + "px'>" +
                         "<span id='" + id + "-label' class='masktext' " + capSty + ">" + label + ":</span>" +
                         "<span class='masksepa'>" +
                            "<select id='" + id + "-TAG' class='masksel" + (this.obliged ? "o" : "e") + "' " + selSty + "></select>" +
                         "</span>" +
                         "<input id='" + id + "-MSK' name='" + id + "-MSK' type='text' class='hidden' />" +
                         "<input id='" + id + "-VAL' name='" + id + "-VAL' type='text' class='hidden' />" +
                         "<input id='" + id + "-SQL' name='" + id + "-SQL' type='text' class='hidden' />" +
                     "</span>";
        }
        else if (this.type == "CHK") {
            height = fSize + 4;
            var capSty = "style='font-size:" + fSize + "px;" + ((label.length > 0) ? "" : ";display:none") + ";position:relative" + ((browser.ie6 || browser.ie7) ? ";left:-2px;top:2px" : ";padding-left:5px;top:2px") + ";vertical-align:top'";
            var chkSty = "style='height:" + (height + 3) + "px;vertical-align:top'";
            strHTM = "<span style='font-size:1px;padding-left:" + offset + "px'>" +
                         "<span style='font-size:1px" + ((browser.ie6 || browser.ie7) ? ";position:relative;left:-4px" : "") + "'>" +
                            "<input id='" + id + "-TAG' type='checkbox' class='masktext' " + chkSty + "/>" +
                         "</span>" +
                         "<span id='" + id + "-label' class='masktext' " + capSty + ">" + label + "</span>" +
                         "<input id='" + id + "-MSK' name='" + id + "-MSK' type='text' class='hidden' />" +
                         "<input id='" + id + "-VAL' name='" + id + "-VAL' type='text' class='hidden' />" +
                         "<input id='" + id + "-SQL' name='" + id + "-SQL' type='text' class='hidden' />" +
                     "</span>";
        }
        else if (this.type == "MEM") {
            var capSty = "style='font-size:" + fSize + "px" + ((label.length > 0) ? "" : ";display:none") + ";position:relative;top:2px;vertical-align:top'";
            var texSty = "style='font-size:" + fSize + "px;height:" + height + "px;padding-top:1px" + ((browser.ie6 || browser.ie7) ? ";position:relative;top:-1px" : "") + ((width == "*") ? "" : ";width:" + width + "px") + "'";
            strHTM = "<span style='font-size:1px;padding-left:" + offset + "px'>" +
                         "<span id='" + id + "-label' class='masktext' " + capSty + ">" + label + ":</span>" +
                         "<span class='masksepa'>" +
                             "<textarea id='" + id + "-TAG' class='maskinp" + (this.obliged ? "o" : "e") + "' " + texSty + " /></textarea>" +
                         "</span>" +
                         "<textarea id='" + id + "-MSK' name='" + id + "-MSK' type='text' class='hidden'></textarea>" +
                         "<textarea id='" + id + "-VAL' name='" + id + "-VAL' type='text' class='hidden'></textarea>" +
                         "<textarea id='" + id + "-SQL' name='" + id + "-SQL' type='text' class='hidden'></textarea>" +
                     "</span>";
        }
        else {
            height = fSize + 4;
            var capSty = "style='font-size:" + fSize + "px" + ((label.length > 0) ? "" : ";display:none") + ";position:relative;top:2px;vertical-align:top'";
            var inpSty = "style='font-size:" + fSize + "px;height:" + (height + ((browser.ff || browser.op) ? 1 : 0)) + "px" + (browser.ff || browser.op ? "" : ";padding-top:1px") + ((browser.ie6 || browser.ie7) ? ";position:relative;top:-1px" : "") + ";vertical-align:top" + ((width == "*") ? "" : ";width:" + width + "px") + "'";
            var hlpSty = "style='display:" + ((this.helper && this.isNum) ? "" : "none") + ";font-size:" + fSize + "px;height:" + (height + 3) + "px" + ((browser.ie || browser.op) ? "" : ";padding-bottom:0px") + ";vertical-align:top;width:" + (height + 2) + "px'";
            strHTM = "<span style='font-size:1px;padding-left:" + offset + "px'>" +
                         "<span id='" + id + "-label' class='masktext' " + capSty + ">" + label + ":</span>" +
                         "<span class='masksepa'>" +
                             "<input id='" + id + "-TAG' type='" + ((type == "PWD") ? "password" : "text") + "' class='maskinp" + (this.obliged ? "o" : "e") + "' " + inpSty + " />" +
                             "<input id='" + id + "-HLP' type='button' class='maskhelp' value='?' title='Click aqui para ver as instruções de preenchimento deste campo' " + hlpSty + " />" +
                         "</span>" +
                         "<input id='" + id + "-MSK' name='" + id + "-MSK' type='text' class='hidden' />" +
                         "<input id='" + id + "-VAL' name='" + id + "-VAL' type='text' class='hidden' />" +
                         "<input id='" + id + "-SQL' name='" + id + "-SQL' type='text' class='hidden' />" +
                     "</span>";
        }
        this.element = document.getElementById(id);
        this.element.innerHTML = strHTM;
        this.element.container = this;
        this.MSK = document.getElementById(id + "-MSK");
        this.VAL = document.getElementById(id + "-VAL");
        this.SQL = document.getElementById(id + "-SQL");
        this.input = document.getElementById(id + "-TAG");
        this.input.container = this;
        this.input.disabled = false;
        if (this.helper && this.isNum) {
            this.help = document.getElementById(id + "-HLP");
            this.help.container = this;
            this.help.onclick = this.showHelp;
            this.help.style.display = "";
        }
        if (this.isTxt) {
            var auxMask = "";
            if (type == "NOM") auxMask = "\[ 0123456789aáàãâäbcçdeéèêëfghiíìîïjklmnoóòõôöpqrstuúùûüvwxyýÿzAÁÀÃÂÄBCÇDEÉÈÊËFGHIÍÌÎÏJKLMNOÓÒÕÔÖPQRSTUÚÙÛÜVWXYYÝZ\\-\\']";
            else if (type == "END") auxMask = "\[ 0123456789aáàãâäbcçdeéèêëfghiíìîïjklmnoóòõôöpqrstuúùûüvwxyýÿzAÁÀÃÂÄBCÇDEÉÈÊËFGHIÍÌÎÏJKLMNOÓÒÕÔÖPQRSTUÚÙÛÜVWXYYÝZºª\\-\\'\\.\\/]";
            else if (type == "PWD") auxMask = "\[0-9a-zA-Z\]";
            else if (type == "EML") auxMask = "\(\\w|\[\-\@\.\]\)";
            this.input.exprMask = new RegExp(auxMask, "g");
            this.input.textSize = (type != "MEM") ? var1 : 65535;
            this.input.caseMode = var2;
            this.input.trimMode = var3;
        }
        switch (type) {
        case "INT":
            this.input.exprMask = new RegExp(((min < 0) ? "\(\\d|\\-\)" : "\\d"), "g");
            this.input.leadings = var1;
            this.input.minValue = min;
            this.input.maxValue = max;
            this.input.textSize = (min < 0) ? 16 : 15;
            break;
        case "DEC":
            this.input.exprMask = new RegExp(((min < 0) ? "\(\\d|\\-|\\,\)" : "\(\\d|\\,\)"), "g");
            this.input.decimals = var1;
            this.input.minValue = min;
            this.input.maxValue = max;
            this.input.textSize = 17;
            break;
        case "DAT":
            this.input.exprMask = new RegExp("\\d", "g");
            this.input.minValue = min;
            this.input.maxValue = max;
            this.input.textSize = 8;
            break;
        case "HOR":
            this.input.exprMask = new RegExp("\\d", "g");
            this.input.minValue = min;
            this.input.maxValue = max;
            this.input.textSize = 4;
            break;
        case "TIM":
            this.input.exprMask = new RegExp("\\d", "g");
            this.input.minValue = min;
            this.input.maxValue = max;
            this.input.textSize = 6;
            break;
        case "CEP":
            this.input.exprMask = new RegExp("\\d", "g");
            this.input.textSize = 8;
            break;
        case "TEL":
            this.input.exprMask = new RegExp("\\d", "g");
            this.input.textSize = 8;
            break;
        case "CPF":
            this.input.exprMask = new RegExp("\\d", "g");
            this.input.textSize = 11;
            break;
        case "CPJ":
            this.input.exprMask = new RegExp("\\d", "g");
            this.input.textSize = 14;
            break;
        }
        if (!this.isSel) this.input.toText = this.toText;
        // DEFINIÇÃO DOS EVENTOS ===================================================================
        if (type == "CBO") {
            this.input.buffer = (window.event ? -1 : 0);
            this.input.onblur = this.onBlur;
            if (browser.sa || browser.ch || browser.ie) this.input.onchange = this.onChange;
            if (browser.ff || browser.op) this.input.onclick = this.onClick;
            this.input.onfocus = this.onFocus;
            this.input.onkeyup = this.onKeyUp;
        }
        else if (this.type == "CHK") {
            this.input.onclick = this.onClick;
        }
        else {
            this.input.buffer = "";
            this.input.changed = false;
            this.input.onblur = this.onBlur;
            this.input.onchange = this.onChange;
            this.input.oncontextmenu = this.onContextMenu; // OP não suporta
            this.input.oncut = this.onCut; // OP não suporta
            this.input.onfocus = this.onFocus;
            if (!browser.op) this.input.onkeypress = this.onKeyPress; // OP retorna keyCodes errados
            this.input.onkeyup = this.onKeyUp;
            this.input.onpaste = this.onPaste; // OP não suporta
        }
        if (type == "CHK") {
            this.input.not = false;
            this.input.yes = true;
            this.MSK.value = false;
            this.VAL.value = false;
            this.SQL.value = "FALSE";
        }
        else {
            this.MSK.value = null;
            this.VAL.value = null;
            this.SQL.value = "NULL";
        }
    }
    catch(e) {
        throw "cltmsk.js: mask()__" + (e.message || e);
    }
}

//**************************************************************************************************
//                                                                                                 *
//                                             EVENTOS                                             *
//                                                                                                 *
//**************************************************************************************************

//**************************************************************************************************
mask.prototype.onBlur = function() {
    try {
        if (this.container.type == "CBO") {
            // Eliminar bug do Opera quando o mouse move-se pelo primeiro item do combo e seleciona-o sem click
            if ((browser.op) && (this.selectedIndex == -1)) this.selectedIndex = -1;
            if ((browser.ff) && (this.buffer != this.selectedIndex)) this.container.loadEvent();
        }
        else if (this.container.type != "CHK") {
            this.container.MSK.value = this.container.getMsk();
            this.container.VAL.value = this.container.getVal();
            this.container.SQL.value = this.container.getSQL();
            this.value = this.toText();
        }
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.onBlur()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.onChange = function() {
    try {
        if (this.container.type == "CBO") {
            if (this.buffer != this.selectedIndex) this.container.loadEvent();
        }
        else {
            if ((!this.changed) && (this.buffer != this.toText())) {
                this.container.loadEvent();
                this.changed = true;
            }
        }
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.onChange()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.onClick = function() {
    try {
        if (this.container.type == "CBO") {
            if (this.buffer != this.selectedIndex) this.container.loadEvent();
        }
        else if (this.container.type == "CHK") this.container.loadEvent();
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.onClick()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.onContextMenu = function(evt) {
    try {
        if (this.container.type == "PWD") {
            if (evt) evt.stopPropagation();
        	return false;
        }
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.onContextMenu()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.onCut = function() {
    try {
        if (this.container.type == "PWD") return false;
        if (!this.changed) {
            this.container.loadEvent();
            this.changed = true;
        }
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.onCut()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.onFocus = function() {
    try {
        if (this.container.type == "CBO") {
            this.buffer = this.selectedIndex;
        }
        else {
            if ((this.container.type == "INT") || (this.container.type == "DEC")) {
                this.value = this.value.replace(/\./g, "");
            }
            else if (this.container.isNum) {
                this.value = this.value.replace(/\D/g, "");
            }
            this.buffer = this.toText();
            this.changed = false;
        }
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.onFocus()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.onKeyPress = function(evt) {
    try {
        var evt = evt ? evt : window.event;
        var key = (evt.which ? evt.which : window.event.keyCode);
        if (key > 0) {
            // 8 = backspace | 13 = enter
            if ((key == 8) || (key == 13) || evt.ctrlKey || evt.altKey) return true;
            if (this.value.length < this.textSize) {
                if ((this.container.type == "TXT") || (this.container.type == "MEM")) return true;
                if (String.fromCharCode(key).match(this.exprMask) != null) return true;
            }
            return false;
        }
        return true;
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.onKeyPress()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.onKeyUp = function(evt) {
    try {
        if (this.container.type == "CBO") {
            var key = (evt ? evt.which : event.keyCode);
            if (key == 46) this.selectedIndex = (window.event ? -1 : 0); // DEL
            if (this.buffer != this.selectedIndex) this.container.loadEvent();
        }
        else {
            if ((!this.changed) && (this.buffer != this.toText())) {
                this.container.loadEvent();
                this.changed = true;
            }
        }
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.onKeyUp()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.onPaste = function() {
    try {
        if (this.container.type == "PWD") return false;
        if (!this.changed) {
            this.container.loadEvent();
            this.changed = true;
        }
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.onPaste()__" + (e.message || e);
    }
}

//**************************************************************************************************
//                                                                                                 *
//                                            MÉTODOS                                              *
//                                                                                                 *
//**************************************************************************************************

//**************************************************************************************************
mask.prototype.enable = function(mode) {
    try {
        mode = (mode == true) ? true : false;
        this.input.disabled = !mode;
        if (this.help) this.help.disabled = !mode;
        this.enabled = mode;
        if (this.type == "CBO") this.input.className = "masksel" + (!mode ? "d" : (this.obliged ? "o" : "e"));
        else if (this.type != "CHK") this.input.className = "maskinp" + (!mode ? "d" : (this.obliged ? "o" : "e"));
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.enable()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.focus = function() {
    try {
        if (this.enabled) this.input.focus();
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.focus()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.getMsk = function() {
    try {
        var type = this.type;
        var ctrl = this.input;
        if (type == "CBO") return ((ctrl.selectedIndex < 0) ? "" : ctrl.options[ctrl.selectedIndex].text);
        if (type == "CHK") return (ctrl.checked ? ctrl.yes : ctrl.not);
        return ctrl.toText();
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.getMsk()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.getSQL = function() {
    try {
        var type = this.type;
        var ctrl = this.input;
        var aux = "";
        if (type == "CBO") {
            if (ctrl.selectedIndex <= (window.event ? -1 : 0)) return "NULL";
            aux = ctrl.options[ctrl.selectedIndex].value;
            return ((aux.match(/[^\-0-9]/) != null) ? "'" + aux + "'" : "" + parseInt(aux, 10));
        }
        if (type == "CHK") {
            aux = (ctrl.checked ? ctrl.yes : ctrl.not);
            if ((aux == true) || (aux == false)) return ("" + aux).toUpperCase();
            else return ((aux.match(/[^0-9]/) != null) ? "'" + aux + "'" : "" + parseInt(aux, 10));
        }
        if (this.isTxt) {
            aux = ctrl.toText().replace(/\'/g, "''");
            if (aux != "") aux = "'" + aux + "'";
        }
        else if (type == "INT") {
            aux = ctrl.toText().replace(/\./g, "");
        }
        else if (type == "DEC") {
            aux = ctrl.toText().replace(/\./g, "").replace(/\,/, ".");
        }
        else if (type == "DAT") {
            aux = ctrl.toText();
            if (aux != "") aux = newDate(aux).format("#");
        }
        else if (type == "HOR") {
            aux = ctrl.toText();
            if (aux != "") aux = newDate(aux).format("##");
        }
        else if (type == "TIM") {
            aux = ctrl.toText();
            if (aux != "") aux = newDate(aux).format("###");
        }
        else {
            aux = ctrl.toText().replace(/\D/g, "");
            if (aux != "") aux = "" + parseInt(aux, 10);
        }
        return (aux == "") ? "NULL" : aux;
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.getSQL()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.getVal = function() {
    try {
        var type = this.type;
        var ctrl = this.input;
        var aux = "";
        if (type == "CBO") {
            if (ctrl.selectedIndex <= (window.event ? -1 : 0)) return null;
            aux = ctrl.options[ctrl.selectedIndex].value;
            return ((aux.match(/[^0-9]/) != null) ? aux : parseInt(aux, 10));
        }
        if (type == "CHK") {
            var aux = (ctrl.checked ? ctrl.yes : ctrl.not);
            if ((aux == true) || (aux == false)) return aux;
            else return ((aux.match(/[^0-9]/) != null) ? aux : parseInt(aux, 10));
        }
        if (this.isTxt) {
            aux = ctrl.toText();
            return (aux == "") ? null : aux;
        }
        if (type == "INT") {
            aux = ctrl.toText().replace(/\./g, "");
            return (aux == "") ? null : parseInt(aux, 10);
        }
        if (type == "DEC") {
            aux = ctrl.toText().replace(/\./g, "").replace(/\,/, ".");
            return (aux == "") ? null : parseFloat(aux);
        }
        if ((type == "DAT") || (type == "HOR") || (type == "TIM")) {
            aux = ctrl.toText();
            return (aux == "") ? null : newDate(aux);
        }
        aux = ctrl.toText().replace(/\D/g, "");
        return (aux == "") ? null : parseInt(aux, 10);
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.getVal()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.load = function(source) {
    try {
        if (this.type == "CBO") {
            var value = this.input.value;
            this.input.innerHTML = "";
            var option;
            if (!window.event) {
                option = document.createElement("OPTION");
                option.value = "";
                option.text = "";
                option.style.display = "none";
                this.input.appendChild(option);
            }
            if (isArray(source)) {
                for (var loop = 0; loop < source.length; loop++) {
                    option = document.createElement("OPTION");
                    option.value = source[loop][0];
                    option.text = source[loop][1];
                    option.selected = false;
                    if (window.event) this.input.add(option);
                    else this.input.appendChild(option);
                }
            }
            this.input.selectedIndex = (window.event ? -1 : 0);
            if (value) {
                var found = false;
                for (var loop = 0; loop < this.input.options.length; loop++) {
                    if (this.input.options[loop].value == value) {
                        this.input.value = value;
                        found = true;
                        break;
                    }
                }
                if (!found) this.loadEvent();
            }
        }
        else if (this.type == "CHK") {
            var isArr = ((isArray(source)) && (source.length == 2))
            var oldNot = this.input.not;
            var oldYes = this.input.yes;
            this.input.not = isArr ? source[0] : false;
            this.input.yes = isArr ? source[1] : true;
            if (((this.input.checked) && (oldYes != this.input.yes)) || ((!this.input.checked) && (oldNot != this.input.not))) this.loadEvent();
        }
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.load()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.loadEvent = function() {
    try {
        if (this.type == "CBO") this.input.buffer = this.input.selectedIndex;
        if ((this.type == "CBO") || (this.type == "CHK")) {
            this.MSK.value = this.getMsk();
            this.VAL.value = this.getVal();
            this.SQL.value = this.getSQL();
        }
        eval(this.change);
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.loadEvent()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.oblige = function(mode) {
    try {
        mode = (mode == true) ? true : false;
        this.obliged = mode;
        if (this.type == "CBO") this.input.className = "masksel" + (!mode ? "d" : (this.obliged ? "o" : "e"));
        else if (this.type != "CHK") this.input.className = "maskinp" + (!mode ? "d" : (this.obliged ? "o" : "e"));
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.oblige()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.setVal = function(value) {
    try {
        if (this.type == "CBO") {
            var auxVal = this.input.value;
            var found = false;
            if ((value) && ((isString(value)) || (isInteger(value, 0)))) {
                for (var loop = (window.event ? 0 : 1); loop < this.input.options.length; loop++) {
                    if (this.input.options[loop].value == value) {
                        this.input.value = value;
                        found = true;
                        break;
                    }
                }
            }
            if (!found) this.input.selectedIndex = (window.event ? -1 : 0);
            if (auxVal != this.input.value) this.loadEvent();
        }
        else if (this.type == "CHK") {
            var auxVal = this.input.checked;
            this.input.checked = (((value == this.input.yes) || (value == true)) ? true : false);
            if (this.input.checked != auxVal) this.loadEvent();
        }
        else {
            value = toString(value);
            if (this.type == "MEM") value = value.replace(/{CR}/g, "\r").replace(/{LF}/g, "\n");
            else if (this.type == "DEC") {
                var points = value.match(/\./g); points = points ? points.length : 0;
                var pointsPos = value.search(/\./);
                var commas = value.match(/\,/g); commas = commas ? commas.length : 0;
                var commasPos = value.search(/\,/);
                if (commas > 1) value = "";
                else if (commas == 0) {
                    if (points == 1) value = value.replace(/\./, ",");
                    else value = value.replace(/\./, "");
                }
                else {
                    if (commasPos < pointsPos) value = "";
                    else value = value.replace(/\./, "");
                }
            }
            this.input.value = (arguments.length == 1) ? this.input.toText(value) : "";
            this.MSK.value = this.getMsk();
            this.VAL.value = this.getVal();
            this.SQL.value = this.getSQL();
            var auxBuf = this.input.toText();
            if (this.input.buffer != auxBuf) {
                this.input.buffer = auxBuf;
                this.loadEvent();
                this.input.changed = true;
            }
        }
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.setVal()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.sizer = function(id, min, max, fSize) {
    try {
        document.getElementById(id).innerHTML = "<span id='" + id + "-sizer' class='maskinpe' style='font-size:" + fSize + "px'></span>";
        var ctrl = document.getElementById(id + "-sizer");
        ctrl.innerHTML = min;
        min = ctrl.offsetWidth;
        ctrl.innerHTML = max;
        max = ctrl.offsetWidth;
        return Math.max(min, max);
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.sizer()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.showHelp = function() {
    try {
        var type = this.container.type;
        if (type == "INT") auxMsg = "Digite apenas algarismos numéricos." + (this.container.minTitle ? "\nValor Mínimo: " + this.container.minTitle : "") + (this.container.maxTitle ? "\nValor Mínimo: " + this.container.maxTitle : "") + "\n\n";
        else if (type == "DEC") auxMsg = "Digite apenas algarismos numéricos e vírgula para o separador decimal." + (this.container.minTitle ? "\nValor Mínimo: " + this.container.minTitle : "") + (this.container.maxTitle ? "\nValor Mínimo: " + this.container.maxTitle : "") + "\n\n";
        else if (type == "DAT") {
            var auxDat = newDate().format("DATE");
            auxMsg = "Digite 8 algarismos numéricos que representem uma data válida.\nExemplo: " + auxDat.replace(/\D/g, "") + " será convertido em " + auxDat + "." + (this.container.minTitle ? "\nValor Mínimo: " + this.container.minTitle : "") + (this.container.maxTitle ? "\nValor Mínimo: " + this.container.maxTitle : "") + "\n\n";
        }
        else if (type == "HOR") {
            var auxDat = newDate().format("HOUR");
            auxMsg = "Digite 4 algarismos numéricos que representem uma hora válida, no formato HH:MM.\nExemplo: " + auxDat.replace(/\D/g, "") + " será convertido em " + auxDat + "." + (this.container.minTitle ? "\nValor Mínimo: " + this.container.minTitle : "") + (this.container.maxTitle ? "\nValor Mínimo: " + this.container.maxTitle : "") + "\n\n";
        }
        else if (type == "TIM") {
            var auxDat = newDate().format("TIME");
            auxMsg = "Digite 6 algarismos numéricos que representem uma hora válida, no formato HH:MM:SS.\nExemplo: " + auxDat.replace(/\D/g, "") + " será convertido em " + auxDat + "." + (this.container.minTitle ? "\nValor Mínimo: " + this.container.minTitle : "") + (this.container.maxTitle ? "\nValor Mínimo: " + this.container.maxTitle : "") + "\n\n";
        }
        else if (type == "CEP") auxMsg = "Digite 8 algarismos numéricos que representem um número de CEP.\n\n";
        else if (type == "TEL") auxMsg = "Digite 8 algarismos numéricos que representem um número de telefone.\n\n";
        else if (type == "CPF") auxMsg = "Digite 11 algarismos numéricos que representem um CPF válido.\n\n";
        else if (type == "CPJ") auxMsg = "Digite 14 algarismos numéricos que representem um CNPJ válido.\n\n";
        if (auxMsg) alert(auxMsg);
        this.container.focus();
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.showHelp()__" + (e.message || e);
    }
}

//**************************************************************************************************
mask.prototype.toText = function(source) {
    try {
        var auxVal = (arguments.length > 0) ? source : this.value;
        if ((auxVal == null) || (auxVal == "")) return "";
        if (this.container.isTxt) {
            auxVal = "" + auxVal;
            if ((this.container.type != "TXT") && (this.container.type != "MEM")) {
                var auxStr = "";
                for (var loop = 0; loop < auxVal.length; loop++) {
                    if (auxVal.charAt(loop).match(this.exprMask) != null) auxStr += auxVal.charAt(loop);
                }
                auxVal = auxStr;
            }
            auxVal = auxVal.trim(this.trimMode);
            auxVal = auxVal.substr(0, this.textSize);
            auxVal = auxVal.trim(this.trimMode);
            if (auxVal == "") return auxVal;
        }
        switch (this.container.type) {
        case "NOM":
            auxVal = auxVal.replace(/\'{2,}/g, "'").replace(/\-{2,}/g, "-");
            while ((auxVal.match(/^\'/) != null) || (auxVal.match(/\'$/) != null) ||
                   (auxVal.match(/ \'/) != null) || (auxVal.match(/\' /) != null) ||
                   (auxVal.match(/^\-/) != null) || (auxVal.match(/\-$/) != null) ||
                   (auxVal.match(/ \-/) != null) || (auxVal.match(/\- /) != null) ||
                   (auxVal.match(/\'\-/) != null) || (auxVal.match(/\-\'/) != null)) {
                auxVal = auxVal.replace(/^\'/, "").replace(/\'$/, "").replace(/ \'/g, "'").replace(/\' /g, "'");
                auxVal = auxVal.replace(/^\-/, "").replace(/\-$/, "").replace(/ \-/g, "-").replace(/\- /g, "-");
                auxVal = auxVal.replace(/\'\-/, "'").replace(/\-\'/, "-");
            }
            auxVal = auxVal.replace(/\'{2,}/g, "'").replace(/\-{2,}/g, "-");
            auxVal = auxVal.trim(this.trimMode);
            break;
        case "END":
            auxVal = auxVal.replace(/\'{2,}/g, "'").replace(/\.{2,}/g, ".").replace(/\-{2,}/g, "-").replace(/\/{2,}/g, "/");
            auxVal = auxVal.addressMask();
            while ((auxVal.match(/^\'/) != null) || (auxVal.match(/\'$/) != null) ||
                   (auxVal.match(/ \'/) != null) || (auxVal.match(/\' /) != null) ||
                   (auxVal.match(/^\-/) != null) || (auxVal.match(/\-$/) != null) ||
                   (auxVal.match(/ \-/) != null) || (auxVal.match(/\- /) != null) ||
                   (auxVal.match(/^\//) != null) || (auxVal.match(/\/$/) != null) ||
                   (auxVal.match(/^\./) != null) || (auxVal.match(/ \./) != null) ||
                   (auxVal.match(/((\'(\-|\.|\/))|(\-(\'|\.|\/))|(\.(\'|\-|\/))|(\/(\'|\-|\.)))/) != null)) {
                auxVal = auxVal.replace(/^\'/, "").replace(/\'$/, "").replace(/ \'/g, "'").replace(/\' /g, "'");
                auxVal = auxVal.replace(/^\-/, "").replace(/\-$/, "").replace(/ \-/g, "-").replace(/\- /g, "-");
                auxVal = auxVal.replace(/^\//, "").replace(/\/$/, "");
                auxVal = auxVal.replace(/^\./, "").replace(/ \./, ".");
                auxVal = auxVal.replace(/\'(\-|\.|\/)/, "'").replace(/\-(\'|\.|\/)/, "-").replace(/\.(\'|\-|\/)/, ".").replace(/\/(\'|\.|\-)/, "/");
            }
            auxVal = auxVal.replace(/\'{2,}/g, "'").replace(/\.{2,}/g, ".").replace(/\-{2,}/g, "-").replace(/\/{2,}/g, "/");
            auxVal = auxVal.replace(/\./g, ". ");
            auxVal = auxVal.trim(this.trimMode);
            break;
        case "EML":
            auxVal = auxVal.isEmail() ? auxVal : "";
            break;
        case "INT":
            auxVal = auxVal.replace(/\./g, "");
            auxVal = isIntegerString(auxVal, this.minValue, this.maxValue) ? ((this.leadings == 0) ? (parseInt(auxVal, 10)).currency(0) : (parseInt(auxVal, 10)).leading(this.leadings)) : "";
            break;
        case "DEC":
            auxVal = auxVal.replace(/\./g, "").replace(/\,/, ".");
            auxVal = isDecimalString(auxVal, this.minValue, this.maxValue) ? (parseFloat(auxVal)).currency(this.decimals) : "";
            break;
        case "DAT":
            if (auxVal.constructor == Date) auxVal = auxVal.format("DATE");
            auxVal = (isDateString(auxVal, this.minValue, this.maxValue) ? newDate(auxVal).format("DATE") : "");
            break;
        case "HOR":
            if (auxVal.constructor == Date) auxVal = auxVal.format("HOUR");
            auxVal = (isHourString(auxVal, this.minValue, this.maxValue) ? newDate(auxVal).format("HOUR") : "");
            break;
        case "TIM":
            if (auxVal.constructor == Date) auxVal = auxVal.format("TIME");
            auxVal = (isTimeString(auxVal, this.minValue, this.maxValue) ? newDate(auxVal).format("TIME") : "");
            break;
        case "CEP":
            auxVal = CEPMask(auxVal);
            break;
        case "TEL":
            auxVal = TELMask(auxVal);
            break;
        case "CPF":
            auxVal = CPFMask(auxVal);
            break;
        case "CPJ":
            auxVal = CNPJMask(auxVal);
            break;
        }
        if (this.container.isTxt) {
            if (this.caseMode == "U") auxVal = auxVal.toUpperCase()
            else if (this.caseMode == "L") auxVal = auxVal.toLowerCase();
        }
        return auxVal;
    }
    catch(e) {
        throw "cltmsk.js: mask.prototype.toText()__" + (e.message || e);
    }
}

//</script>
