(function ($) {
    $.fn.defaultmask = function(mask) {
        $(this).unbind('keypress')

        if(!mask) {
            throw 'Argumento obrigatório está faltando.'
        } else if(mask == 'cep') {
            mask = /^(\d{0,5}|\d{5}-\d{0,3})$/

            // Comportamento específico para CEP: já coloca o hífen na posição 6
            $(this).keypress(function (event) {
                if(!event.keyCode)
                    return true

                var selStart = ""
                var selEnd = ""
                    
                //compatibilização com IE 8, que não interpreta selectionStart e selctionEnd
                if($.browser.msie) {
                    var sel = rw.getSelecaoInput(this)
                    selStart = sel.start
                    selEnd = sel.end
                } else {                     
                    selStart = this.selectionStart
                    selEnd = this.selectionEnd
                }


                var comeco = this.value.substring(0, selStart)
                var final = this.value.substring(selEnd, this.value.length)

                if(mask.test(comeco + String.fromCharCode(event.keyCode) + final)) {
                    if(this.value.length == 4) {
                        this.value = comeco + String.fromCharCode(event.keyCode) + "-" + final
                        return false
                    } else {
                        return true
                    }
                } else {
                    return false
                }
            })
            return
        } else if(mask == 'data') {
            mask = /^([0-3]?[0-9]?|[0-3][0-9]\/[01]?[0-9]?|[0-3][0-9]\/[01][0-9]\/\d{0,4})$/

            // Comportamento específico para datas: já coloca a barra nas posições 3 e 6
            $(this).keypress(
                function (event) {
                    if(!event.keyCode)
                        return true

                    var selStart = ""
                    var selEnd = ""
                    
                    //compatibilização com IE 8, que não interpreta selectionStart e selctionEnd
                    if($.browser.msie) {
                        var sel = rw.getSelecaoInput(this)
                        selStart = sel.start
                        selEnd = sel.end                    
                    } else {                     
                        selStart = this.selectionStart
                        selEnd = this.selectionEnd
                    }

                    var comeco = this.value.substring(0, selStart)
                    var fim = this.value.substring(selEnd, this.value.length)
                    var sSub = comeco + String.fromCharCode(event.keyCode)

                    if(mask.test(sSub + fim)) {
                        if(this.value.length == 1) {
                            var iDia = Number(this.value.substring(0, 1) + String.fromCharCode(event.keyCode))
                            if(iDia > 31) {
                                sSub = "3"
                                return false
                            }

                            this.value = sSub + "/" + fim
                            return false
                        } else if(this.value.length == 4) {
                            var iMes = Number(this.value.substring(3, 4) + String.fromCharCode(event.keyCode))
                            if(iMes > 12) {
                                sSub = sSub + "1"
                                return false
                            }

                            this.value = sSub + "/" + fim
                            return false
                        } else
                            return true
                    } else
                        return false
                }
            )

            return
        } else if(mask == 'inteiro') {
            mask = /^(\d*)$/
        } else if(mask == 'moeda') {
            mask = /^(\d*|\d+,\d{0,2})$/
        } else if(mask == 'real') {
            mask = /^((\d{1,3}(\.\d{3})*(((\.\d{0,2}))|((\,\d*)?)))|(\d+(\,\d*)?))$/
        } else if(mask == 'hora') { //00:00
            mask = /^([0-2]?[0-9]?|[0-2][0-9]\:[0-5]?[0-9]?|[0-5][0-9])$/

            $(this).keypress(
                function(event) {                    
                    if(!event.keyCode)
                        return true 

                    var selStart = ""
                    var selEnd = ""
                    
                    //compatibilização com IE 8, que não interpreta selectionStart e selctionEnd
                    if($.browser.msie) {
                        var sel = rw.getSelecaoInput(this)
                        selStart = sel.start
                        selEnd = sel.end                    
                    } else {                     
                        selStart = this.selectionStart
                        selEnd = this.selectionEnd
                    }

                    var comeco = this.value.substring(0, selStart)
                    var fim = this.value.substring(selEnd, this.value.length)
                    var sHora = comeco + String.fromCharCode(event.keyCode)
                   
                    if(mask.test(comeco + String.fromCharCode(event.keyCode) + fim)) {
                        if(this.value.length == 1) {
                            var iHora = Number(this.value.substring(0, 1) + String.fromCharCode(event.keyCode))
                            if(iHora > 23) {
                                sHora = "2"
                                return false
                            }

                            this.value = sHora + ":" + fim
                            return false
                        } else
                            return true
                    } else
                        return false
                }
            )

            return
        } else if(mask == 'totalHora') { //000:00
            mask = /^([0-9]?[0-9]?[0-9]?|[0-9][0-9][0-9]\:[0-5]?[0-9]?|[0-5][0-9])$/

            $(this).keypress(
                function (event) {
                    if(!event.keyCode)
                        return true

                    var selStart = ""
                    var selEnd = ""
                    
                    //compatibilização com IE 8, que não interpreta selectionStart e selctionEnd
                    if($.browser.msie) {
                        var sel = rw.getSelecaoInput(this)
                        selStart = sel.start
                        selEnd = sel.end                    
                    } else {                     
                        selStart = this.selectionStart
                        selEnd = this.selectionEnd
                    }

                    var comeco = this.value.substring(0, selStart)
                    var fim = this.value.substring(selEnd, this.value.length)
                    var sHora = comeco + String.fromCharCode(event.keyCode)

                    if(mask.test(comeco + String.fromCharCode(event.keyCode) + fim)) {
                        if(this.value.length == 2) {                            
                            this.value = sHora + ":" + fim
                            return false
                        } else 
                            return true
                    } else
                        return false
                }
            )

            return
        } else if(mask == 'chave') { //0000-000000
            mask = /^([0-9]?[0-9]?[0-9]?[0-9]?|[0-9][0-9][0-9][0-9]\-\d{0,6})$/

            $(this).keypress(
                function (event) {
                    if(!event.keyCode)
                        return true

                    var selStart = ""
                    var selEnd = ""
                    
                    //compatibilização com IE 8, que não interpreta selectionStart e selctionEnd
                    if($.browser.msie) {
                        var sel = rw.getSelecaoInput(this)
                        selStart = sel.start
                        selEnd = sel.end                    
                    } else {                     
                        selStart = this.selectionStart
                        selEnd = this.selectionEnd
                    }

                    var comeco = this.value.substring(0, selStart)
                    var fim = this.value.substring(selEnd, this.value.length)
                    var sSub = comeco + String.fromCharCode(event.keyCode)

                    if(mask.test(sSub + fim)) {
                        if(this.value.length == 3) {
                            this.value = sSub + "-" + fim
                            return false
                        } else
                            return true
                    } else
                        return false
                }
            )
        } else {
            try {
                mask.test("")
            } catch (e) {
                throw 'Objeto passado como argumento não aceita o método "test".'
            }
        }

        // Comportamento padrão: só aceita inputs que batam com a regex
        $(this).keypress(function (event) {
            if(!event.keyCode)
                return true

            var selStart = ""
            var selEnd = ""
                    
            //compatibilização com IE 8, que não interpreta selectionStart e selctionEnd
            if($.browser.msie) {
                var sel = rw.getSelecaoInput(this)
                selStart = sel.start
                selEnd = sel.end                    
            } else {                     
                selStart = this.selectionStart
                selEnd = this.selectionEnd
            }

            var comeco = this.value.substring(0, selStart)
            var fim = this.value.substring(selEnd, this.value.length)

            return mask.test(comeco + String.fromCharCode(event.keyCode) + fim)
        })
    }
})(jQuery)