function SinoticoVeiculosDetalhesPerspectiva(vm, informacoes) {
    const mSelf = this;
    mSelf.TemQuePlotarVeiculo = ko.observable(false);
    mSelf.ModuloGridVeiculoDetalhesViewModel = null;
    mSelf.TemQuePlotarVeiculo = ko.observable(true);

    if (typeof (informacoes) === 'string') {
        const value = informacoes.split(';');
        informacoes = {};
        informacoes.id = parseInt(value[0]);
        informacoes.Data = value[1];
        informacoes.ConnectionId = '';
        informacoes.dataHoraHistorico = '';
    }

    mSelf.VeiculoId = ko.observable(informacoes.id);
    mSelf.DataParametro = ko.observable(informacoes.dataHoraHistorico);
    mSelf.Veiculo = null;

    mSelf.ClickBreadcumb = () => { };
    mSelf.ClickBreadcumbDetalhes = () => { };
    mSelf.AoAbrirFerramenta = () => { }

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

    mSelf.ListaModulosLaterais = ko.observableArray([
        { url: 'VeiculoGenericoDetalhes/ModuloEstatisticas', data: {} },
    ]);

    mSelf.ListaFerramentasCarregar = ko.observableArray([
        { url: 'VeiculoGenericoDetalhes/FerramentaHistorico', data: {} },
        { url: 'VeiculoGenericoDetalhes/FerramentaVisualizacao', data: {} },
        { url: 'VeiculoGenericoDetalhes/FerramentaPosicionamento', data: {} },
        { url: 'VeiculoGenericoDetalhes/FerramentaLocalizacao', data: {} },
        { url: 'VeiculoGenericoDetalhes/FerramentaUltimasPosicoes', data: {} },
        { url: 'VeiculoGenericoDetalhes/FerramentaTempoReal', data: {} },
        { url: 'VeiculoGenericoDetalhes/FerramentaReferencias', data: { codigoVeiculo: mSelf.VeiculoId() } }
    ]);

    mSelf.Init = () => {
        let params = {
            veiculoid: mSelf.VeiculoId,
            data: informacoes.Data,
            connectionId: vmEventos.TempoReal.GetId()
        };

        mSelf.ListaModulosCarregar.push({ url: 'VeiculoGenericoDetalhes/IndexVeiculos', data: params });

        vm.Breadcumbs([{ Item: 'Sinótico de Veículos', click: mSelf.ClickBreadcumb }, { Item: 'Detalhes', click: mSelf.ClickBreadcumbDetalhes }]);

        mSelf.CarregarFerramentas();
        mSelf.CarregarModulosLaterais();
        mSelf.CarregarModulos();
        mSelf.CarregarTitulo();
        vmEventos.TempoReal.SetHandlers(mSelf);
    };

    mSelf.Destroy = () => {
        ko.utils.arrayForEach(vm.Ferramentas(), (func) => {
            try {
                func.Destroy();
            } catch (e) { }
        });

        vm.Modulos.removeAll();
        vm.Ferramentas.removeAll();
        vm.ModulosLaterais.removeAll();
    };

    mSelf.CarregarFerramentas = () => {
        vm.CarregarFuncionalidades(mSelf.ListaFerramentasCarregar, (data) => {
            if (data) {
                const kojs = ko.mapping.fromJS(data);

                /* Iniciar VIEWMODEL Knockout js pelo JSON; */
                const vmInit = new window[kojs.ViewModelKnockout()](kojs);
                vm.Ferramentas.push(vmInit);
                vmInit.Init();
                mSelf.ReconfigurarFerramentas(vmInit.FerramentaId());
                vm.Ferramentas(vm.Ferramentas().sort((left, right) =>
                    left.Ordem == right.Ordem ? 0 : (left.Ordem < right.Ordem ? -1 : 1)));
            }
        });
    };

    mSelf.CarregarModulos = () => {
        vm.CarregarFuncionalidades(mSelf.ListaModulosCarregar, (data) => {
            if (data) {
                const kojs = ko.mapping.fromJS(data);

                /* Iniciar VIEWMODEL Knockout js pelo JSON; */
                const vmInit = new window[kojs.ViewModelKnockout()](kojs);
                vm.Modulos.push(vmInit);
                vmInit.Init();
                mSelf.ReconfiguarModulos(vmInit.ModuloId()); /* Aplicar enumerador para os módulos. */
            }
        });
    };

    mSelf.CarregarModulosLaterais = () => {
        vm.CarregarFuncionalidades(mSelf.ListaModulosLaterais, (data) => {
            if (data) {
                const kojs = ko.mapping.fromJS(data);

                /* Iniciar VIEWMODEL Knockout js pelo JSON; */
                const vmInit = new window[kojs.ViewModelKnockout()](kojs);
                vm.ModulosLaterais.push(vmInit);
                vmInit.Init();
                mSelf.ReconfiguarModulos(vmInit.ModuloId()); /* Aplicar enumerador para os módulos. */
            }
        });
    };

    mSelf.ReconfigurarFerramentas = () => {
        ativarIconeHover(); /* ativa o hint do menu da esquerda */

        /* remove o evento de click no menu */
        $('.menu_item').unbind('click');

        /* FUNÇÃO DO CLIQUE SOBRE UM ITEM DE MENU QUE ABRA OUTRAS JANELAS DE MENU */
        $('.menu_item').click(function () {
            if ($(this).parents('.menu_bloco').length) {
                $(this).next('.menu_bloco').css('left', $(this).parents('.menu_bloco').outerWidth() + 1 + 'px');
                $(this).next('.menu_bloco').css('top', $(this).position().top);
                $(this).parents('.menu_bloco').show(); /* mostra os blocos-pai */
            } else {
                $('.menu_bloco').not($(this).parent().next('.menu_bloco')).hide(); /* esconde todos os blocos */
            }

            $(this).parent().next('.menu_bloco').toggle('fade', 200);
        });

        /* evento do botão para fechar janela do menu */
        $('.menu_titulo .icon_fechar').click(function () {
            $(this).closest('.menu_bloco').hide();
            $(this).parents('.menu_titulo').parent('.menu_bloco').prev('.icone').removeClass('active');
        });

        $('nav .modulo_item > .menu_bloco > .menu_titulo .icon_fechar')
            .click(() => ativarIconeHover());

        /* ativar/desativar ícones do menu */
        $('#menu .icone').click(function () {
            $('.icone.active').not($(this)).removeClass('active');
            $(this).toggleClass('active');

            if ($('.icone.active').length) {
                desativarIconeHover();
            }
            else ativarIconeHover();
        });
    };

    mSelf.ReconfiguarModulos = (idModulo) => {
        eventoClicarModuloRodape(idModulo);
        eventoClicarIconeMenuDireito(idModulo);
        eventoDragModulo(idModulo);
    };

    mSelf.SetarVeiculo = (veiculo) => {
        mSelf.Veiculo = veiculo;
        mSelf.CarregarTitulo();
    };

    mSelf.CarregarTitulo = () => {
        if (mSelf.Veiculo) {
            vm.Titulo(`${mSelf.Veiculo.Identificador()} - ${mSelf.Veiculo.Descricao()}`);
        }
    };

    mSelf.AtualizaListaFerramentas = (lista, visivel) => {
        for (let x in lista) {
            const ferramenta = ko.utils.arrayFilter(vm.Ferramentas(),
                (item) => item.FerramentaId() == lista[x]);

            if (ferramenta) {
                ferramenta[0].Visivel(visivel);
            }
        }
    };

    mSelf.alinharGrid = () => { };

    mSelf.PopUp = null;

    mSelf.TratarEvento = (tipoEvento, conteudo) => {
        if (tipoEvento === 1) { /* Evento posição */
            for (let i in conteudo) {
                mSelf.AtualizarPosicao(conteudo[i].CodigoVeiculo, conteudo[i]);
            }
        } else if (tipoEvento === 5) {
            if (mSelf.PopUp != null) {
                mSelf.PopUp.IncluirAtualizarPopUp(conteudo);
            }
        } else if (tipoEvento === 7) { /* Remover Popup */
            mSelf.PopUp.RemoverPopUp(conteudo);
        } else if (tipoEvento === 8) { /* Evento de tempo real */
            mSelf.AtualizarStatusTempoReal(conteudo);
        }
    };

    mSelf.AtualizarPosicao = (codigoVeiculo, eventoPosicao) => {
        if (mSelf.Veiculo && mSelf.VeiculoId() == codigoVeiculo) {
            vm.currentMap.alterMarkerPosition('veiculos', [eventoPosicao.Latitude / 1000000, eventoPosicao.Longitude / 1000000],
                true, (item) => item.CodigoVeiculo === codigoVeiculo);

            mSelf.Veiculo.Velocidade(eventoPosicao.Velocidade);
            mSelf.Veiculo.DataHoraUltimoPeriodico(eventoPosicao.DisplayUltimoPeriodico);
        }
    };

    mSelf.AtualizarStatusTempoReal = (conteudo) => {
        if (conteudo.CodigoVeiculo == mSelf.Veiculo.CodigoVeiculo()) {
            if (conteudo.RespostaComando == 'TTR') {
                /* Mostrar mensagem de fim do tempo real */
                vm.ShowMensagemInformacao('Tempo real encerrado!');
            } else {
                if (conteudo.Status == 'X') {
                    /* Plotar ultima posição no mapa */
                    if (conteudo.Posicoes[0]) {
                        vm.currentMap.alterMarkerPosition('veiculos', [conteudo.Posicoes[0].Lat / 1000000, conteudo.Posicoes[0].Lon / 1000000],
                            true, (item) => item.CodigoVeiculo === conteudo.CodigoVeiculo);
                    }

                    /* Plotar círculo mapa */
                    if (conteudo.Posicoes[1]) {
                        const options = new InlogMaps.CircleMarkerOptions([conteudo.Posicoes[1].Lat / 1000000, conteudo.Posicoes[1].Lon / 1000000]);
                        options.style = new InlogMaps.CircleMarkerStyle(4, 1, '#008000', '#008000', 0.8);
                        options.object = conteudo.Posicoes[1];
                        vm.currentMap.drawCircleMarker('tempo-real', options, mSelf.ClickMarkerTempoReal);
                    }
                } else {
                    /* AVL ainda não foi executado */
                    vm.ShowMensagemInformacao('Aguardando tempo real do veículo');
                }
            }
        }
    };

    mSelf.ClickMarkerTempoReal = (event, object) => {
        const viewModel = (ko.mapping.fromJS({
            Codigo: object.CodigoVeiculo,
            DataHora: object.DataHoraDisplay,
            Velocidade: object.Velocidade + 'Km/h',
        }));

        const $elemento = $("<div>" + $("#template-info-window-tempo-real").html() + "</div>");
        ko.applyBindings(viewModel, $elemento[0]);

        const options = new InlogMaps.PopupOptions();
        options.content = $elemento.html();
        options.marker = 'tempo-real';
        options.conditionMarker = (item) => item.DataHoraDisplay === object.DataHoraDisplay
        vm.currentMap.drawPopup('tempo-real', options);
    }

    mSelf.RecuperarModuloGridVeiculoDetalhes = () => {
        if (mSelf.ModuloGridVeiculoDetalhesViewModel == null) {
            mSelf.ModuloGridVeiculoDetalhesViewModel = vm.GetModulo('GridVeiculoDetalhesViewModel');
        }
    };

    mSelf.AplicarStyleCSS = () => {
        $('.table-head').toggle(() => {
            $('.grid-footer').css({ 'top': 'auto', 'height': 'auto' });
            $('.tab-content').hide();
            $('#myTab').hide();
            $('#menu, #mapa').css({ 'bottom': '20px' });
            vm.currentMap.resizeMap();
        }, () => {
            $('.tab-content').show();
            $('#myTab').show();
            /* Ajusta o menu de acordo com a altura da grid */
            let h = $('.grid-footer').outerHeight();
            $('#menu, #mapa').css({ 'bottom': +h + 'px' });
            vm.currentMap.resizeMap();
        });
    };

    mSelf.EncerrarTemporReal = () =>
        $('.modal-confirm').parent().fadeIn('fast');

    mSelf.CancelarTempoReal = () => {
        $('.modal-confirm').parent().fadeOut('fast');
        $('.loading-div').fadeIn();
        const ferramenta = vm.GetFerramenta('FerramentaTempoReal');
        if (ferramenta) {
            ferramenta.Data().ConfirmacaoDesativarTempoReal(false);
        }
    };
}

function LinkFcv(Url) {
    const param = {
        'Url': '..' + Url,
        'urlRequest': window.location.host
    }

    $.ajax({
        url: urlGlobal + 'Autenticador/Autenticador/AutenticadorAplicativoBus',
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        type: 'POST',
        data: JSON.stringify(param),
        success: (retorno) => {
            if (retorno.Sucesso) {
                window.open(retorno.Objeto, '_blank', '');
            }
        }
    });
}