var Utils = {

    /**
     * Metodos desabilita todos os elementos de um formulario
     * @param idForm ID do Elemento HTML form para servir como alvo do bloqueio/desbloqueio
     * @param action TRUE para habilitar e FALSE para desabilitar
     * @return void
     */
    disableForm : function(idForm, action) {

        if(action) {

            $(idForm).find('input, select, textarea, checkbox, radio, button').attr('disabled','disabled');

        } else {

            $(idForm).find('input, select, textarea, checkbox, radio, button').removeAttr('disabled');

        }

    },

    /**
     * Converts a UTF-8 encoded string to ISO-8859-1
     * @param str_data An UTF-8 encoded string
     */
    utf8_decode : function (str_data) {

        var tmp_arr = [], i = 0, ac = 0, c1 = 0, c2 = 0, c3 = 0;
        str_data += '';

        while ( i < str_data.length ) {c1 = str_data.charCodeAt(i);
            if (c1 < 128) {
                tmp_arr[ac++] = String.fromCharCode(c1);
                i++;
            } else if ((c1 > 191) && (c1 < 224)) {c2 = str_data.charCodeAt(i+1);
                tmp_arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
                i += 2;
            } else {
                c2 = str_data.charCodeAt(i+1);c3 = str_data.charCodeAt(i+2);
                tmp_arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
        }
        return tmp_arr.join('');

    },

    /**
     * Encodes an ISO-8859-1 string to UTF-8
     * @param string An ISO-8859-1 encoded string
     */
    utf8_encode : function (string) {

        var utftext = "";
        var start, end;
        var stringl = 0;
        start = end = 0;
        stringl = string.length;
        for (var n = 0; n < stringl; n++) {
            var c1 = string.charCodeAt(n);var enc = null;

            if (c1 < 128) {
                end++;
            } else if (c1 > 127 && c1 < 2048) {enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
            } else {
                enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
            }
            if (enc !== null) {if (end > start) {
                    utftext += string.substring(start, end);
                }
                utftext += enc;
                start = end = n+1;}
        }

        if (end > start) {
            utftext += string.substring(start, string.length);}

        return utftext;
    },

    /**
    * Metodo responsável por verificação da grafia do e-mail.
    * @param mail Uma string com o e-mail a ser Validado
    * @return boolean TRUE caso e-mail for válido e FALSE caso e-mail seja inválido
    */
    validateEmail : function (mail) {

        var er          = new RegExp(/^[A-Za-z0-9_\-\.]+@[A-Za-z0-9_\-\.]{2,}\.[A-Za-z0-9]{2,}(\.[A-Za-z0-9])?/);
        var returnValue = false;

        if(typeof(mail) == "string") {

            if(er.test(mail)){returnValue = true;}

        } else if (typeof(mail) == "object") {

            if(er.test(mail.value)){returnValue = true;}

        } else {returnValue = false;}

        return returnValue;

    },

    /**
     * Metodo que limpa o hint de um elemento de entrada de um formulário
     * @param idElement
     * @param hintText
     */
    autoClearHint : function(idElement, hintText) {

        var formElement = $("#" + idElement);

        // Verficando se hint text é o valor atual do elemento
        if(formElement.val() == hintText) {formElement.val('');}

        formElement.blur(function() {

            if(formElement.val() == "") {formElement.val(hintText);}

        });

    },

    /**
     * Metodo que faz abrir um pop up centralizado na tela
     * @param url URL no qual a pop-up abrira
     * @param width Largura da Janela
     * @param height Altura da Janela
     * @param name (Opcional) Nome para a janela Pop Up, por padrao 'popup'
     * @param scrollBars (Opcional) Habilita o scroll bar da pop up. Por padrao, FALSE
     */
    openPopUp : function(url, width, height, name, scrollBars) {

        //pega a resolução do visitante
        var w = screen.width;
        var h = screen.height;

        //divide a resolução por 2, obtendo o centro do monitor
        var meio_w = w/2;
        var meio_h = h/2;

        //diminui o valor da metade da resolução pelo tamanho da janela, fazendo com q ela fique centralizada
        var altura2  = height / 2;
        var largura2 = width / 2;
        var meio1    = meio_h - altura2;
        var meio2    = meio_w - largura2;

        var windowName      = (name && name != "" ? name : "popup");
        var enableScrollBar = (scrollBars ? "scrollbars=yes, " : "");

        //abre a nova janela, já com a sua devida posição
        var popupWindow = window.open(url, windowName, enableScrollBar + 'height=' + height + ', width=' + width + ', top=' + meio1 + ', left=' + meio2 + '');
        popupWindow.focus();
        
    },

    /**
     * Checa se um valor existe em um array
     * @param needle O valor procurado.
     * @param haystack O array.
     * @param argStrict Se o terceiro parâmetro strict for TRUE então in_array() também irá checar os tipos de needle em haystack.
     */
    inArray : function (needle, haystack, argStrict) {

        var key = '', strict = !! argStrict;

        if (strict) {
            for (key in haystack) {
                if (haystack[key] === needle) {return true;
                }
            }
        } else {
            for (key in haystack) {if (haystack[key] == needle) {
                    return true;
                }
            }
        }
        return false;
    },

    /**
     * Metódo de redirecionamento para uso em botões
     */
    redirectTo : function(url) {
        location = url;
    },

    /**
     * Metodo para paginacao dos selects
     * @param url Url de destino com a hashtag [PAGE]
     * @page page Pagina a ser deslocada
     * @return void
     */
    redirectPagination : function(url, page) {

        var newUrl = url.replace("[PAGE]", page);
        this.redirectTo(newUrl);

    },

    /**
     * Metodo que verifica se a versão do navegador. Caso seja IE 6 ou inferiores, redireciona para
     * página de atualização de browser
     * @param pageError (Opcional) Página no qual o usuário será redirecionado. Por padrão: iePageError.php
     * @return void
     */
    verifyBrowserVersion : function(pageError) {

        var browserIE      = $.browser.msie;
        var versionBrowser = parseInt($.browser.version);
        var redirectPage   = (pageError ? pageError : "iePageError.php");

        if(browserIE && versionBrowser <= 6) {
            location = redirectPage;
        }

    },

    /**
     * Metodo que forca o usuario a colocar valores numericos em um campo de entrada
     * @e Evento
     * @return boolean
     */
    onlyNumbers : function(e) {

        var tecla = (window.event) ? event.keyCode : e.which;

        if((tecla>47 && tecla<58)) return true;
        else {
            if (tecla==8 || tecla==0) return true;
            else return false;
        }

    },
    
    /**
     * Desfaz o efeito de addslashes()
     * @param str A string de entrada.
     * @return Retorna uma string com as barras invertidas retiradas. (\' se torna ' e assim por diante.) Duas barras invertidas (\\) se tornam uma (\). 
     */
    stripslashes : function (str) {
        
        return (str + '').replace(/\\(.?)/g, function (s, n1) {
            switch (n1) {
            case '\\':
                return '\\';
            case '0':return '\u0000';
            case '':
                return '';
            default:
                return n1;
            }
        });

    },
    
    /**
     * Metodo que faz a truncagem de uma string
     * @param string String a ser truncada
     * @param length Tamanho final da string
     * @param complement (Opcional) Complemento para ficar no final da string caso ultrapasse length
     * @return String truncada
     */
    truncate : function(string, length, complement) {
        
        var tamanhoString = string.length;
        var finalString   = "";
        
        if(tamanhoString > length) {
            
            finalString = (complement ? string.substring(0, length) + complement : string.substring(0, length));
            
        } else {
            
            finalString = string;
            
        }
        
        return finalString;

    },
    
    /**
     * Retira as tags HTML e PHP de uma string
     * @param input A string de entrada.
     * @param allowed Voce pode utilizar o segundo parâmetro, que é opcional, para indicar tags que n?o devam ser retiradas.
     * @return Retorna a string modificada.
     */
    stripTags : function  (input, allowed) {

        // Strips HTML and PHP tags from a string  
        // 
        // version: 1103.1210
        // discuss at: http://phpjs.org/functions/strip_tags
        // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   improved by: Luke Godfrey
        // +      input by: Pul
        // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   bugfixed by: Onno Marsman
        // +      input by: Alex
        // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +      input by: Marc Palau
        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +      input by: Brett Zamir (http://brett-zamir.me)
        // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   bugfixed by: Eric Nagel
        // +      input by: Bobby Drake
        // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   bugfixed by: Tomasz Wesolowski
        // +      input by: Evertjan Garretsen
        // +    revised by: Rafa³ Kukawski (http://blog.kukawski.pl/)
        // *     example 1: strip_tags('<p>Kevin</p> <b>van</b> <i>Zonneveld</i>', '<i><b>');
        // *     returns 1: 'Kevin <b>van</b> <i>Zonneveld</i>'
        // *     example 2: strip_tags('<p>Kevin <img src="someimage.png" onmouseover="someFunction()">van <i>Zonneveld</i></p>', '<p>');
        // *     returns 2: '<p>Kevin van Zonneveld</p>'
        // *     example 3: strip_tags("<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>", "<a>");
        // *     returns 3: '<a href='http://kevin.vanzonneveld.net'>Kevin van Zonneveld</a>'
        // *     example 4: strip_tags('1 < 5 5 > 1');
        // *     returns 4: '1 < 5 5 > 1'
        // *     example 5: strip_tags('1 <br/> 1');
        // *     returns 5: '1  1'
        // *     example 6: strip_tags('1 <br/> 1', '<br>');
        // *     returns 6: '1  1'
        // *     example 7: strip_tags('1 <br/> 1', '<br><br/>');
        // *     returns 7: '1 <br/> 1'
        allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
        var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
            commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
        return input.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
            return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
        });

    },
    
    /**
     * Retira as tags HTML e PHP de uma string
     * @param input A string de entrada.
     * @return Retorna a string modificada.
     */
    stripTagsSimple : function(input) {
        
        var stripped = input.replace(/(<([^>]+)>)/ig, ""); 

        return stripped;
        
    },
    
    /**
     * Retorna a tabela de traduç?o usada por htmlspecialchars() e htmlentities()
     * @param table Há duas novas constantes definidas (HTML_ENTITIES, HTML_SPECIALCHARS) que permitem especificar a tabela que voc? quer. Valor padr?o para table é HTML_SPECIALCHARS. 
     * @param quote_style Como nas funç?es htmlspecialchars() e htmlentities() voc? pode opcionalmente especificar a quote_style que voc? está trabalhando. O padr?o é modo ENT_COMPAT. Veja a descriç?o desses modos em htmlspecialchars(). 
     * @return Retorna a tabela de traduç?o como um array. 
     */
    getHtmlTranslationTable : function (table, quote_style) {
        
        var entities = {},
            hash_map = {},        decimal = 0,
            symbol = '';
        var constMappingTable = {},
            constMappingQuoteStyle = {};
        var useTable = {},        useQuoteStyle = {};

        // Translate arguments
        constMappingTable[0] = 'HTML_SPECIALCHARS';
        constMappingTable[1] = 'HTML_ENTITIES';constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
        constMappingQuoteStyle[2] = 'ENT_COMPAT';
        constMappingQuoteStyle[3] = 'ENT_QUOTES';

        useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_COMPAT';

        if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
            throw new Error("Table: " + useTable + ' not supported');
            // return false;    }

        entities['38'] = '&amp;';
        if (useTable === 'HTML_ENTITIES') {
            entities['160'] = '&nbsp;';entities['161'] = '&iexcl;';
            entities['162'] = '&cent;';
            entities['163'] = '&pound;';
            entities['164'] = '&curren;';
            entities['165'] = '&yen;';entities['166'] = '&brvbar;';
            entities['167'] = '&sect;';
            entities['168'] = '&uml;';
            entities['169'] = '&copy;';
            entities['170'] = '&ordf;';entities['171'] = '&laquo;';
            entities['172'] = '&not;';
            entities['173'] = '&shy;';
            entities['174'] = '&reg;';
            entities['175'] = '&macr;';entities['176'] = '&deg;';
            entities['177'] = '&plusmn;';
            entities['178'] = '&sup2;';
            entities['179'] = '&sup3;';
            entities['180'] = '&acute;';entities['181'] = '&micro;';
            entities['182'] = '&para;';
            entities['183'] = '&middot;';
            entities['184'] = '&cedil;';
            entities['185'] = '&sup1;';entities['186'] = '&ordm;';
            entities['187'] = '&raquo;';
            entities['188'] = '&frac14;';
            entities['189'] = '&frac12;';
            entities['190'] = '&frac34;';entities['191'] = '&iquest;';
            entities['192'] = '&Agrave;';
            entities['193'] = '&Aacute;';
            entities['194'] = '&Acirc;';
            entities['195'] = '&Atilde;';entities['196'] = '&Auml;';
            entities['197'] = '&Aring;';
            entities['198'] = '&AElig;';
            entities['199'] = '&Ccedil;';
            entities['200'] = '&Egrave;';entities['201'] = '&Eacute;';
            entities['202'] = '&Ecirc;';
            entities['203'] = '&Euml;';
            entities['204'] = '&Igrave;';
            entities['205'] = '&Iacute;';entities['206'] = '&Icirc;';
            entities['207'] = '&Iuml;';
            entities['208'] = '&ETH;';
            entities['209'] = '&Ntilde;';
            entities['210'] = '&Ograve;';entities['211'] = '&Oacute;';
            entities['212'] = '&Ocirc;';
            entities['213'] = '&Otilde;';
            entities['214'] = '&Ouml;';
            entities['215'] = '&times;';entities['216'] = '&Oslash;';
            entities['217'] = '&Ugrave;';
            entities['218'] = '&Uacute;';
            entities['219'] = '&Ucirc;';
            entities['220'] = '&Uuml;';entities['221'] = '&Yacute;';
            entities['222'] = '&THORN;';
            entities['223'] = '&szlig;';
            entities['224'] = '&agrave;';
            entities['225'] = '&aacute;';entities['226'] = '&acirc;';
            entities['227'] = '&atilde;';
            entities['228'] = '&auml;';
            entities['229'] = '&aring;';
            entities['230'] = '&aelig;';entities['231'] = '&ccedil;';
            entities['232'] = '&egrave;';
            entities['233'] = '&eacute;';
            entities['234'] = '&ecirc;';
            entities['235'] = '&euml;';entities['236'] = '&igrave;';
            entities['237'] = '&iacute;';
            entities['238'] = '&icirc;';
            entities['239'] = '&iuml;';
            entities['240'] = '&eth;';entities['241'] = '&ntilde;';
            entities['242'] = '&ograve;';
            entities['243'] = '&oacute;';
            entities['244'] = '&ocirc;';
            entities['245'] = '&otilde;';entities['246'] = '&ouml;';
            entities['247'] = '&divide;';
            entities['248'] = '&oslash;';
            entities['249'] = '&ugrave;';
            entities['250'] = '&uacute;';entities['251'] = '&ucirc;';
            entities['252'] = '&uuml;';
            entities['253'] = '&yacute;';
            entities['254'] = '&thorn;';
            entities['255'] = '&yuml;';}

        if (useQuoteStyle !== 'ENT_NOQUOTES') {
            entities['34'] = '&quot;';
        }if (useQuoteStyle === 'ENT_QUOTES') {
            entities['39'] = '&#39;';
        }
        entities['60'] = '&lt;';
        entities['62'] = '&gt;'; 

        // ascii decimals to real symbols
        for (decimal in entities) {
            symbol = String.fromCharCode(decimal);hash_map[symbol] = entities[decimal];
        }

        return hash_map;
        }
    },
    
    /**
     * Converte todos os caracteres aplicáveis em entidades html.
     * @param string A string de entrada.
     * @param quote_style Como htmlspecialchars(), o segundo parâmetro opcional quote_style voc? define o que irá ser feito com aspas 'simples' e "duplas". Use uma das tr?s constantes com o padr?o sendo ENT_COMPAT
     * @return Retorna a string codificada. 
     */
    htmlEntityDecode : function (string, quote_style) {
        // Convert all HTML entities to their applicable characters  
        // 
        // version: 1103.1210
        // discuss at: http://phpjs.org/functions/html_entity_decode    // +   original by: john (http://www.jd-tech.net)
        // +      input by: ger
        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +   bugfixed by: Onno Marsman    // +   improved by: marc andreu
        // +    revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +      input by: Ratheous
        // +   bugfixed by: Brett Zamir (http://brett-zamir.me)
        // +      input by: Nick Kolosov (http://sammy.ru)    // +   bugfixed by: Fox
        // -    depends on: get_html_translation_table
        // *     example 1: html_entity_decode('Kevin &amp; van Zonneveld');
        // *     returns 1: 'Kevin & van Zonneveld'
        // *     example 2: html_entity_decode('&amp;lt;');    // *     returns 2: '&lt;'
        var hash_map = {},
            symbol = '',
            tmp_str = '',
            entity = '';tmp_str = string.toString();

        if (false === (hash_map = this.getHtmlTranslationTable('HTML_ENTITIES', quote_style))) {
            return false;
        } 
        // fix &amp; problem
        // http://phpjs.org/functions/get_html_translation_table:416#comment_97660
        delete(hash_map['&']);
        hash_map['&'] = '&amp;'; 
        for (symbol in hash_map) {
            entity = hash_map[symbol];
            tmp_str = tmp_str.split(entity).join(symbol);
        }tmp_str = tmp_str.split('&#039;').join("'");

        return tmp_str;
    },
    
    /**
     * Formata um número com os milhares agrupados
     */
    numberFormat : function (number, decimals, dec_point, thousands_sep) {
        // Formats a number with grouped thousands  
        // 
        // version: 1103.1210
        // discuss at: http://phpjs.org/functions/number_format    // +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +     bugfix by: Michael White (http://getsprink.com)
        // +     bugfix by: Benjamin Lupton
        // +     bugfix by: Allan Jensen (http://www.winternet.no)    // +    revised by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
        // +     bugfix by: Howard Yeend
        // +    revised by: Luke Smith (http://lucassmith.name)
        // +     bugfix by: Diogo Resende
        // +     bugfix by: Rival    // +      input by: Kheang Hok Chin (http://www.distantia.ca/)
        // +   improved by: davook
        // +   improved by: Brett Zamir (http://brett-zamir.me)
        // +      input by: Jay Klehr
        // +   improved by: Brett Zamir (http://brett-zamir.me)    // +      input by: Amir Habibi (http://www.residence-mixte.com/)
        // +     bugfix by: Brett Zamir (http://brett-zamir.me)
        // +   improved by: Theriault
        // +      input by: Amirouche
        // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)    // *     example 1: number_format(1234.56);
        // *     returns 1: '1,235'
        // *     example 2: number_format(1234.56, 2, ',', ' ');
        // *     returns 2: '1 234,56'
        // *     example 3: number_format(1234.5678, 2, '.', '');    // *     returns 3: '1234.57'
        // *     example 4: number_format(67, 2, ',', '.');
        // *     returns 4: '67,00'
        // *     example 5: number_format(1000);
        // *     returns 5: '1,000'    // *     example 6: number_format(67.311, 2);
        // *     returns 6: '67.31'
        // *     example 7: number_format(1000.55, 1);
        // *     returns 7: '1,000.6'
        // *     example 8: number_format(67000, 5, ',', '.');    // *     returns 8: '67.000,00000'
        // *     example 9: number_format(0.9, 0);
        // *     returns 9: '1'
        // *    example 10: number_format('1.20', 2);
        // *    returns 10: '1.20'    // *    example 11: number_format('1.20', 4);
        // *    returns 11: '1.2000'
        // *    example 12: number_format('1.2000', 3);
        // *    returns 12: '1.200'
        // *    example 13: number_format('1 000,50', 2, '.', ' ');    // *    returns 13: '100 050.00'
        // Strip all characters but numerical ones.
        number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
        var n = !isFinite(+number) ? 0 : +number,
            prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
            dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
            s = '',
            toFixedFix = function (n, prec) {
                var k = Math.pow(10, prec);return '' + Math.round(n * k) / k;
            };
        // Fix for IE parseFloat(0.55).toFixed(0) = 0;
        s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
        if (s[0].length > 3) {s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
        }
        if ((s[1] || '').length < prec) {
            s[1] = s[1] || '';
            s[1] += new Array(prec - s[1].length + 1).join('0');}
        return s.join(dec);
    },
    
    /**
     * Metodo que faz a validacao de um CPF
     * @param cpf String com ou sem caracteres de um CPF
     * @return boolean TRUE caso cpf seja valido e FALSE caso seja invalido
     */
    validarCpf : function (cpf) {
                
        exp = /\.|\-/g
        cpf = cpf.toString().replace( exp, "" ); 
        var digitoDigitado = eval(cpf.charAt(9)+cpf.charAt(10));
        var soma1=0, soma2=0;
        var vlr =11;
        var returnValue;
        
        for(i=0;i<9;i++){
            soma1+=eval(cpf.charAt(i)*(vlr-1));
            soma2+=eval(cpf.charAt(i)*vlr);
            vlr--;
        }       
        
        soma1 = (((soma1*10)%11)==10 ? 0:((soma1*10)%11));
        soma2 = (((soma2+(2*soma1))*10)%11);
        
        var digitoGerado = (soma1 * 10) + soma2;
        if(digitoGerado != digitoDigitado) {
            returnValue = false;
        } else {
            returnValue = true;
        }
        
        return returnValue;

    }
 
}
