// Módulo que contém funções relacionadas ao uso de F4s
rw.consultasF4 = (function ($, rw) {
    var _DIV = "#wkf4" //constante
    var _BLACK = ".wkblack" //constante
    var _CLASSE_CSS = "wkconsulta" //constante  

    function cria(urlLista, urlConsulta, idInput) {
        var f4 = {}
        var _urlLista = urlLista
        var _urlConsulta = urlConsulta
        var _idOrdenacao = idInput.replace('#', '#ordena')
        var _idTabela = idInput.replace('#', '#tabela')

        if ($(_BLACK).length == 0)
            $(document.body).append('<div class="wkblack"></div>')

        if ($(_DIV).length == 0)
            $(document.body).append('<div id="wkf4" class="wkf4">')

        $(idInput).blur(
            function () {
                var callback = function (data) {
                    if (data.resposta.status == "ERRO") {
                        rw.msg.erro(data)
                        $(idInput).parent().children(".nome").html("")
                        $(idInput).val("")
                        $(idInput).focus()
                    } else {
                        $(idInput).parent().children(".nome").html(data.resposta.registro.nome)
                    }
                }

                if ($(idInput).val() != "") {
                    $.ajax(
                        _urlConsulta, {
                            data: { codigo: String($(idInput).val()).toUpperCase() },
                            async: true,
                            success: callback
                        }
                    )
                } else {
                    $(idInput).parent().children(".nome").html("")
                }
            }
        )

        f4.getUrlLista = function () {
            if (_urlLista == "")
                rw.msg.alerta("")

            return _urlLista
        }

        f4.getUrlConsulta = function () {
            if (_urlConsulta == "")
                rw.msg.alerta("")

            return _urlConsulta
        }

        f4.getIdOrdenacao = function () {
            if (_idOrdenacao == "")
                rw.msg.alerta("")

            return _idOrdenacao
        }

        f4.getIdTabela = function () {
            if (_idTabela == "")
                rw.msg.alerta("")

            return _idTabela
        }

        f4.configuraFade = function (consulta) {
            $(_DIV + " table").hide()
            $(consulta.idTabela).show()

            $(_BLACK).css({ "width": $(window).width(), "height": $(document).height() })
            $(_BLACK).fadeTo(1000, .6)

            $(_DIV).css("top", $(window).height() / 2 - $(_DIV).height() / 2)
            $(_DIV).css("left", $(window).width() / 2 - $(_DIV).width() / 2)
            $(_DIV).fadeIn(rw.FADE())

            $(_BLACK).click(
                function () {
                    $(_BLACK + ", " + _DIV).fadeOut(rw.FADE())
                }
            )

            $(document.body).keydown(
                function (event) {
                    if (event.keyCode == 27) // ESC
                        $(_BLACK + ", " + _DIV).fadeOut(rw.FADE())
                }
            )

            var altura = 0
            var tamanhoScroll = 0

            $(_DIV).scroll(
                function () {
                    altura = $(_DIV)[0].scrollTop

                    if (tamanhoScroll == 0) { // calcular da primeira vez a posição mais baixa
                        $(_DIV).animate({ scrollTop: $(_DIV)[0].scrollHeight }, 0)
                        tamanhoScroll = $(_DIV)[0].scrollTop // pegar a posição mais baixa possivel do scroll
                        $(_DIV).animate({ scrollTop: 0 }, 0) // voltar a posição do scroll 
                    }
            
                    if (altura < 0)
                        altura = 0

                    if (altura > $(_DIV)[0].scrollHeight)
                        altura = $(_DIV)[0].scrollHeight

                    $(_DIV).animate({ scrollTop: altura }, 0)

                    if ($(_DIV)[0].scrollTop == tamanhoScroll) {
                        document.body.style.cursor = "progress"
                        consulta.buscaMais()

                        $(_DIV).animate({ scrollTop: $(_DIV)[0].scrollHeight }, 0)
                        tamanhoScroll = $(_DIV)[0].scrollTop // pegar a posição mais baixa possivel do scroll

                        $(_DIV).animate({ scrollTop: altura }, 0) // voltar a posição do scroll 
                    }
                
                    document.body.style.cursor = "default"
                }
            )
        }

        // Abre uma tela de F4. O parametro consulta é um objeto criado pela função
        // rw.consultas.cria e será usado para preencher a tabela do F4.
        f4.abre = function (consulta, fnSetaFoco) {
            return function () {
                if (consulta.async) {
                    f4.configuraFade(consulta)
                    consulta.limpa()
                } else {
                    consulta.limpa()

                    if (consulta.numRegistros > 0)
                        f4.configuraFade(consulta)
                    else if (fnSetaFoco)
                        fnSetaFoco()
                }
            }
        }

        // Adiciona um icone de F4 ao lado do input especificado
        f4.icone = function (idInput, abreF4) {
            var input = $(idInput)
            //Criando o campo de descricao
            var desc = idInput.replace('#', 'desc_f4_')

            if (!$("#" + desc).html())
                input.parent().append(" <label class='nome'id=" + desc + "></label>")

            input.after(" <img src='../images/f4.gif' alt='F4' class='wkclicavel' />")
            input.next().click(abreF4)
            input.dblclick(abreF4)

            // Atribui o comando à tecla F4 também.
            input.keydown(
                function (event) {
                    if (event.keyCode == 115) { // F4
                        event.preventDefault()
                        event.originalEvent.keyCode = 0
                        abreF4()
                    }
                }
            )
        }

        return f4
    }

    descricao = function (registro, idInput) {
        return function () {
            var input = $(idInput)
            var desc = idInput.replace('#', 'desc_f4_')
            input.val(registro.codigo).blur()
            input.parent().children(".nome").html(registro.nome)
            $(_BLACK + ", " + _DIV).fadeOut(rw.FADE())
        }
    }

    function getDiv() {
        return _DIV
    }

    function getBlack() {
        return _BLACK
    }

    function getClasseCss() {
        return _CLASSE_CSS
    }

    return {
        cria: cria,
        descricao: descricao,
        getDiv: getDiv,
        getBlack: getBlack,
        getClasseCss: getClasseCss
    }
} ($, rw))

rw.consultasF4.filiais = (function ($, rw) {
    function cria(idInput) {
        var f4 = rw.consultasF4.cria("../api/df/lista-filiais.asp", "../api/df/consulta-filial.asp", idInput)
        var montaDados = rw.df.montaDados(f4.getIdTabela(), f4.getIdOrdenacao())
        var insere = rw.df.filiais.insereF4(idInput, f4.getIdTabela())
        var consulta = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insere, montaDados, false)
        f4.icone(idInput, f4.abre(consulta))
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consulta, 'Código', 'Nome')
    }

    return {
        cria: cria
    }
} ($, rw))

rw.consultasF4.clientes = (function ($, rw) {
    function cria(idInput) {
        var f4 = rw.consultasF4.cria("../api/ft/lista-clientes.asp", "../api/ft/consulta-Cliente.asp", idInput)
        var montaDados = rw.df.montaDados(f4.getIdTabela(), f4.getIdOrdenacao())
        var insere = rw.ft.clientes.insereF4(idInput, f4.getIdTabela())
        var consulta = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insere, montaDados, false)
        f4.icone(idInput, f4.abre(consulta))
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consulta, 'Código', 'Nome')
    }

    return {
        cria: cria
    }
} ($, rw))

rw.consultasF4.clientesFornecedores = (function ($, rw) {
    function cria(idInput) {
        var f4 = rw.consultasF4.cria("../api/ft/lista-clientesFornecedores.asp", "../api/ft/consulta-dadosClienteFornecedor.asp", idInput)
        var montaDados = rw.df.montaDados(f4.getIdTabela(), f4.getIdOrdenacao())
        var insere = rw.ft.clientesFornecedores.insereF4(idInput, f4.getIdTabela())
        var consulta = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insere, montaDados, false)
        f4.icone(idInput, f4.abre(consulta))
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consulta, 'Código', 'Nome', 'Tipo')
    }

    return {
        cria: cria
    }
} ($, rw))


rw.consultasF4.servicos = (function ($, rw) {
    function cria(idInput, idInputQtdeHoras, idServico) {
        var f4 = rw.consultasF4.cria("../api/df/lista-servicos.asp", "../api/df/consulta-servico.asp", idInput)
        var montaDados = rw.df.servicos.montaDados(f4.getIdTabela(), f4.getIdOrdenacao(), idServico)
        var insere = rw.df.servicos.insereF4(idInput, f4.getIdTabela(), idInputQtdeHoras)
        var consulta = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insere, montaDados, false)
        f4.icone(idInput, f4.abre(consulta))
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consulta, 'Código', 'Nome', 'Un.', 'Classificação')
    }

    return {
        cria: cria
    }
} ($, rw))

rw.consultasF4.cfops = (function ($, rw) {

    function cria(idInput, idInputFilial, idInputCliente) {
     
        var f4 = rw.consultasF4.cria("../api/df/naturezas-operacao.asp", "../api/df/consulta-natureza.asp", idInput)
        var montaDados = rw.df.cfops.montaDados(f4.getIdOrdenacao(), idInputFilial, idInputCliente)
        var insere = rw.df.cfops.insereF4(idInput, f4.getIdTabela())
        var consulta = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insere, montaDados, false)
        var idCampoVazio = $(idInputFilial).val() == "" ? idInputFilial : idInputCliente

        f4.icone(idInput,
            f4.abre(
                consulta,
                function () {
                    idCampoVazio = $(idInputFilial).val() == "" ? idInputFilial : idInputCliente
                    $(idCampoVazio).focus()
                }
            )
        )

        $(idInput).unbind("blur")
        $(idInput).blur(
            function () {
                ////////////////////Tratamento da mascara de CFOP
                var cfop = $(idInput).val().replace(/_/g, "")

                if (cfop.charAt(cfop.length - 1) == ".")
                    cfop = cfop.slice(0, cfop.length - 1)

                if (cfop == ".")
                    cfop = ""

                $(idInput).val(cfop)
                ///////////////////Fim do tratamento da mascara de cfop
                var callback = function (data) {
                    if (data.resposta.status == "ERRO") {
                        rw.msg.erro(data)
                        $(idInput).parent().children(".nome").html("")
                        $(idInput).val("")
                        $(idInput).focus()
                    } else {
                        $(idInput).parent().children(".nome").html(data.resposta.registro.nome)
                    }
                }

                if ($(idInput).val() != "" && $(idInput).val() != "_.___.____") {
                    $.ajax(
                        f4.getUrlConsulta(), {
                            data: { 
                                codigo: $(idInput).val(),
                                filial: $(idInputFilial).val(),
                                cliente: $(idInputCliente).val()
                            },
                            async: true,
                            success: callback
                        }
                    )
                } else {
                    $(idInput).parent().children(".nome").html("")
                }
            }
        )

        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consulta, 'Código', 'Nome')
    }

    return {
        cria: cria
    }
} ($, rw))

rw.consultasF4.opsComerciais = (function ($, rw) {
    function cria(idInput) {
        var f4 = rw.consultasF4.cria("../api/df/lista-opcomerciais.asp", "../api/df/consulta-opcomerciais.asp", idInput)
        var montaDados = rw.df.montaDados(f4.getIdTabela(), f4.getIdOrdenacao())
        var insere = rw.df.opsComerciais.insereF4(idInput, f4.getIdTabela())
        var consulta = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insere, montaDados, false)
        f4.icone(idInput, f4.abre(consulta))
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consulta, 'Código', 'Nome')
    }

    return {
        cria: cria
    } 
} ($, rw))

rw.consultasF4.transportadoras = (function ($, rw) {
    function cria(idInput) {
        var f4 = rw.consultasF4.cria("../api/df/plano-transportadora.asp", "../api/df/consulta-transportadora.asp", idInput)
        var montaDados = rw.df.montaDados(f4.getIdTabela(), f4.getIdOrdenacao())
        var insere = rw.df.transportadoras.insereF4(idInput, f4.getIdTabela())
        var consulta = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insere, montaDados, false)
        f4.icone(idInput, f4.abre(consulta))
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consulta, 'Cód.', 'Nome', "Classificação", "Inscrição", "")
    }

    return {
        cria: cria
    }
} ($, rw))

rw.consultasF4.tabPrecos = (function ($, rw) {
    function cria(idInput) {
        var f4 = rw.consultasF4.cria("../api/df/tabelas-preco.asp", "../api/df/consulta-tabela-precos.asp", idInput)
        var montaDados = rw.df.montaDados(f4.getIdTabela(), f4.getIdOrdenacao())
        var insere = rw.df.tabPrecos.insereF4(idInput, f4.getIdTabela())
        var consulta = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insere, montaDados, false)
        f4.icone(idInput, f4.abre(consulta))
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consulta, 'Código', 'Nome', 'Validade')
    }

    return {
        cria: cria
    }
} ($, rw))
 
rw.consultasF4.planosContabeis = (function ($, rw) {
    function cria(idInput) {
        var f4 = rw.consultasF4.cria("../api/df/plano-contabil.asp", "../api/df/conta-contabil.asp", idInput)
        var montaDados = rw.df.montaDados(f4.getIdTabela(), f4.getIdOrdenacao())
        var insere = rw.df.planosContabeis.insereF4(idInput, f4.getIdTabela())
        var consulta = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insere, montaDados, false)
        f4.icone(idInput, f4.abre(consulta))
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consulta, 'Código', 'Nome', 'Classificação', 'Tipo')
    }

    return {
        cria: cria
    }
} ($, rw))

rw.consultasF4.planosGerenciais = (function ($, rw) {
    function cria(idInput) {
        var f4 = rw.consultasF4.cria("../api/df/plano-gerencial.asp", "../api/df/conta-gerencial.asp", idInput)
        var montaDados = rw.df.montaDados(f4.getIdTabela(), f4.getIdOrdenacao())
        var insere = rw.df.planosGerenciais.insereF4(idInput, f4.getIdTabela())
        var consulta = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insere, montaDados, false)
        f4.icone(idInput, f4.abre(consulta))
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consulta, 'Código', 'Nome', 'Classificação', 'Tipo')
    }

    return {
        cria: cria
    }
} ($, rw))


rw.consultasF4.municipios = (function ($, rw) {
    function cria(idInput) {
        var f4 = rw.consultasF4.cria("../api/df/lista-estados.asp", "../api/df/consulta-municipio.asp", idInput)
        var idSelect = rw.consultasF4.getDiv().replace("#", "#select_")

        $(rw.consultasF4.getDiv()).append('<label>&nbsp;&nbsp;UF:</label>')
        $(rw.consultasF4.getDiv()).append('<select id="' + idSelect.replace("#", "") + '"></select>')

        var idTabelaMunicipios = rw.consultasF4.getDiv().replace("#", "#tabela_mun_")
        var consultaMunicipios = rw.consultas.cria(
            idTabelaMunicipios,
            "../api/df/lista-municipios.asp",
            rw.df.municipios.insereF4(idInput, idTabelaMunicipios),
            rw.df.municipios.montaDados(null, null, idSelect)
        )
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), idTabelaMunicipios, null, consultaMunicipios, 'Código', 'Nome')

        var insere = rw.df.estados.carregaSelect(idSelect)
        var consulta = rw.consultas.cria(idTabelaMunicipios, f4.getUrlLista(), insere, rw.df.estados.montaDados(false))
        f4.icone(idInput, f4.abre(consulta))

        $(idSelect).change(function () { consultaMunicipios.limpa() })
        $(idSelect).selectedIndex = -1
    }

    return {
        cria: cria
    }
} ($, rw))

//F4 dinâmico de produtos.
//Para usá-lo é necessário somente criar um input base na view html, toda a lógica está concetrada neste módulo.
rw.consultasF4.produtos = (function ($, rw) {
    var _descricoes = []
    var _arrayBlurInputs = [false, false, false, false]
    var _map = null

    function _descricao(descricaoAtual, index) {
        if (index == 0) {
            _descricoes = []
            _arrayBlurInputs = [false, false, false, false]
            _descricoes.push(descricaoAtual)
            return descricaoAtual
        }
        var contem = false
        var retorno = ""
        _arrayBlurInputs[index] = true

        for (var i = 0; i < _descricoes.length && !contem; i++) {
            if (_descricoes[i] == descricaoAtual)
                contem = true
        }

        if (!contem)
            _descricoes.push(descricaoAtual)

        if (_descricoes.length != index) {
            var diferenca = _descricoes.length - index
            for (var i = 0; i < diferenca; i++) {
                _descricoes.pop()
            }
            _descricoes.push(descricaoAtual)
        }

        for (var i = 0; i < _descricoes.length; i++) {
            if (i > 0)
                retorno += " - "

            retorno += _descricoes[i]
        }

        return retorno
    }

    function limpaDescricao(index, map) {
        if (index == undefined)
            index = 0
        if (map == null)
            map = _map
        var retorno = ""
        var tamanho = _descricoes.length

        if (_descricoes.length != index) {
            var diferenca = _descricoes.length - index
            for (var i = 0; i < diferenca; i++) {
                _arrayBlurInputs[tamanho - i - 1] = false
                _descricoes.pop()
            }
        } else {
            _arrayBlurInputs[index] = false
            _descricoes.pop()
        }

        limpaCampos(map, index)

        for (var i = 0; i < _descricoes.length; i++) {
            if (i > 0)
                retorno += " - "

            retorno += _descricoes[i]
        }

        return retorno
    }

    function _onFocus(map) {
        return function () {
            limpaCampos(map, 0)
            _descricoes = []
            habilitaGrades(map, false)
        }
    }

    function _onKeyDown(abre) {
        return function (event) {
            if (event.keyCode == 115) { // F4
                event.preventDefault()
                event.originalEvent.keyCode = 0
                abre()
            }
        }
    }


    //efeito blur (exit) dos inputs de produto e grades.
    //map: map contendo todos os quatro inputs do f4.
    //index: posição atual do input: 0 -> produto
    //                               1 -> grade 1
    //                               2 -> grade 2
    //                               3 -> grade 3
    //idDescricao: campo de descrição dos produtos criado dinamicamente.
    //idTabPrecos: campo para filtro por tabela de preços. ***OPCIONAL***
    function _onBlur(map, index, idDescricao, idTabPrecos) {
        return function () {
            if ($(map[index].input).val() != "") {
                var url = "../api/df/consulta-produto.asp"
                limpaCampos(map, index)

                if (index == 0) { //BLUR DO EDIT DE PRODUTO     
                    _map = map
                    var callback = function (data) {
                        if (data.resposta.status == "ERRO") {
                            rw.msg.erro(data)
                            $(map[index].input).focus()
                            _descricoes = []
                            limpaCampos(map, index)
                            habilitaGrades(map, false)
                        } else {
                            $(idDescricao).html("")
                            $(idDescricao).html(_descricao(data.resposta.registro.nome, index))

                            if (Number(data.resposta.registro.grade1) > 0) { //GRADE 1
                                rw.habilitaCampo(map[1].input, true)
                                $(map[1].input).focus()

                                if (Number(data.resposta.registro.grade2) > 0) { //GRADE 2
                                    rw.habilitaCampo(map[2].input, true)

                                    if (Number(data.resposta.registro.grade3) > 0) //GRADE 3
                                        rw.habilitaCampo(map[3].input, true)
                                    else
                                        rw.habilitaCampo(map[3].input, false)
                                } else {
                                    rw.habilitaCampo(map[3].input, false)
                                    rw.habilitaCampo(map[2].input, false)
                                }

                            } else {
                                rw.habilitaCampo(map[1].input, false)
                                rw.habilitaCampo(map[3].input, false)
                                rw.habilitaCampo(map[2].input, false)
                            }
                        }
                    }

                    $.ajax(url, {
                        data: {
                            codigo: String($(map[index].input).val()).toUpperCase(),
                            codTabela: $(idTabPrecos).val(),
                            tipo: 'produto'
                        },
                        async: true,
                        success: callback
                    })

                } else { //BLUR DOS EDITS DE GRADES CRIADOS DINAMICAMENTE                    
                    if ($(map[index - 1].input).val() == "") {
                        rw.msg.alerta("Você deve preencher a grade anterior.")
                        $(map[index].input).val("")
                        $(map[index - 1].input).focus()
                    } else {
                        var callback = function (data) {
                            if (data.resposta.status == "ERRO") {
                                rw.msg.erro(data)
                                $(map[index].input).val("")
                                $(map[index].input).focus()
                                limpaCampos(map, index)
                            } else {
                                $(idDescricao).html("")
                                $(idDescricao).html(_descricao(data.resposta.registro.nome, index))
                            }
                        }

                        $(map[index].input).blur(
                            function () {
                                if (_arrayBlurInputs[index] && $(map[index].input).val() == "")
                                    $(idDescricao).html(limpaDescricao(index))
                            }
                        )

                        $.ajax(url, {
                            data: {
                                codigo: String($(map[index].input).val()).toUpperCase(),
                                codTabela: $(idTabPrecos).val(),
                                tipo: 'g' + String(index)
                            },
                            async: true,
                            success: callback
                        })
                    }
                }
            }
        }
    }

    //cria o f4 de produtos dinâmico default
    //bindBlur: flag que indica se é para criar o efeito blur dos inputs.
    //          por default serão criados, deve ser == false caso pretenda-se sobreescrever o evento de blur
    function cria(idInput, idTabPrecos, bindBlur) {
        var f4 = rw.consultasF4.cria("../api/df/lista-produtos.asp", null, idInput)
        $(idInput).unbind("blur") //desvincula o efeito blur criado em 'rw.consultasF4.cria' para reescrevê-lo
        var map = new Array()

        //PRODUTOS
        var montaDados = rw.df.produtos.montaDados(f4.getIdTabela(), f4.getIdOrdenacao(), idTabPrecos, idInput, 0)
        var insereF4 = rw.df.produtos.insereF4(idInput, f4.getIdTabela(), 0)
        var consultaF4 = rw.consultas.cria(f4.getIdTabela(), f4.getUrlLista(), insereF4, montaDados, false)
        var abreF4 = f4.abre(consultaF4)
        rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), f4.getIdTabela(), f4.getIdOrdenacao(), consultaF4, 'Código', 'Nome', 'Un.', 'Preço', 'Classificação')

        var reg = { tabela: f4.getIdTabela(), abre: abreF4, input: idInput }
        map.push(reg)

        //GRADES 1, 2 e 3
        for (var i = 1; i < 4; i++) {
            var grade = 'g' + String(i)
            var idInputGrade = '#' + grade + '_produto'
            var idTabelaGrade = '#' + grade + '_tabela'
            var idOrdGrade = '#' + grade + '_ordenacao'

            var montaDadosGrade = rw.df.produtos.montaDados(idTabelaGrade, idOrdGrade, idTabPrecos, idInput, i)
            var insereF4Grade = rw.df.produtos.insereF4(idInputGrade, idTabelaGrade, i)
            var consultaF4Grade = rw.consultas.cria(idTabelaGrade, f4.getUrlLista(), insereF4Grade, montaDadosGrade, false)
            var abreF4Grade = f4.abre(consultaF4Grade)
            rw.tabelas.criaHeader(rw.consultasF4.getDiv(), rw.consultasF4.getClasseCss(), idTabelaGrade, idOrdGrade, consultaF4Grade, 'Código', 'Descrição')

            $(idInput).parent().append(" <input id='" + idInputGrade.replace('#', '') + "' class='wkgradeproduto' disabled='disabled'/>")
            $(idInputGrade).dblclick(abreF4Grade)
            $(idInputGrade).keydown(_onKeyDown(abreF4Grade))

            if (i == 3) {
                $(idInputGrade).after(" <img id='" + idInputGrade.replace('#', '') + "_img' src='../images/f4.gif' alt='F4' class='wkclicavel' />")
                $(idInputGrade).next().click(abreF4)
                $(idInputGrade).parent().append(" <label id=" + idInput.replace('#', 'desc_f4_') + " class='nome'> </label>")
            }

            reg = { tabela: idTabelaGrade, abre: abreF4Grade, input: idInputGrade }
            map.push(reg)
        }

        var idDescricao = $(idInput).parent().children(".nome")

        //atribuição de eventos
        $(idInput).dblclick(abreF4)
        $(idInput).keydown(_onKeyDown(abreF4))
        $(idInput).focus(_onFocus(map))

        //facilidade para pular de uma tabela para outra, caso existam grades        
        for (var i = 0; i < map.length - 1; i++)
            $(map[i].tabela + "> tbody").click(map[i + 1].abre)

        //atribuição dinâmica do evento de blur
        for (var i = 0; (i < map.length) && (bindBlur != false); i++)
            $(map[i].input).blur(_onBlur(map, i, idDescricao, idTabPrecos))

        return map
    }

    function limpaCampos(map, index) {
        for (var i = index + 1; i < map.length; i++)
            $(map[i].input).val("")

        $(map[index].input).parent().children(".nome").html("")
    }

    function habilitaGrades(map, habilita) {
        for (var i = 1; i < map.length; i++)
            rw.habilitaCampo(map[i].input, habilita)
    }

    return {
        cria: cria,
        limpaCampos: limpaCampos,
        habilitaGrades: habilitaGrades,
        limpaDescricao: limpaDescricao
    }
} ($, rw))

rw.consultasF4.posicaoProdutos = (function ($, rw) {
    //efeito blur (exit) dos inputs de produto e grades.
    //map: map contendo todos os quatro inputs do f4.
    //index: posição atual do input: 0 -> produto
    //                               1 -> grade 1
    //                               2 -> grade 2
    //                               3 -> grade 3        
    function _onBlur(map, index, idTabPrecos, idFilial, idEP, idEPT, idETPE, idTabUltimasCompras) {
        return function () {
            if ($(map[index].input).val() != "") {
                //callback da fção que vai preencher os campos da view    
                var preencheCampos = rw.ft.posicaoProdutos.preencheCampos()
                rw.consultasF4.produtos.limpaCampos(map, index)

                //deverá realizar primeiramente a consulta assíncrona para o input de produto, 
                //somente para deixar habilitados os campos que têm grades
                if (index == 0) {
                    var callback = function (data) {
                        if (data.resposta.status == "ERRO") {
                            rw.msg.erro(data)
                            $(map[index].input).focus()
                            rw.consultasF4.produtos.limpaCampos(map, index)
                            rw.consultasF4.produtos.habilitaGrades(map, false)
                        } else {
                            if (Number(data.resposta.registro.grade1) > 0) { //GRADE 1
                                rw.habilitaCampo(map[1].input, true)
                                $(map[1].input).focus()

                                if (Number(data.resposta.registro.grade2) > 0) { //GRADE 2
                                    rw.habilitaCampo(map[2].input, true)

                                    if (Number(data.resposta.registro.grade3) > 0) //GRADE 3
                                        rw.habilitaCampo(map[3].input, true)
                                }
                            }

                            preencheCampos(map, idTabPrecos, idFilial, idEP, idEPT, idETPE, idTabUltimasCompras)
                        }
                    }

                    $.ajax("../api/df/consulta-produto.asp", {
                        data: {
                            codigo: $(map[index].input).val(),
                            codTabela: $(idTabPrecos).val(),
                            tipo: 'produto'
                        },
                        async: true,
                        success: callback
                    })
                } else {
                    var callback = function (data) {
                        if (data.resposta.status == "ERRO") {
                            rw.msg.erro(data)
                            $(map[index].input).val("")
                            $(map[index].input).focus()
                            rw.consultasF4.produtos.limpaCampos(map, index)
                        } else {
                            preencheCampos(map, idTabPrecos, idFilial, idEP, idEPT, idETPE, idTabUltimasCompras)
                        }
                    }

                    $.ajax("../api/df/consulta-produto.asp", {
                        data: {
                            codigo: $(map[index].input).val(),
                            codTabela: $(idTabPrecos).val(),
                            tipo: 'g' + String(index)
                        },
                        async: true,
                        success: callback
                    })
                }
            }
        }
    }

    //idInput: tag html com o input criado na página    
    //idTabPrecos: id do f4 da tabela de preços
    //idFilial: id do F4 de filiais   
    //idEP: id do chkbox EP
    //idEPT: id do chkbox EPT 
    //idETPE: id do chkbox ETPE
    //idTabUltimasCompras: id da tabela últimas compras    
    function cria(idInput, idTabPrecos, idFilial, idEP, idEPT, idETPE, idTabUltimasCompras) {
        var map = rw.consultasF4.produtos.cria(idInput, idTabPrecos, false)
        $(idEP).click(_onBlur(map, 0, idTabPrecos, idFilial, idEP, idEPT, idETPE, idTabUltimasCompras))
        $(idEPT).click(_onBlur(map, 0, idTabPrecos, idFilial, idEP, idEPT, idETPE, idTabUltimasCompras))
        $(idETPE).click(_onBlur(map, 0, idTabPrecos, idFilial, idEP, idEPT, idETPE, idTabUltimasCompras))

        for (var i = 0; i < map.length - 1; i++)
            $(map[i].input).blur(_onBlur(map, i, idTabPrecos, idFilial, idEP, idEPT, idETPE, idTabUltimasCompras))
    }

    return {
        cria: cria
    }
} ($, rw))
