function FerramentaHistoricoViewModel(data) {
    var mSelf = this;

    mSelf.Data = ko.observable(new FerramentaHistoricoOpcoes(mSelf));

    mSelf.FerramentaId = data.FerramentaId;

    mSelf.Template = data.Template;

    mSelf.Nome = data.Nome;

    mSelf.Titulo = data.Titulo;

    mSelf.NomeBotao = data.NomeBotao;

    mSelf.Icone = data.Icone;

    mSelf.Ordem = 2;

    mSelf.Visivel = ko.observable(true);

    mSelf.Init = function () {
    };

    mSelf.Destroy = function () {
        mSelf.Data().Destroy();
    };

    mSelf.FiltrarPontosPara = function (limite) {
        mSelf.Data().ExibirPontosParada(limite);
    };
}

function FerramentaHistoricoOpcoes(viewModel) {

    var mSelf = this;

    mSelf.timezoneOptions = ko.observableArray(timezoneOptions);

    currentTimezone = getCurrentTimezone();
    mSelf.timezoneSelecionadoInicial = ko.observable(currentTimezone);

    mSelf.timezoneSelecionadoFinal = ko.observable(currentTimezone);

    mSelf.DataInicial = ko.observable();

    mSelf.HoraInicial = ko.observable();

    mSelf.DataFinal = ko.observable();

    mSelf.HoraFinal = ko.observable();

    mSelf.HistoricoPlotado = ko.observable(false);

    mSelf.ItensExpotar = ko.observableArray([{ Nome: "XML", Valor: "XML", Selecionado: ko.observable(false) }]);

    mSelf.PlanejamentoHistorico = ko.observable();

    mSelf.ListaHistoricoBuscado = ko.observable(null);

    mSelf.ListaHistoricoParadoBuscado = ko.observable(null);

    mSelf.PolylineHistoricoId = ko.observable("polylineHistorico");

    mSelf.FerramentasDependentes = ko.observableArray(["FerramentaPosicionamento", "FerramentaVisualizacao"]);

    mSelf.DataCompletaInicial = ko.observable();

    mSelf.DataCompletaFinal = ko.observable();

    mSelf.ExibirPontosParada = function (limite) {
        if (mSelf.ListaHistoricoParadoBuscado() != null) {
            vm.Perspectiva.ControleMapa.EsconderPolyline(mSelf.PolylineHistoricoId());
        }
    };

    mSelf.BtnBuscarHistorico = function () {
        if (mSelf.ValidarDatasFiltro()) {
            mSelf.HistoricoPlotado(true);

            $(".loading-inlog").fadeIn(500);

            var dataInicial = mSelf.DataCompletaInicial();
            var dataFinal = mSelf.DataCompletaFinal();
            var timezoneInicial = null;
            var timezoneFinal = null;
            if (UsarGMTOperacao) {
                timezoneInicial = mSelf.timezoneSelecionadoInicial();
                timezoneFinal = mSelf.timezoneSelecionadoFinal();
            }

            var param = {
                'timezoneInicial': timezoneInicial,
                'timezoneFinal': timezoneFinal,
                'codigoVeiculo': vm.Perspectiva.VeiculoId(),
                'dataInicio': dataInicial,
                'dataFim': dataFinal
            };

            $.ajax({
                url: "VeiculoDetalhes/BuscarHistorico",
                contentType: 'application/json; charset=utf-8',
                dataType: "json",
                type: "GET",
                data: param,
                success: mSelf.OnBuscarHistorico,
                complete: function () {
                }
            });
        }
    };

    mSelf.BtnExportarHistoricoXml = function () {
        var itensSelecionados = [];
        ko.utils.arrayForEach(mSelf.ItensExpotar(), function (item) {
            if (item.Selecionado())
                itensSelecionados.push(item);
        });

        if (mSelf.ValidarDatasFiltro() && itensSelecionados.length > 0) {
            $(".loading-inlog").fadeIn(500);
            window.open("VeiculoDetalhes/ExportarHistoricoParaXml?codigoVeiculo=" + vm.Perspectiva.VeiculoId() + "&dataInicio=" + mSelf.DataCompletaInicial() + "&dataFim=" + mSelf.DataCompletaFinal(), "Exportar");
            $(".loading-inlog").fadeOut(500);
        }
    };

    mSelf.OnBuscarHistorico = function (data) {
        $(".loading-inlog").fadeOut(500);
        if (data != null) {
            data = ko.mapping.fromJS(data);

            if (data.Lista().length > 0) {
                if (mSelf.PlanejamentoHistorico())
                    mSelf.LimparFuncionalidades();

                mSelf.ListaHistoricoBuscado = data.Lista;
                mSelf.ListaHistoricoParadoBuscado = data.PontosParada;

                if (mSelf.ValidarDatasFiltro()) {
                    mSelf.DataCompletaInicial(mSelf.DataInicial() + "T" + mSelf.HoraInicial());
                    mSelf.DataCompletaFinal(mSelf.DataFinal() + "T" + mSelf.HoraFinal());
                } else {
                    mSelf.PreencherFiltroDatas(data.Lista().map(item => new Date(item.DataHoraGMT())));
                }

                if (mSelf.PlanejamentoHistorico()) {
                    mSelf.PlanejamentoHistorico().PlotarHistorico(data);
                } else {
                    mSelf.PlanejamentoHistorico(new PlanejamentoHistorico(data, vm.Perspectiva.ControleMapa));
                }

                //Preenche o painel de Estatísticas
                if (data.Estatisticas)
                    mSelf.PreencheEstatisticas(data.Estatisticas);

                //habilita as ferramentas dependentes
                vm.Perspectiva.AtualizaListaFerramentas(mSelf.FerramentasDependentes(), true);

                mSelf.HistoricoPlotado(true);
            } else {
                vm.ShowMensagemAlerta("Nenhum registro encontrado!");
            }
        }
    };

    mSelf.PreencherFiltroDatas = function (datas) {
        mSelf.DataCompletaInicial(new Date(Math.min(...datas)));
        mSelf.DataCompletaFinal(new Date(Math.max(...datas)));
    };

    mSelf.BtnExportarXML = function () {
        if (mSelf.ValidarDatasFiltro()) {
            $(".loading-inlog").fadeIn(500);

            var param = {
                'codigoVeiculo': vm.Perspectiva.VeiculoId(),
                'dataInicio': mSelf.DataInicial(),
                'dataFim': mSelf.DataFinal()
            };

            $.ajax({
                url: "VeiculoDetalhes/BuscarHistoricoXML",
                contentType: 'application/json; charset=utf-8',
                type: "GET",
                data: param,
                success: mSelf.OnBuscarHistorico,
                complete: function () {
                }
            });
        }
    };

    mSelf.PreencheEstatisticas = function (data) {
        var moduloEstatistica = vm.GetModuloMenuLateral("EstatisticasViewModel");

        if (moduloEstatistica) {
            moduloEstatistica.Data.PossuiHistorico(data ? true : false);

            moduloEstatistica.Data.VelocidadeMedia(data ? data.VelocidadeMedia() : data);
            moduloEstatistica.Data.Distancia(data ? data.DistanciaTotal() : data);
            moduloEstatistica.Data.TempoParadoTotal(data ? data.TempoParadoTotal() : data);
            moduloEstatistica.Data.TempoMovimentoTotal(data ? data.TempoMovimentoTotal() : data);
            moduloEstatistica.Data.TempoTotal(data ? data.TempoTotal() : data);

            moduloEstatistica.Data.TempoParadoConsiderado(data ? data.TempoParadoConsiderado() : data);
            moduloEstatistica.Data.TempoMovimentoConsiderado(data ? data.TempoMovimentoConsiderado() : data);
            moduloEstatistica.Data.NumeroParadas(data ? data.NumeroParadas() : data);
            moduloEstatistica.Data.VelocidadeMediaConsiderada(data ? data.VelocidadeMedia() : data);
        }
    }

    mSelf.BtnLimparHistorico = function () {
        mSelf.DataInicial(null);
        mSelf.DataFinal(null);
        mSelf.HoraInicial(null);
        mSelf.HoraFinal(null);

        if (mSelf.HistoricoPlotado()) {
            this.LimparDadosHistorico();

            mSelf.HistoricoPlotado(false);

            var ferramenta = vm.GetFerramenta("FerramentaUltimasPosicoes");
            if (ferramenta) {
                ferramenta.Data().QuantidadePosicoes(0);
            }
        }

        vm.Perspectiva.LimparInformacoesHistorico();
    };

    mSelf.LimparDadosHistorico = function () {
        if (mSelf.PlanejamentoHistorico())
            mSelf.PlanejamentoHistorico().Destroy();

        mSelf.ListaHistoricoBuscado(null);
        mSelf.ListaHistoricoParadoBuscado(null);

        vm.Perspectiva.AtualizaListaFerramentas(mSelf.FerramentasDependentes(), false);

        //Limpar estatísticas
        mSelf.PreencheEstatisticas(null);
    };

    mSelf.ValidarDatasFiltro = function () {
        if (mSelf.DataInicial() != null && mSelf.DataInicial() != "" && mSelf.DataFinal() != null && mSelf.DataFinal() != ""
            && mSelf.HoraInicial() != null && mSelf.HoraInicial() != "") {
            var dtInicial = new Date((this.DataInicial() + "T" + this.HoraInicial()));
            var dtFinal = new Date(this.DataFinal() + "T" + this.HoraFinal());

            if (isNaN(dtInicial.getTime())) {
                vm.ShowMensagemAlerta("A data inicial informada não é válida!");
                return;
            }
            if (isNaN(dtFinal.getTime())) {
                vm.ShowMensagemAlerta("A data final informada não é válida!");
                return;
            }
            mSelf.DataCompletaInicial(this.DataInicial() + "T" + this.HoraInicial());
            mSelf.DataCompletaFinal(this.DataFinal() + "T" + this.HoraFinal());

            if (dtFinal > dtInicial || (dtInicial.toString() == dtFinal.toString() && this.timezoneSelecionadoInicial() != this.timezoneSelecionadoFinal())) {
                var d = 1000 * 60 * 60 * 24;

                var df = new Date(this.DataFinal());
                var di = new Date(this.DataInicial());

                var days = Math.round(df.getTime() - di.getTime()) / d;

                if (days > 1) {
                    vm.ShowMensagemAlerta("Período de dias com valor alto, informe um range menor que um dia.");
                    return false;
                }
                return true;
            } else {
                vm.ShowMensagemAlerta("A data final deve ser maior que a data inicial.");
            }
        } else {
            vm.ShowMensagemAlerta("As datas inicial e final devem ser informadas!");
        }
        return false;
    };

    mSelf.Destroy = function () {
        mSelf.BtnLimparHistorico();
    };

    mSelf.LimparFuncionalidades = function () {
        var ferramenta = vm.GetFerramenta("FerramentaVisualizacao");
        ferramenta.Data().LimparFuncionalidades();
    };

    mSelf.CopiarDataHistorico = function () {
        if (mSelf.DataInicial() != null && mSelf.DataFinal() != "") {
            mSelf.DataFinal($("#Detalhes-HistoricoDataInicial").val());

            mSelf.HoraInicial("00:00");
            mSelf.HoraFinal("00:00");
        }
    };

    Date.prototype.toISOTimeZoneString = function (hour) {

        var date = eval(`new Date(new Date('${this}').getTime() + (60 * 60 * 1000 * ${hour}))`);

        var localeTimeString = date.toLocaleTimeString();
        var day = date.getDate();
        var month = date.getMonth() + 1;
        var year = date.getFullYear();

        return `${year}-${month}-${day}T${localeTimeString}`;
    }
}