function VeiculosPopUp(data) {
    const mSelf = this;
    mSelf.Data = [];

    mSelf.Init = () => {
        const h = $(".grid-footer").outerHeight();
        $("#barra-alarmes").css({ "bottom": h });
        mSelf.AlturaBarra();

        mSelf.Data = data;
        if (data.length > 0) {
            ko.utils.arrayForEach(mSelf.Data, (item) => mSelf.IncluirAtualizarPopUp(item));
        }
    };

    mSelf.IncluirAtualizarPopUp = (evento) => {
        if (evento) {
            let item = mSelf.Data[evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento];
            if (item) {
                item = evento;
                if (evento.Count > 0) {
                    const box = $("#popup_" + evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento);

                    $(box).children("[class^='icon-alert-']").text(evento.Count);
                    $(box).find("[class^='Vl-Data-Hora']").text(evento.DataHoraDisplay);
                    $(box).attr("order", evento.DataHoraTimestamp);

                    if (evento.Som) {
                        mSelf.Ringar(evento);
                    }
                }
                else if (evento.Count <= 0) {
                    mSelf.RemoverPopUp(evento);
                }
            } else {
                mSelf.Data[evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento] = evento;
                mSelf.AdicionarAlarmeHtml(evento);

                if (evento.Som) {
                    mSelf.Ringar(evento);
                }
            }
            mSelf.OrdenarPopUp();
            mSelf.RegistrarEventos(evento);
        }
    };

    mSelf.Ringar = (evento) => {
        document.getElementById('audio').load();
        document.getElementById('audio').play()
            .then(() => document.getElementById('audio').play())
            .catch(() => mSelf.ShowNotification(evento));
    }

    mSelf.ShowNotification = (evento) => {
        if (!("Notification" in window)) {
            console.log("This browser does not support desktop notification");
        } else if (Notification.permission === "granted") {
            mSelf.CreateNotification(evento);
        } else if (Notification.permission !== 'denied' || Notification.permission === "default") {
            Notification.requestPermission((permission) => {
                if (permission === "granted") {
                    mSelf.CreateNotification(evento);
                }
            });
        }
    }

    mSelf.CreateNotification = (evento) => {
        const options = {
            icon: urlGlobal + 'Content/VeiculosGenerico/img/default/logo_ginlog_56.png',
            body: `Veiculo: ${evento.Identificador}\nAlarme: ${evento.DescricaoAlarmeEvento}\n${evento.DataHoraDisplay}`,
            requireInteraction: true
        }

        const n = new Notification('ALARME', options);
        n.onclick = () => {
            window.focus();
            mSelf.Ringar();
        };
    }

    mSelf.RemoverPopUp = (evento) => {
        if (evento) {
            const item = mSelf.Data[evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento];

            if (item) {
                $("#popup_" + evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento).remove();
                delete mSelf.Data[evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento];

                mSelf.OrdenarPopUp();
                mSelf.RegistrarEventos(evento);
            }
        }
    };

    mSelf.OrdenarPopUp = () => {
        const $people = $('.lista-barra-alarmes'),
            $peopleli = $people.children('li');

        $peopleli.sort((a, b) => {
            const an = Number(a.getAttribute('order')),
                bn = Number(b.getAttribute('order'));

            if (an > bn) {
                return 1;
            }
            if (an < bn) {
                return -1;
            }
            return 0;
        });

        $peopleli.detach().appendTo($people);
    }

    mSelf.AlturaBarra = () => {
        const boxHeight = $("#barra-alarmes").outerHeight();

        if ($(".lista-barra-alarmes").outerHeight() > boxHeight) {
            $("#barra-alarmes").css({ "overflow-y": "scroll" });
            $(".lista-barra-alarmes").css({ "position": "relative" });
        } else {
            $("#barra-alarmes").css({ "overflow-y": "hidden" });
            $(".lista-barra-alarmes").css({ "position": "absolute" });
        }
    }

    mSelf.AdicionarAlarmeHtml = (evento) => {
        const box = $(".box-info-alarmes:first-child").clone();
        const gridVeiculosModulo = vm.GetModulo("GridVeiculosViewModel");

        $(".lista-barra-alarmes").prepend(box);
        box.fadeIn("slow");

        mSelf.AlturaBarra();

        $(box).attr("id", "popup_" + evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento);
        $(box).children("[class^='icon-alert-']").removeClass().addClass("icon-alert-" + evento.AlertaCor);
        $(box).children("[class^='icon-alert-']").text(evento.Count);
        $(box).children("[class^='Vl-Identificador']").text(evento.Identificador);
        $(box).find("[class^='Vl-Data-Hora']").text(evento.DataHoraDisplay);
        $(box).find("[class^='Vl-DescricaoAlarmeEvento']").text(evento.DescricaoAlarmeEvento);
        $(box).attr("order", evento.DataHoraTimestamp);

        $(box).children("[class^='btn-fechar-box']").removeClass()
            .addClass('btn-fechar-box fechar-' + evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento);

        if (!gridVeiculosModulo || gridVeiculosModulo.ExibeDetalhes()) {
            $(box).children("[class^='ver-detalhes-alerta']").removeClass()
                .addClass('ver-detalhes-alerta detalhes-' + evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento);
        }
        else $(box).children("[class^='ver-detalhes-alerta']").hide();
    }

    mSelf.RegistrarEventos = (evento) => {
        $(".fechar-" + evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento).unbind();
        $(".fechar-" + evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento).on("click", function () {
            $(this).parent().fadeOut("fast");
            mSelf.AlturaBarra();

            const popup = mSelf.GetIdPopup(this);
            mSelf.RemoverPopUp(popup);
            mSelf.FecharPopUp(popup);
        });

        $(".detalhes-" + evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento).unbind();
        $(".detalhes-" + evento.CodigoVeiculo + "_" + evento.CodigoAlarmeEvento).on("click", function () {
            const popup = mSelf.GetIdPopup(this);
            mSelf.DetalhePopUp(popup, evento.DataHora);
        });
    };

    mSelf.FecharPopUp = (data) => {
        $.ajax({
            url: urlGlobal + "RastreamentoGeral/VeiculosGenerico/LogarNotificacaoAlarme",
            dataType: "json",
            type: "POST",
            data: data,
            beforeSend: () => $(".loading-inlog").fadeIn(),
            success: () => { }
        }).done(() => $(".loading-inlog").fadeOut());
    };

    mSelf.DetalhePopUp = (data, datahora) => {
        $.ajax({
            url: urlGlobal + "RastreamentoGeral/VeiculosGenerico/LogarNotificacaoAlarme",
            dataType: "json",
            type: "POST",
            data: data,
            beforeSend: () => $(".loading-inlog").fadeIn(),
            success: () => {
                let modulo = vm.GetModulo("GridVeiculosViewModel");
                if (modulo) {
                    const veiculo = ko.utils.arrayFirst(modulo.Data.VeiculosGrid(),
                        (item) => item.CodigoVeiculo() == data.CodigoVeiculo);

                    if (veiculo) {
                        modulo.AbrirDetalhesPopup(veiculo);
                    }
                } else {
                    modulo = vm.GetModulo("GridVeiculoDetalhesViewModel");
                    if (modulo) {
                        window.open(urlGlobal + "RastreamentoGeral/VeiculoGenericoDetalhes?Visao=Veiculos&Acao=Detalhes&Data=" + data.CodigoVeiculo + ";"
                            + datahora, "_blank", "");
                    }
                }
            }
        }).done(() => $(".loading-inlog").fadeOut());
    };

    mSelf.GetIdPopup = (element) => {
        const ids = $(element).parent().attr("id").split("_");
        return { CodigoVeiculo: parseInt(ids[1]), CodigoAlarmeEvento: parseInt(ids[2]) };
    };

    mSelf.Init();
}