function FerramentaNovoFiltroVeiculosViewModel(data) {
    var mSelf = this;

    mSelf.Data = ko.observable(new FerramentaNovoFiltroVeiculos(data.Data));

    mSelf.FerramentaId = data.FerramentaId;

    mSelf.Template = data.Template;

    mSelf.Visivel = ko.observable(true);

    mSelf.Icone = data.Icone;

    mSelf.Nome = data.Nome;

    mSelf.Ordem = 6;

    mSelf.Titulo = data.Titulo;

    mSelf.NomeBotao = data.NomeBotao;

    mSelf.Init = function () {
        mSelf.Data().Init();
        //var linhas = vm.GetFerramenta("FerramentaLinhasVeiculos");
        //if (linhas)
        //    linhas.Initialize(mSelf.Data().Data);
    }
}

function FerramentaNovoFiltroVeiculos(data) {
    var mSelf = this;

    //Planejamento linhas
    ko.utils.arrayForEach(data(), function (item) {
        item.Carregado = ko.observable(false);
    });
    mSelf.Data = data;
    mSelf.ListaFiltrada = ko.observableArray([]);
    mSelf.Planejamentos = {};
    //--

    mSelf.Veiculos;
    mSelf.VeiculosFiltrados;

    mSelf.ModuloGridVeiculos;

    // itens de filtro
    mSelf.ListaTipoVeiculo = ko.observableArray([]);
    mSelf.ListaLinhas = ko.observableArray([]);
    mSelf.ListaOperacoes = ko.observableArray([]);
    mSelf.ListaIdentificadorVeiculos = ko.observableArray([]);
    mSelf.ListaDescricaoVeiculos = ko.observableArray([]);
    mSelf.ListaPlacas = ko.observableArray([]);
    mSelf.ListaNumerosSerie = ko.observableArray([]);
    mSelf.ListaGrupoControle = ko.observableArray([]);

    mSelf.Identificador = ko.observable();
    mSelf.Veiculo = ko.observable();
    mSelf.Placa = ko.observable();
    mSelf.NumeroSerie = ko.observable();

    mSelf.AvlConectado = ko.observable(false);
    mSelf.AvlDesconectado = ko.observable(false);

    mSelf.IgnicaoLigado = ko.observable(false);
    mSelf.IgnicaoDesligado = ko.observable(false);

    mSelf.PesquisarLinha = ko.observable();

    mSelf.VerPlanejamentosFiltrados = ko.observable(false);

    // filtro data hora
    mSelf.DataHoraCheckMaiorQue = ko.observable("Maior");
    mSelf.DataSelecionada = ko.observable(null);
    mSelf.HoraSelecionada = ko.observable(null);

    mSelf.CodigoLinhasFiltradas = ko.observableArray([]);

    mSelf.Init = function () {
        mSelf.ModuloGridVeiculos = vm.GetModulo("GridVeiculosViewModel");

        ko.utils.arrayForEach(mSelf.ModuloGridVeiculos.VeiculosFiltrados(), function (item) {
            if (item.GrupoControle().length >= 1)
                item.DescricaoGrupoControle(item.GrupoControle()[0].DescricaoGrupoControle())
            else
                item.DescricaoGrupoControle("SEM GRUPO DE CONTROLE");
        });

        mSelf.Veiculos = ko.observableArray(mSelf.ModuloGridVeiculos.VeiculosGrid());
        mSelf.VeiculosFiltrados = ko.observableArray(mSelf.ModuloGridVeiculos.VeiculosFiltrados());

        mSelf.CarregaFiltros();

        $("#filtroVeiculos").filtroDDS(mSelf.EventoFiltroDDS);
    };

    mSelf.EventoFiltroDDS = function (elemento) {
        if (elemento[0] != undefined) {
            var item = elemento.attr("data-item");
            $("#checkbox-" + item).attr("checked", false);
            switch (item) {
                case "item-1"://Tipo
                    mSelf.LimparListaSelecionado('ListaTipoVeiculo');
                    break;
                case "item-2"://Identificador
                    mSelf.Identificador("");
                    mSelf.LimparListaSelecionado('ListaIdentificadorVeiculos');
                    break;
                case "item-3"://Veiculo
                    mSelf.Veiculo("");
                    mSelf.LimparListaSelecionado('ListaDescricaoVeiculos');
                    break;
                case "item-4"://Placa
                    mSelf.Placa("");
                    mSelf.LimparListaSelecionado('ListaPlacas');
                    break;
                case "item-5"://Numero Serie
                    mSelf.NumeroSerie("");
                    mSelf.LimparListaSelecionado('ListaNumerosSerie');
                    break;
                case "item-6"://Linhas
                    mSelf.LimparListaSelecionado('ListaLinhas');
                    break;
                case "item-7"://Operacao
                    mSelf.LimparListaSelecionado('ListaOperacoes');
                    break;
                case "item-8"://AVL
                    {
                        mSelf.AvlConectado(false);
                        mSelf.AvlDesconectado(false);
                    }
                    break;
                case "item-9"://Ignicao
                    {
                        mSelf.IgnicaoLigado(false);
                        mSelf.IgnicaoDesligado(false);
                    }
                    break;
                case "item-10"://DataHora
                    mSelf.DataSelecionada("");
                    mSelf.HoraSelecionada("");

                    break;
                case "item-11"://Grupos de controle
                    mSelf.LimparListaSelecionado('ListaGrupoControle');
                    break;
                default:
                    break;
            }

            mSelf.EventoFiltroDDS(elemento.next());
        }

        return;
    };

    var ClassListaItem = function () {
        this.ListaTipoVeiculo = ko.observable(0);
        this.ListaLinhas = ko.observable(0);
        this.ListaOperacoes = ko.observable(0);
        this.ListaIdentificadorVeiculos = ko.observable(0);
        this.ListaDescricaoVeiculos = ko.observable(0);
        this.ListaPlacas = ko.observable(0);
        this.ListaNumerosSerie = ko.observable(0);
        this.ListaAvl = ko.observable(0);
        this.ListaIgnicao = ko.observable(0);
        this.ListaGrupoControle = ko.observable(0);
    };

    mSelf.CountListaItem = ko.observable(new ClassListaItem());

    mSelf.ChangeItemSelecionado = function (lista, data, event) {
        var item = mSelf.CountListaItem()[lista];
        if (event.target.checked)
            item(item() + 1);
        else
            item(item() - 1);

        if (item() == 0) {
            var elemento = $("#filtro-" + event.target.parentNode.parentNode.parentNode.className).next();
            mSelf.EventoFiltroDDS(elemento);
        }

        $('#btnFiltrar').prop('disabled', false);
    };

    mSelf.CarregaFiltros = function (limpar) {
        mSelf.ListaTipoVeiculo(mSelf.GetDistinctValues("TipoVeiculo", "ListaTipoVeiculo", limpar));
        mSelf.ListaLinhas(mSelf.GetDistinctValues("IdentificadorLinha", "ListaLinhas", limpar));
        mSelf.ListaOperacoes(mSelf.GetDistinctValues("DescricaoOperacao", "ListaOperacoes", limpar));
        mSelf.ListaIdentificadorVeiculos(mSelf.GetDistinctValues("Identificador", "ListaIdentificadorVeiculos", limpar));
        mSelf.ListaDescricaoVeiculos(mSelf.GetDistinctValues("Descricao", "ListaDescricaoVeiculos", limpar));
        mSelf.ListaPlacas(mSelf.GetDistinctValues("Placa", "ListaPlacas", limpar));
        mSelf.ListaNumerosSerie(mSelf.GetDistinctValues("NumeroSerie", "ListaNumerosSerie", limpar));
        mSelf.ListaGrupoControle(mSelf.GetDistinctValues("GrupoControle", "ListaGrupoControle", limpar, true, "DescricaoGrupoControle"));
    };

    mSelf.AutoCompletGenerico = function (campo, nomeLista, data, event) {
        ko.utils.arrayForEach(mSelf[nomeLista](), function (row) {
            if (row.Item.toUpperCase().indexOf(mSelf[campo]().toUpperCase()) > -1) {
                row.Visivel(true);
                return;
            }
            row.Visivel(false);
        });
    };

    mSelf.GetDistinctValues = function (coluna, lista, limpar, isArray, propriedadeItemArray) {
        if (limpar != null && limpar)
            mSelf[lista].removeAll();

        var ListItens = function (valor) {
            this.Item = valor;
            this.Visivel = ko.observable(true);

            var IsSelecionado = ko.utils.arrayFilter(mSelf[lista](), function (item) {
                return item.Selecionado() === true && item.Item === valor;
            });

            if (IsSelecionado.length > 0)
                this.Selecionado = ko.observable(true);
            else
                this.Selecionado = ko.observable(false);
        };

        var col = isArray ?
            mSelf.VeiculosFiltrados().map(item => item[coluna]()).flat().map(subItem => subItem[propriedadeItemArray]()) :
            ko.utils.arrayMap(mSelf.VeiculosFiltrados(), item => item[coluna]());
        
        var sort = ko.utils.arrayGetDistinctValues(col).sort();

        return ko.utils.arrayMap(sort, function (item) { return new ListItens(item); });
    };

    mSelf.LimparFiltros = function () {
        $(".loading-inlog").fadeIn("fast", function () {
            mSelf.VeiculosFiltrados(mSelf.Veiculos());
            mSelf.ModuloGridVeiculos.AtualizarGridFiltrado(mSelf.VeiculosFiltrados());

            mSelf.Identificador("");
            mSelf.Veiculo("");
            mSelf.Placa("");
            mSelf.NumeroSerie("");
            mSelf.DataSelecionada("");
            mSelf.HoraSelecionada("");

            mSelf.CarregaFiltros(true);

            mSelf.OcultaPlanejamento();

            vm.Perspectiva.ControleMapa.ShowTodosMarkers();

            vm.Perspectiva.ControleMapa.RefreshCluster();

            mSelf.VerPlanejamentosFiltrados(false);

            ko.utils.arrayForEach(mSelf.Veiculos(), function (v) {
                if (!v.Visivel())
                    v.Visivel(true);
            });

            var modulo = vm.GetModulo("GridVeiculosViewModel");
            if (modulo) {
                modulo.TotalVeiculos = modulo.Data.VeiculosGrid().length;
                modulo.TotalVeiculosMapa = modulo.ItensPlotados;
                modulo.AlterarTituloGrid();
            }

            var config = vm.GetFerramenta("ConfiguracoesVeiculos");

            if (config)
                config.Data().setarConfiguracoesMapa();

            $("#filtroVeiculos").filtroDDS(mSelf.EventoFiltroDDS);

            //após limpar os filtros da Grid, marcar os veículos que já estavam selecionados
            if (modulo) {
                modulo.Data.MarcarVeiculosSelecionados();
            }

            $('#btnFiltrar').prop('disabled', false);

            $(".loading-inlog").fadeOut();
        });
    };

    mSelf.FiltrarVeiculos = function () {
        $(".loading-inlog").fadeIn("fast", function () {
            mSelf.OcultaPlanejamento();

            mSelf.VeiculosFiltrados(mSelf.Veiculos());

            var lstColunaSelecao = mSelf.RecuperaFiltroSelecionandos();

            ko.utils.arrayForEach(lstColunaSelecao, function (itemFiltro) {
                mSelf.aplicarFiltroGrid(itemFiltro);
            });

            mSelf.ModuloGridVeiculos.AtualizarGridFiltrado(mSelf.VeiculosFiltrados());

            if (mSelf.VeiculosFiltrados().length > 0)
                mSelf.CarregaFiltros();

            if (lstColunaSelecao.indexOf('item-6') > -1)//caso contenha o filtro de linhas
                mSelf.PlotarPlanejamentoFiltroLinhas();

            var modulo = vm.GetModulo("GridVeiculosViewModel");
            if (modulo) {
                vm.Perspectiva.ControleMapa.ClearMarkers();

                ko.utils.arrayForEach(mSelf.VeiculosFiltrados(), function (veiculo) {
                    mSelf.SetarMarkerVeiculo(veiculo, true);
                });

                modulo.TotalVeiculosMapa = vm.Perspectiva.ControleMapa.GetQuantidadeMarkers();
                modulo.AlterarTituloGrid();

                vm.Perspectiva.ControleMapa.RefreshCluster();
            }

            $("#filtrarVeiculos").filtroDDS(mSelf.EventoFiltroDDS);

            mSelf.VerPlanejamentosFiltrados(true);

            //após filtrar os veiculos, marcar os veículos que já estavam selecionados
            if (modulo) {
                modulo.Data.MarcarVeiculosSelecionados();
            }

            $('#btnFiltrar').prop('disabled', true);

            $(".loading-inlog").fadeOut();

            //fecha a janela de filtro
            $('.menu_bloco').hide();
            $('.menu_titulo').parent('.menu_bloco').prev('.icone').removeClass('active');

            //Ativa o icone hover
            ativarIconeHover();
        });
    };

    mSelf.LimparListaSelecionado = function (nomeLista) {
        ko.utils.arrayForEach(mSelf[nomeLista](), function (item) {
            item.Selecionado(false);
        });
    };

    mSelf.SelecionarTodos = function (nomeLista, data, evt) {
        ko.utils.arrayForEach(mSelf[nomeLista](), function (item) {
            if (evt.target.checked && item.Visivel())
                item.Selecionado(true);
            else
                item.Selecionado(false);
        });

        if (evt.target.checked) {
            mSelf.CountListaItem()[nomeLista](mSelf[nomeLista]().length);
        } else {
            var elemento = $("#filtro-" + evt.target.parentNode.parentNode.parentNode.className).next();
            mSelf.CountListaItem()[nomeLista](0);
            mSelf.EventoFiltroDDS(elemento);
        }

        $('#btnFiltrar').prop('disabled', false);
    };

    mSelf.SelecionaTodosCheck = function (campo1, campo2, data, evt) {
        if (evt.target.checked) {
            mSelf[campo1](true);
            mSelf[campo2](true);
        }
        else {
            mSelf[campo1](false);
            mSelf[campo2](false);
        }
    };

    mSelf.RecuperaFiltroSelecionandos = function () {
        var itens = $(".lista-b li");
        var filtros = [];

        ko.utils.arrayForEach(itens, function (item) {
            filtros.push(item.attributes["data-item"].value);
        });

        return filtros;
    };

    mSelf.aplicarFiltroGrid = function (filtro) {
        var resultado = [];

        if ($("#filtro-" + filtro).attr("class") == 'desativado')
            return;

        switch (filtro) {
            case "item-1"://Tipo
                resultado = mSelf.FiltroArrayGenerico("TipoVeiculo", mSelf.ListaTipoVeiculo());
                break;
            case "item-2"://Identificador
                resultado = mSelf.FiltroArrayGenerico("Identificador", mSelf.ListaIdentificadorVeiculos());
                break;
            case "item-3"://Veiculo
                resultado = mSelf.FiltroArrayGenerico("Descricao", mSelf.ListaDescricaoVeiculos());
                break;
            case "item-4"://Placa
                resultado = mSelf.FiltroArrayGenerico("Placa", mSelf.ListaPlacas());
                break;
            case "item-5"://Numero Serie
                resultado = mSelf.FiltroArrayGenerico("NumeroSerie", mSelf.ListaNumerosSerie());
                break;
            case "item-6"://Linhas
                {
                    resultado = mSelf.FiltroArrayGenerico("IdentificadorLinha", mSelf.ListaLinhas());
                    var linhas = ko.utils.arrayMap(resultado, function (item) { return item['CodigoLinha']() });
                    mSelf.CodigoLinhasFiltradas(ko.utils.arrayGetDistinctValues(linhas));
                }
                break;
            case "item-7"://Operacao
                resultado = mSelf.FiltroArrayGenerico("DescricaoOperacao", mSelf.ListaOperacoes());
                break;
            case "item-8"://AVL
                {
                    var lista = [];
                    if (mSelf.AvlConectado())
                        lista.push('T');
                    if (mSelf.AvlDesconectado())
                        lista.push('F');
                    resultado = mSelf.FiltroBooleano("Conectado", lista);
                }
                break;
            case "item-9"://Ignicao
                {
                    var lista = [];
                    if (mSelf.IgnicaoLigado())
                        lista.push('L');
                    if (mSelf.IgnicaoDesligado())
                        lista.push('D');
                    resultado = mSelf.FiltroBooleano("StatusIgnicao", lista);
                }
                break;
            case "item-10"://DataHora
                resultado = mSelf.FiltroDataHora(mSelf.DataHoraCheckMaiorQue());
                break;
            case "item-11"://Grupos de controle
                //resultado = mSelf.FiltroArrayGenerico("DescricaoGrupoControle", mSelf.ListaGrupoControle());
                resultado = mSelf.FiltroMultiOperacoes("DescricaoGrupoControle", mSelf.ListaGrupoControle());
                break;
            default:
                break;
        }
        if (resultado != null)
            mSelf.VeiculosFiltrados(resultado);
    };

    mSelf.FiltroMultiOperacoes = function (campo, lista) {
        var tiposSelecionados = ko.utils.arrayFilter(lista, function (item) {
            return item.Selecionado() === true;
        });

        var tipos = ko.utils.arrayMap(tiposSelecionados, function (item) { return item["Item"] });

        if (tiposSelecionados.length > 0) {
            var veiculosFiltrados = [];

            ko.utils.arrayForEach(mSelf.VeiculosFiltrados(), function (veic) {
                var retGrep = $.grep(veic.GrupoControle(), function (op, indice) {
                    return $.inArray(op[campo](), tipos) > -1;
                });

                if (retGrep.length > 0)
                    veiculosFiltrados.push(veic);
            });
            return veiculosFiltrados;
        }
    };

    mSelf.FiltroBooleano = function (campo, lista) {
        if (lista.length <= 0) {
            return mSelf.VeiculosFiltrados();
        }
        return $.grep(mSelf.VeiculosFiltrados(), function (veic, indice) {
            return $.inArray(veic[campo](), lista) > -1;
        });
    };

    mSelf.FiltroArrayGenerico = function (campo, lista) {
        var tiposSelecionados = ko.utils.arrayFilter(lista, function (item) {
            return item.Selecionado() === true;
        });

        var tipos = ko.utils.arrayMap(tiposSelecionados, function (item) { return item["Item"] });

        if (tiposSelecionados.length > 0) {
            return $.grep(mSelf.VeiculosFiltrados(), function (veic, indice) {
                return $.inArray(veic[campo](), tipos) > -1;
            });
        }
        else
            return mSelf.VeiculosFiltrados();
    };

    mSelf.FiltroDataHora = function (maiorque) {
        if (mSelf.HoraSelecionada() == null || mSelf.HoraSelecionada() == undefined || mSelf.HoraSelecionada() == "")
            mSelf.HoraSelecionada("00:00")

        if (mSelf.DataSelecionada() == null || mSelf.DataSelecionada() == undefined || mSelf.DataSelecionada() == "")
            mSelf.DataSelecionada("");

        var data = mSelf.DataSelecionada().concat('T' + mSelf.HoraSelecionada());

        var dataValida = new Date(data);

        var timeStampData = dataValida.getTime();

        if (isNaN(timeStampData)) {
            vm.ShowMensagemAlerta("A data informada não é válida!");
            return mSelf.VeiculosFiltrados();
        }

        return ko.utils.arrayFilter(mSelf.VeiculosFiltrados(), function (veic) {
            return maiorque == "Maior" ? veic.DataHoraTimeStamp() >= timeStampData : veic.DataHoraTimeStamp() <= timeStampData;
        });
    };

    mSelf.SetarMarkerVeiculo = function (veiculo, visualizarVeiculo) {
        if (visualizarVeiculo) {
            vm.Perspectiva.ControleMapa.ShowMarker(veiculo.CodigoVeiculo());
        } else {
            vm.Perspectiva.ControleMapa.EsconderMarker(veiculo.CodigoVeiculo());
        }
    };

    mSelf.PlotarPlanejamentoFiltroLinhas = function () {
        var linhas = ko.utils.arrayMap(mSelf.VeiculosFiltrados(), function (item) { return item['CodigoLinha']() });
        mSelf.CodigoLinhasFiltradas(ko.utils.arrayGetDistinctValues(linhas));

        mSelf.ListaFiltrada([]);

        if (mSelf.CodigoLinhasFiltradas().length > 0) {
            ko.utils.arrayForEach(mSelf.CodigoLinhasFiltradas(), function (item) {
                if (item > 0) {
                    ko.utils.arrayForEach(mSelf.Data(), function (linhaFerramenta) {
                        if (parseInt(item) === parseInt(linhaFerramenta.Value()))
                            mSelf.ListaFiltrada.push(linhaFerramenta);
                    });
                }
            });
        }

        ko.utils.arrayForEach(mSelf.ListaFiltrada(), function (item) {
            item.Selected(true);
            mSelf.CarregarPlanejamentoPorLinha(item);
        });
    };

    mSelf.CarregarPlanejamentoPorLinha = function (viewModel) {
        var codigo = viewModel.Value();
        var moduloGridVeiculos = vm.GetModulo("GridVeiculosViewModel");

        if (mSelf.Planejamentos[codigo] == 0)
            return;

        if (viewModel.Carregado()) {
            if (!viewModel.Selected()) {
                mSelf.Planejamentos[codigo].Hide();
                moduloGridVeiculos.MudarCorVeiculosPorLinhaParaOperacao(codigo);
            }
            else {
                mSelf.Planejamentos[codigo].Show();
                moduloGridVeiculos.MudarCorLinhaVeiculos(mSelf.Planejamentos[codigo].Cor(), codigo);
            }
        } else if (viewModel.Selected()) {
            var url = "Veiculos/CarregarPlanejamento";
            mSelf.Planejamentos[codigo] = 0;
            $.ajax({
                url: url,
                contentType: 'application/json; charset=utf-8',
                dataType: "json",
                type: "GET",
                data: { codigoLinha: codigo },
                beforeSend: function () {
                },
                success: function (data) {
                    viewModel.Carregado(true);
                    if (data != "" && data != null && data != undefined) {
                        mSelf.Planejamentos[codigo] = new Planejamento(data, vm.Perspectiva.ControleMapa);

                        viewModel.SecondValue(mSelf.Planejamentos[codigo].Cor());

                        $("input[name=color-linhas-filtro-" + viewModel.Value() + "]").spectrum("set", viewModel.SecondValue());

                        mSelf.Planejamentos[codigo].Show();

                        //plotarPlanejamento(data, codigo);

                        //CarregarCorPorLinha(codigo, data.CorEnlace);

                        var moduloGridVeiculos = vm.GetModulo("GridVeiculosViewModel");

                        if (moduloGridVeiculos)
                            moduloGridVeiculos.MudarCorLinhaVeiculos(mSelf.Planejamentos[codigo].Cor(), codigo);
                    }
                },
                complete: function () {
                },
                error: function () {
                    viewModel.Carregado(false);
                }
            });
        }
        return true;
    };

    mSelf.OcultaPlanejamento = function () {
        var moduloGridVeiculos = vm.GetModulo("GridVeiculosViewModel");
        for (var i in mSelf.Planejamentos) {
            if (jQuery.type(mSelf.Planejamentos[i]) == "object") {
                if (mSelf.Planejamentos[i].IsShowing()) {
                    if (moduloGridVeiculos)
                        moduloGridVeiculos.MudarCorVeiculosPorLinhaParaOperacao(i);

                    mSelf.Planejamentos[i].Hide();
                }
            }
            //delete mSelf.Planejamentos[i];
        }
    };

    mSelf.CarregarPlanejamentoClick = function (data) {
        alert(data.Codigo);
    };

    mSelf.OnChangeDataHora = function () {
        $('#btnFiltrar').prop('disabled', false);
    };
}