function EnlacesModel(p) {
    "use strict";
    var mSelf = this,
        o = checkValue(p, {});

    ViewModelBase.apply(mSelf, arguments);

    mSelf.NovoEnlace = new EnlaceModel();
    mSelf.Novo = null;

    mSelf.CopiaLista = [];

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

    mSelf.Selected = ko.observable(null);

    mSelf.Show = ko.observable(true);
    mSelf.Visible = ko.observable(false);
    mSelf.ListaVisivel = ko.observable(false);
    mSelf.AddVisivel = ko.observable(false);
    mSelf.EditarVisivel = ko.observable(false);
    mSelf.isEditandoEnlace = ko.observable(false);
    mSelf.isAdicionandoEnlace = ko.observable(false);

    //flags para controle do menu
    mSelf.InformacoesNovoEnlaceVisivel = ko.observable(false);
    mSelf.InformacoesNovoEnlaceDesabilitado = ko.observable(false);

    mSelf.permiteAcao = ko.observable(true);

    mSelf.permiteAcaoInformacoesEnlace = ko.observable(true);

    mSelf.permiteAcaoTolerancias = ko.observable(true);

    mSelf.permiteAcaoItinerario = ko.observable(true);

    mSelf.permiteAcaoRotogramas = ko.observable(true);

    mSelf.permiteAcaoDesvios = ko.observable(true);

    mSelf.permiteAcaoListaExclusao = ko.observable(true);

    mSelf.permiteAcaoPontosOnibus = ko.observable(true);

    mSelf.permiteAcaoAdicionarEnlace = ko.observable(true);

    mSelf.EnlaceEdicao = ko.observable(-1);

    mSelf.mostrar = function () {
        mSelf.Visible(true);
        mSelf.ListaVisivel(true);
        mSelf.AddVisivel(false);
        mSelf.EditarVisivel(false);
        vm.permiteSelecionarTerminal(false);
    };

    mSelf.esconder = function () {
        mSelf.Visible(false);
        mSelf.ListaVisivel(false);
        mSelf.AddVisivel(false);
        mSelf.EditarVisivel(false);

        if (!vm.InformacoesLinhaVisivel()) {
            var array = mSelf.Lista();
            for (var i = 0, j = array.length; i < j; i++) {
                if (array[i].isEditando()) {
                    mSelf.editar(i, array[i]);
                }

                array[i].Itinerario.Novo.permiteAdicionarRotograma(false);
                array[i].Itinerario.Novo.permiteAdicionarRotogramaAcao(false);
                array[i].Itinerario.Novo.limparPolylinhaRotograma();
                //array[i].Itinerario.Novo.limparFormularioRotograma();
                $('body').data("atualizarRotograma", null);
            }

            if (vm.visualizarConfiguracaoRotograma()) {

                vm.visualizarConfiguracaoRotograma(false);

                mostrarGuia("guiamapa");
            }
        }
    };

    mSelf.toggleAdicionar = function () {
        if (!mSelf.isEditandoEnlace() && mSelf.permiteAcaoAdicionarEnlace()) {
            mSelf.novoEnlace();
            mSelf.permiteAcaoAdicionarEnlace(false);
        }
    };

    mSelf.toggleInformacoesNovoEnlace = function () {
        // if(!mSelf.InformacoesDesabilitado()){
        var aux = mSelf.InformacoesNovoEnlaceVisivel();
        mSelf.InformacoesNovoEnlaceVisivel(!aux);
        vm.visualizaBotoesEnlace(true);
        vm.visualizaInformacoesEnlace(mSelf.InformacoesNovoEnlaceVisivel());
        mostrarGuia(aux ? "guiamapa" : "enlace");
        //}
    };

    mSelf.novoEnlace = function () {
        if (mSelf.isEditandoEnlace() || mSelf.isAdicionandoEnlace()) {
            mSelf.zerarEdicaoEnlace();
            mSelf.Novo = new EnlaceModel();
        }

        mSelf.fecharInfoWindows();

        mSelf.escoderItinerarios();
        mSelf.esconderTodosRotogramas();

        vm.Terminais.setarCoresTerminais();

        $("#modalAvisos").modal("hide");
        var aux = mSelf.AddVisivel(),
            obj = mSelf.NovoEnlace.clone();

        if (aux) {
            mSelf.finalizar();
        }

        var isNovoEnlace = mSelf.isAdicionandoEnlace();
        mSelf.isAdicionandoEnlace(!isNovoEnlace);

        mSelf.Novo = new EnlaceModel(obj);
        mSelf.ListaVisivel(aux);
        mSelf.AddVisivel(!aux);
        ajusteTamanhos();
        vm.permiteSelecionarTerminal(!aux);
        vm.permiteAdicionarEnlace(true);
        vm.visualizarAreaTrabalho(true);

        vm.CadastroEnlace = mSelf.NovoEnlace.clone();
        vm.visualizaInformacoesLinha(false);
        vm.visualizaInformacoesEnlace(true);
        vm.visualizaBotoesEnlace(true);
        vm.habilitaAdicionarEnlace(false);

        mSelf.limparCampos();

        var eventHandlers = [],
            clickHandler = new Handler({ eventName: "click" });
        clickHandler.callback = function (e, terminal) {
            if (vm.Enlaces.Novo != null && vm.Enlaces.Novo.InfoVisivel()) {
                if (mSelf.Novo.TerminalInicial() == terminal) {
                    if (mSelf.Novo.TerminalFinal() == null) {
                        abrirModalMensagem("Selecionar enlace", "Deseja selecionar " + terminal.Descricao() + " como terminal inicial e final?",
                            {
                                resizable: false,
                                height: 190,
                                modal: true,
                                buttons: {
                                    "Sim": function () {
                                        mSelf.Novo.selecionarTerminal(terminal);
                                        terminal.toggleInfoWindow("Terminal");
                                        $(this).dialog("close");
                                    },
                                    "Não": function () {
                                        mSelf.Novo.TerminalInicial(null);
                                        $(this).dialog("close");
                                    }
                                }
                            });
                    } else {
                        mSelf.Novo.TerminalInicial(null);
                    }

                } else if (mSelf.Novo.TerminalFinal() == terminal) {
                    if (mSelf.Novo.TerminalInicial() == null) {
                        abrirModalMensagem("Selecionar enlace", "Deseja selecionar " + terminal.Descricao() + " como terminal inicial e final?",
                            {
                                resizable: false,
                                height: 190,
                                modal: true,
                                buttons: {
                                    "Sim": function () {
                                        mSelf.Novo.selecionarTerminal(terminal);
                                        terminal.toggleInfoWindow("Terminal");
                                        $(this).dialog("close");
                                    },
                                    "Não": function () {
                                        mSelf.Novo.TerminalFinal(null);
                                        $(this).dialog("close");
                                    }
                                }
                            });
                    } else {
                        mSelf.Novo.TerminalFinal(null);
                    }
                    terminal.toggleInfoWindow();
                } else if (mSelf.Novo.TerminalInicial() == null ||
                    mSelf.Novo.TerminalFinal() == null) {
                    mSelf.Novo.selecionarTerminal(terminal);
                }
            };
        };

        vm.Terminais.setFormaEvents([
            clickHandler
        ]);
    }

    mSelf.zerarEdicaoEnlace = function () {
        mSelf.limparTerminaisMapa();
        vm.Terminais.mostrarTodosTerminais();
        mSelf.isEditandoEnlace(false);
        vm.Enlaces.Novo.isEditando(false);
        //mSelf.limparSetaMapa();

        if (vm.Enlaces.Novo.Itinerario.Novo.hasItinerario()) {

            mSelf.limparRotograma();

            vm.Enlaces.Novo.Itinerario.Novo.polylinhaSelecionada.setMap(null);

            vm.Enlaces.Novo.Itinerario.Novo.polylinha.setMap(null);

            vm.Enlaces.Novo.Itinerario.Novo.polylinhaSelecionada = new google.maps.Polyline({
                strokeColor: '#FF0000',
                strokeOpacity: 1.0,
                strokeWeight: 10,
                map: map,
                zIndex: 3
            });
        }
        vm.isEditandoItinerario(false);
    }

    mSelf.Add = ko.computed(function () {
        return mSelf.AddVisivel() && !mSelf.ListaVisivel();
    }, mSelf);

    mSelf.Novo = null;

    mSelf.Edit = ko.computed(function () {
        return mSelf.Visible() && mSelf.EditarVisivel();
    }, mSelf);

    mSelf.mostrarEditar = function () {
        var aux = mSelf.EditarVisivel();
        mSelf.ListaVisivel(aux);
        mSelf.EditarVisivel(!aux);
        ajusteTamanhos();
    };

    mSelf.remover = function () {
        if (!mSelf.Novo.ExcluirDesabilitado()) {
            var descricao = mSelf.Novo.Descricao();
            if (descricao == "" || descricao == null)
                descricao = "Enlace " + (mSelf.Lista.indexOf(mSelf.Novo) + 1);

            abrirModalMensagem("Excluir enlace",
                "Deseja excluir o enlace " + descricao + "?",
                {
                    resizable: false,
                    height: 190,
                    modal: true,
                    buttons: [
                        {
                            text: "Sim",
                            "class": "botaoSimExcluirEnlace",
                            click: function () {
                                vm.Enlaces.confirmarRemover();
                                $(this).dialog("close");
                            }
                        },
                        {
                            text: "Não",
                            "class": "botaoNaoExcluirEnlace",
                            click: function () {
                                $(this).dialog("close");
                            }
                        }
                    ]
                });
        }
    };

    mSelf.confirmarRemover = function () {
        $("#modalAvisos").modal("hide");
        //plota itinerário existente
        if (mSelf.Novo.Itinerario.Novo.hasItinerario()) {

            mSelf.limparRotograma();

            vm.Enlaces.Novo.Rotogramas.removeAll();

            mSelf.Novo.Itinerario.Novo.polylinha.setMap(null);

            mSelf.Novo.Itinerario.Novo.navegarTeclado(true);
        }

        //mSelf.limparSetaMapa();
        mSelf.Novo.Apagado(true);
        mSelf.Novo.EnlaceAlterado(true);

        //mSelf.Lista.remove(mSelf.Novo)

        if (vm.Enlaces.Novo.isEditando()) {
            vm.Enlaces.Novo.isEditando(false);
            vm.Enlaces.Novo.TerminalInicial().infoWindow.setMap(null);
            vm.Enlaces.Novo.TerminalFinal().infoWindow.setMap(null);
        }
        vm.Enlaces.isEditandoEnlace(false);
        vm.visualizaBotoesEnlace(false);
        vm.Terminais.mostrarTodosTerminais();
        mSelf.mostrarItinerarios();
        if (mSelf.Lista().length == 0) {
            vm.Terminais.setarCoresTerminais();
        }

        mSelf.desabilitarEnlaces(false);

        var index = mSelf.Lista.indexOf(mSelf.Novo);

        for (var indexDesvio in mSelf.Novo.Desvios.Lista()) {
            mSelf.Novo.Desvios.Lista()[indexDesvio].Itinerario.Novo.polylinha.setMap(null);
        }
        mSelf.Novo.Desvios.Lista.removeAll();

        mSelf.Lista.replace(mSelf.Lista()[index], mSelf.Novo);
    }

    mSelf.salvarItem = function (index) {

        mSelf.Novo.limparRotogramasClonegemEnlace();

        mSelf.Novo.visualizandoItinerarioEnlace(true);

        mSelf.Novo.EnlaceAlterado(true);

        mSelf.restaurarEnlaceOriginal();

        //mSelf.Novo.drawArrowEnlace();
        //var clone = mSelf.Novo.clone();
        //delete clone.Rotogramas;
        mSelf.Novo.PossuiAlteracao(false);

        var novoEnlace = mSelf.Novo, exclusoes = null;

        novoEnlace.TerminalInicial(mSelf.Novo.TerminalInicial());
        novoEnlace.TerminalFinal(mSelf.Novo.TerminalFinal());

        exclusoes = ko.utils.arrayMap(mSelf.Novo.ListaExclusao.Lista(), function (item) {
            return new EntidadeExclusaoModel(item.clone());
        });

        var existeEnlace = ko.utils.arrayFirst(mSelf.Lista(), function (item) {
            return item.Codigo() == novoEnlace.Codigo();
        });

        if (existeEnlace) {
            mSelf.Lista.replace(mSelf.Lista()[index], novoEnlace);
        } else {
            novoEnlace.EnlaceAlterado(true);
            mSelf.Lista().push(novoEnlace);
        }

        // exclui do mapa os terminais inicial e final, lista de exclusao e desvios
        mSelf.finalizarEnlace();

        mSelf.mostrar();
        vm.permiteAdicionarEnlace(true);
        vm.visualizaInformacoesEnlace(false);
        vm.visualizaBotoesEnlace(false);
        mostrarGuia("guiamapa");
        mSelf.isAdicionandoEnlace(false);
        mSelf.isEditandoEnlace(false);
        //vm.Terminais.mostrarTodosTerminais();
        vm.Enlaces.Novo.fecharItensMenu("");
        mSelf.EnlaceEdicao(-1);

        vm.Enlaces.Novo.isEditando(false);

        vm.visualizarConfiguracaoRotograma(false);

        //retorna o bound para todos os terminais
        vm.Terminais.focarTodosTerminais();

        mSelf.limparCampos();
        //mSelf.limparSetaMapa();

        mSelf.Novo.CopiaTolerancias = null;
        mSelf.Novo.CopiaInformacoesEnlace = null;

        mSelf.permiteAcao(true);

        mSelf.fecharInfoWindows();

        vm.Enlaces.setarEventosDesvios();
    };

    mSelf.finalizarEnlace = function () {
        mSelf.limparTerminaisMapa();

        if (mSelf.Novo.Itinerario.Novo.polylinha != null) {
            mSelf.Novo.Itinerario.Novo.idxIni = -1;
            mSelf.Novo.Itinerario.Novo.setPathSelecionado();

            vm.ListaPolylinhas.push(mSelf.Novo.Itinerario.Novo.polylinha);

            mSelf.Novo.Itinerario.Novo.polylinha.setMap(null);

            //mSelf.limparRotograma();
        }

        //remove os desvios do mapa
        for (var i in mSelf.Novo.Desvios.Lista()) {
            var desvio = mSelf.Novo.Desvios.Lista()[i];
            desvio.Itinerario.Novo.polylinha.setMap(null);
            if (desvio.Itinerario.Novo.polylinha.infoWindow)
                desvio.Itinerario.Novo.polylinha.infoWindow.setMap(null);
        }
    };

    mSelf.cancelarNovo = function () {
        if (mSelf.Novo.TerminalInicial() != null)
            mSelf.Novo.TerminalInicial().toggleInfoWindow();
        if (mSelf.Novo.TerminalFinal() != null)
            mSelf.Novo.TerminalFinal().toggleInfoWindow();
        mSelf.toggleAdicionar();
        vm.permiteAdicionarEnlace(true);
        vm.visualizaInformacoesEnlace(false);
        vm.Enlaces.isEditandoEnlace(false);
        vm.visualizarConfiguracaoRotograma(false);
        //$(".notifyjs-wrapper").trigger('notify-hide');
    };

    mSelf.cancelarEdicaoEnlace = function () {
        if (mSelf.Novo.PossuiAlteracao()) {
            var descricao = mSelf.Novo.Descricao();
            if (descricao == "" || descricao == null)
                descricao = "Enlace " + (mSelf.Lista.indexOf(mSelf.Novo) + 1);

            if (vm.Enlaces.Novo.isEditando()) {
                abrirModalMensagem("Cancelar enlace", "Deseja cancelar as alterações no enlace " + descricao + "?",
                    {
                        resizable: false,
                        height: 190,
                        modal: true,
                        buttons: {
                            "Sim": function () {
                                mSelf.confirmaCancelarEnlace()
                                $(this).dialog("close");
                            },
                            "Não": function () {
                                $(this).dialog("close");
                            }
                        }
                    });
            } else {
                mSelf.confirmaCancelarEnlace();
            }
        } else {
            mSelf.confirmaCancelarEnlace();
        }
        var selecionados = ko.utils.arrayFilter(vm.Terminais.Todos(), function (item) {
            return item.Selected()
        });
        if (selecionados) {
            vm.Terminais.bounds = new google.maps.LatLngBounds();
            for (var i in selecionados) {
                vm.Terminais.bounds.union(selecionados[i].bounds);
            }
            map.fitBounds(vm.Terminais.bounds);
        }
    };

    mSelf.confirmaCancelarEnlace = function () {
        mSelf.Novo.limparRotogramasClonegemEnlace();

        mSelf.fecharInfoWindows();

        mSelf.restaurarEnlaceCopia();

        mSelf.Novo.Itinerario.Novo.idxIni = -1;
        mSelf.Novo.Itinerario.Novo.setPathSelecionado();

        mostrarGuia("guiamapa");
        mSelf.isEditandoEnlace(false);
        vm.visualizaBotoesEnlace(false);
        vm.visualizaInformacoesEnlace(false);
        mSelf.finalizar();
        mSelf.AddVisivel(false);
        mSelf.isAdicionandoEnlace(false);
        mSelf.ListaVisivel(true);
        mSelf.Novo.Itinerario.Novo.visualizarRotograma(false);
        mSelf.EnlaceEdicao(-1);

        mSelf.Novo.isEditando(false);

        mSelf.limparCampos();

        //vm.Terminais.mostrarTodosTerminais();

        mSelf.ExibirTodosTerminaisLinha();

        vm.visualizarConfiguracaoRotograma(false);

        mSelf.Novo.fecharItensMenu("");

        mSelf.limparTerminaisMapa()

        mSelf.finalizarEnlace();

        mSelf.desabilitarEnlaces(false);

        mSelf.permiteAcao(true);

        mSelf.permiteAcaoAdicionarEnlace(true);

        mSelf.plotarTodosDesvios();

        mSelf.setarEventosItinerarios();

        mSelf.setarEventosDesvios();

        mSelf.plotarTodosRotogramas();

        mSelf.mostrarItinerarios();
    }

    mSelf.ExibirTodosTerminaisLinha = function () {
        var keysTerminais = Object.keys(vm.TodosTerminaisSelecionados);

        for (var i in keysTerminais) {
            vm.TodosTerminaisSelecionados[keysTerminais[i]].forma.setMap(map);
            vm.TodosTerminaisSelecionados[keysTerminais[i]].labelMap.setMap(map);
        }
    }

    mSelf.salvar = function () {

        var send = null;

        var enlacesAlterados = ko.utils.arrayFilter(mSelf.Lista(), function (enlace) {
            return enlace.EnlaceAlterado();
        });

        send = ko.utils.arrayMap(enlacesAlterados, function (enlace) {
            return enlace.salvar();
        });

        return send;
    };

    mSelf.finalizar = function () {
        if (mSelf.Novo != null) {
            if (mSelf.Novo.TerminalInicial() != null)
                mSelf.Novo.TerminalInicial().toggleInfoWindow();

            if (mSelf.Novo.TerminalFinal() != null)
                mSelf.Novo.TerminalFinal().toggleInfoWindow();

            //mSelf.Novo.ListaExclusao.finalizar();
            vm.permiteSelecionarTerminal(false);
        }
    };

    mSelf.validarDescricao = function (descricao, index, descricaoResources) {

        if (descricao)
            return descricao;

        return descricaoResources + " " + (index + 1);
    };

    mSelf.obterDistancia = (distancia) => {
        let medida = "m";
        let distanciaConvertida = distancia;

        if (distancia > 1000) {
            medida = "km";
            distanciaConvertida = (distancia / 1000).toFixed(2);
        }

        return `${distanciaConvertida}${medida}`;
    };
    
    mSelf.obterDistanciaTotal = () => {
        let medida = "m";
        let distancia = vm.Enlaces
            .Lista()
            .reduce((a, b) => {

                if (b.DistanciaTotal() > 1000) {
                    medida = "km";
                    a += parseFloat((b.DistanciaTotal() / 1000).toFixed(2));
                } else {
                    a += parseFloat(b.DistanciaTotal());
                }
                return a;
            }, 0);

        return `${distancia}${medida}`;
    };
    
    mSelf.mostrarLinhaEnlace = function (posicao) {
        if (posicao != null) {
            var enlace = vm.Enlaces.Lista()[posicao];
            if (enlace != null) {
                var polylinha = new google.maps.Polyline();

                var terminalInicial = enlace.TerminalInicial().pontoReferencia();
                var terminalFinal = enlace.TerminalFinal().pontoReferencia();

                var path = polylinha.getPath();
                path.push(terminalInicial);
                path.push(terminalFinal);

            }
        }
    };

    mSelf.EnlaceEdicao = ko.observable(null);

    mSelf.salvarEnlace = function () {
        if (vm.Enlaces.Novo.TerminalInicial() == null || vm.Enlaces.Novo.TerminalFinal() == null) {
            abrirModalMensagem("Salvar enlace", "Para salvar o enlace é necessário selecionar o terminal inicial e final.")
        } else {
            mSelf.preencheCadastroEnlace();
            clonarEntidadeVM(vm.CadastroEnlace, vm.Enlaces.Novo);
            mSelf.salvarItem(mSelf.EnlaceEdicao());
            mostrarGuia("guiamapa");
            mSelf.InformacoesNovoEnlaceVisivel(false);

            mSelf.desabilitarEnlaces(false);

            mSelf.permiteAcaoAdicionarEnlace(true);

            mSelf.plotarTodosDesvios();

            mSelf.plotarTodosRotogramas();

            mSelf.mostrarItinerarios();

            //vm.Terminais.mostrarTodosTerminais();
            vm.Enlaces.ExibirTodosTerminaisLinha()
        }
    }

    mSelf.preencheCadastroEnlace = function () {
        var enlace = vm.Enlaces.Novo;
        mSelf.gravaInformacoesEnlace();
        vm.CadastroEnlace.Identificador = $("#txtIdentificadorEnlace").val();
        vm.CadastroEnlace.Descricao = $("#txtDescricaoEnlace").val();
        vm.CadastroEnlace.Plataforma = $("#txtPlataforma").val();

        //informações tolerância
        vm.CadastroEnlace.DistanciaAfastamento = $("#txtDistanciaAfastamento").val();
        vm.CadastroEnlace.CompressaoEntradaAtiva = $("#txtCompressaoEntradaAtiva").val();
        vm.CadastroEnlace.CompressaoEntradaInativa = $("#txtCompressaoEntradaInativa").val();
        vm.CadastroEnlace.CompressaoSaida = $("#txtCompressaoSaida").val();
        vm.CadastroEnlace.ToleranciaChegadaAdiantada = $("#txtToleranciaChegadaAdiantada").val();
        vm.CadastroEnlace.ToleranciaChegadaAtrasada = $("#txtToleranciaChegadaAtrasada").val();
        vm.CadastroEnlace.ToleranciaSaidaAdiantada = $("#txtToleranciaSaidaAdiantada").val();
        vm.CadastroEnlace.ToleranciaSaidaAtrasada = $("#txtToleranciaSaidaAtrasada").val();
        vm.CadastroEnlace.TerminalSaida = $("#txtTerminalSaida").val();
    }

    mSelf.gravaInformacoesEnlace = function () {
        mSelf.Novo.CopiaInformacoesEnlace = {};
        mSelf.Novo.CopiaInformacoesEnlace.Identificador = vm.Enlaces.Novo.Identificador();
        mSelf.Novo.CopiaInformacoesEnlace.Descricao = vm.Enlaces.Novo.Descricao();
        mSelf.Novo.CopiaInformacoesEnlace.Plataforma = vm.Enlaces.Novo.Plataforma();
    };

    mSelf.retornaInformacoesEnlace = function () {
        if (mSelf.Novo.CopiaInformacoesEnlace != null) {
            vm.Enlaces.Novo.Identificador(mSelf.Novo.CopiaInformacoesEnlace.Identificador);
            vm.Enlaces.Novo.Descricao(mSelf.Novo.CopiaInformacoesEnlace.Descricao);
            vm.Enlaces.Novo.Plataforma(mSelf.Novo.CopiaInformacoesEnlace.Plataforma);
        }
    };

    mSelf.editar = function (index) {
        var viewModel = mSelf.Lista()[index];

        if (mSelf.permiteAcao() && !viewModel.desabilitado() && !viewModel.isEditando()) {
            mostrarGuia("guiamapa");
            var aux = vm.Enlaces.isEditandoEnlace();

            //plotar no mapa apenas os itens referentes ao enlace selecionado
            viewModel.plotarItensPorEnlace();

            vm.Enlaces.Novo = viewModel;

            mSelf.EnlaceEdicao(index);

            vm.Enlaces.isEditandoEnlace(true);

            mSelf.desabilitarEnlaces(true);
            mSelf.preencherCampos(viewModel);

            mSelf.ExibirApenasTerminaisEnlace();

            // mostrar no mapa apenas os terminais do enlace
            //vm.Terminais.mostrarTerminaisEnlace(viewModel);
            vm.visualizaBotoesEnlace(true);

            viewModel.isEditando(true);

            var clickTerminalIinicialHandler = new Handler({ eventName: "click" });
            var clickTerminalFinalHandler = new Handler({ eventName: "click" });
            if (mSelf.isEditandoEnlace()) {
                mSelf.escoderItinerarios();

                if (mSelf.Novo.TerminalInicial() != mSelf.Novo.TerminalFinal()) {
                    clickTerminalIinicialHandler.callback = function () {
                        mSelf.Novo.TerminalInicial().infoWindow.setMap(map);
                    };
                    clickTerminalFinalHandler.callback = function () {
                        mSelf.Novo.TerminalFinal().infoWindow.setMap(map);
                    };
                }

                // chama do enlace model a função de editar
                mSelf.Novo.editarItem();
            } else {
                mSelf.mostrarItinerarios();
            }

            if (mSelf.Novo.TerminalInicial())
                setEventHandler(mSelf.Novo.TerminalInicial().forma, [clickTerminalIinicialHandler], mSelf.Novo.TerminalInicial());

            if (mSelf.Novo.TerminalFinal())
                setEventHandler(mSelf.Novo.TerminalFinal().forma, [clickTerminalFinalHandler], mSelf.Novo.TerminalFinal());

            // fecha as guias
            vm.permiteSelecionarTerminal(!aux);
            vm.visualizaInformacoesEnlace(false);
            vm.visualizaInformacoesLinha(false);
            vm.visualizaInformacoesTolerancia(false);
            vm.visualizaHistoricoVeiculo(false);
            vm.isEditandoItinerario(false);
            vm.visualizarConfiguracaoRotograma(false);

            mSelf.fecharInfoWindows();
        }
    };

    mSelf.ExibirApenasTerminaisEnlace = function () {
        for (var i in vm.Terminais.Lista()) {
            if (vm.Terminais.Lista()[i].CodigoGrupoEntidade() != vm.Enlaces.Novo.CodigoGrupoEntidadeIni() && vm.Terminais.Lista()[i].CodigoGrupoEntidade() != vm.Enlaces.Novo.CodigoGrupoEntidadeFim()) {
                vm.Terminais.Lista()[i].setMap(null);
                vm.Terminais.Lista()[i].labelMap.setMap(null);
            }
        }

        //var keysTerminais = Object.keys(vm.TodosTerminaisSelecionados);
        //for (var i in keysTerminais) {

        //    if (keysTerminais[i] != vm.Enlaces.Novo.CodigoGrupoEntidadeIni() && keysTerminais[i] != vm.Enlaces.Novo.CodigoGrupoEntidadeFim())
        //    {
        //        var terminal = ko.utils.arrayFirst(vm.Terminais.Lista(), function (t) {
        //            return t.CodigoGrupoEntidade() == keysTerminais[i]
        //        });
        //        if (terminal) {
        //            terminal.setMap(null);
        //            terminal.labelMap.setMap(null);
        //        }
        //    }
        //}
    };

    mSelf.mostrarTerminaisEnlace = function (enlace) {
        var ocultaTerminal = false;
        if (enlace.TerminalInicial() != null && enlace.TerminalFinal()) {
            for (var term in mSelf.Lista()) {
                if (mSelf.Lista()[term].Codigo != enlace.TerminalFinal().Codigo &&
                    mSelf.Lista()[term].Codigo != enlace.TerminalInicial().Codigo) {

                    ocultaTerminal = true;
                }

                if (ocultaTerminal) {
                    mSelf.Lista()[term].forma.setMap(null);
                    mSelf.Lista()[term].labelMap.setMap(null);
                    if (mSelf.Lista()[term].PontoControle != null)
                        mSelf.Lista()[term].PontoControle.setMap(null);
                }
                ocultaTerminal = false;
            }
        }
    };

    mSelf.preencherCampos = function (enlace) {
        $("#txtIdentificadorEnlace").val(enlace.Identificador());
        $("#txtDescricaoEnlace").val(enlace.Descricao());
        $("#txtPlataforma").val(enlace.Plataforma());

        //informações tolerância
        $("#txtDistanciaAfastamento").val(enlace.DistanciaAfastamento());
        $("#txtCompressaoEntradaAtiva").val(enlace.CompressaoEntradaAtiva());
        $("#txtCompressaoEntradaInativa").val(enlace.CompressaoEntradaInativa());
        $("#txtCompressaoSaida").val(enlace.CompressaoSaida());
        $("#txtToleranciaChegadaAdiantada").val(enlace.ToleranciaChegadaAdiantada());
        $("#txtToleranciaChegadaAtrasada").val(enlace.ToleranciaChegadaAtrasada());
        $("#txtToleranciaSaidaAdiantada").val(enlace.ToleranciaSaidaAdiantada());
        $("#txtToleranciaSaidaAtrasada").val(enlace.ToleranciaSaidaAtrasada());
        $("#txtTerminalSaida").val(enlace.TerminalSaida());
    }

    mSelf.limparCampos = function () {
        $("#txtIdentificadorEnlace").val("");
        $("#txtDescricaoEnlace").val("");
        $("#txtPlataforma").val("");

        //informações tolerância
        $("#txtDistanciaAfastamento").val("");
        $("#txtCompressaoEntradaAtiva").val("");
        $("#txtCompressaoEntradaInativa").val("");
        $("#txtCompressaoSaida").val("");
        $("#txtToleranciaChegadaAdiantada").val("");
        $("#txtToleranciaChegadaAtrasada").val("");
        $("#txtToleranciaSaidaAdiantada").val("");
        $("#txtToleranciaSaidaAtrasada").val("");
        $("#txtTerminalSaida").val("");
    }

    mSelf.boundsEnlaceAtual = function (enlace) {
        if (enlace.TerminalInicial() != null && enlace.TerminalFinal() != null) {
            var bounds = new google.maps.LatLngBounds();
            bounds.union(enlace.TerminalInicial().bounds);
            bounds.union(enlace.TerminalFinal().bounds);
            map.fitBounds(bounds);
        }
    }

    // Itinerário 
    mSelf.salvarItinerario = function () {
        if (vm.Enlaces.Novo != null) {
            mSelf.Novo.Itinerario.Novo.salvar();

            if (vm.mensagemExclusaoRotograma != "")
                abrirModalMensagem("Mensagem", vm.mensagemExclusaoRotograma);

            vm.mensagemExclusaoRotograma = "";
        }
    }

    mSelf.cancelaEdicaoItinerario = function () {
        if (vm.Enlaces.Novo != null) {
            vm.Enlaces.Novo.Itinerario.Novo.cancelar();
            mSelf.Novo.fecharItensMenu("ItinerarioVisivel");
            vm.visualizaBotoesEnlace(true);
            vm.mensagemExclusaoRotograma = "";
        }
    }

    mSelf.limparTerminaisMapa = function () {
        if (vm.Enlaces.Novo.TerminalInicial() != null)
            vm.Enlaces.Novo.TerminalInicial().infoWindow.setMap(null);

        if (vm.Enlaces.Novo.TerminalFinal() != null)
            vm.Enlaces.Novo.TerminalFinal().infoWindow.setMap(null);

        if (vm.Enlaces.Novo.ListaExclusao.Lista != null) {
            for (var list in vm.Enlaces.Novo.ListaExclusao.Lista()) {
                if (vm.Enlaces.Novo.ListaExclusao.Lista()[list].Forma() != null)
                    vm.Enlaces.Novo.ListaExclusao.Lista()[list].Forma().infoWindow.setMap(null);
            }
        }
    }

    mSelf.salvarTolerancias = function () {
        mSelf.salvarCopiaTolerancias();
        mSelf.Novo.DistanciaAfastamento($("#txtDistanciaAfastamento").val());
        mSelf.Novo.CompressaoEntradaAtiva($("#txtCompressaoEntradaAtiva").val());
        mSelf.Novo.CompressaoEntradaInativa($("#txtCompressaoEntradaInativa").val());
        mSelf.Novo.CompressaoSaida($("#txtCompressaoSaida").val());
        mSelf.Novo.ToleranciaChegadaAdiantada($("#txtToleranciaChegadaAdiantada").val());
        mSelf.Novo.ToleranciaChegadaAtrasada($("#txtToleranciaChegadaAtrasada").val());
        mSelf.Novo.ToleranciaSaidaAdiantada($("#txtToleranciaSaidaAdiantada").val());
        mSelf.Novo.ToleranciaSaidaAtrasada($("#txtToleranciaSaidaAtrasada").val());
        mSelf.Novo.TerminalSaida($("#txtTerminalSaida").val());
        mostrarGuia("guiamapa");
        vm.visualizaInformacoesTolerancia(false);
        mSelf.Novo.ToleranciasVisivel(false);
        vm.visualizaBotoesEnlace(true);
        mSelf.Novo.ClonarEnlace(true);
        mSelf.Novo.fecharItensMenu("ToleranciasVisivel");

        vm.Enlaces.permiteAcaoTolerancias(true);
        mSelf.Novo.PossuiAlteracao(true);
    }

    mSelf.cancelarEdicaoTolerancias = function () {
        vm.visualizaInformacoesTolerancia(false);
        mostrarGuia("guiamapa");
        mSelf.Novo.ToleranciasVisivel(false);
        mSelf.preencherCampos(mSelf.Novo);
        vm.visualizaBotoesEnlace(true);
        mSelf.Novo.fecharItensMenu("ToleranciasVisivel");
        mSelf.permiteAcao(true);

        vm.Enlaces.permiteAcaoTolerancias(true);
    }

    mSelf.salvarCopiaTolerancias = function () {
        var tolerancias = {};
        tolerancias.DistanciaAfastamento = mSelf.Novo.DistanciaAfastamento();
        tolerancias.CompressaoEntradaAtiva = mSelf.Novo.CompressaoEntradaAtiva();
        tolerancias.CompressaoEntradaInativa = mSelf.Novo.CompressaoEntradaInativa();
        tolerancias.CompressaoSaida = mSelf.Novo.CompressaoSaida();
        tolerancias.ToleranciaChegadaAdiantada = mSelf.Novo.ToleranciaChegadaAdiantada();
        tolerancias.ToleranciaChegadaAtrasada = mSelf.Novo.ToleranciaChegadaAtrasada();
        tolerancias.ToleranciaSaidaAdiantada = mSelf.Novo.ToleranciaSaidaAdiantada();
        tolerancias.ToleranciaSaidaAtrasada = mSelf.Novo.ToleranciaSaidaAtrasada();
        mSelf.Novo.CopiaTolerancias = tolerancias;
    }

    mSelf.retornarTolerancias = function () {
        if (mSelf.Novo.CopiaTolerancias != null) {
            mSelf.Novo.DistanciaAfastamento(mSelf.Novo.CopiaTolerancias.DistanciaAfastamento);
            mSelf.Novo.CompressaoEntradaAtiva(mSelf.Novo.CopiaTolerancias.CompressaoEntradaAtiva);
            mSelf.Novo.CompressaoEntradaInativa(mSelf.Novo.CopiaTolerancias.CompressaoEntradaInativa);
            mSelf.Novo.CompressaoSaida(mSelf.Novo.CopiaTolerancias.CompressaoSaida);
            mSelf.Novo.ToleranciaChegadaAdiantada(mSelf.Novo.CopiaTolerancias.ToleranciaChegadaAdiantada);
            mSelf.Novo.ToleranciaChegadaAtrasada(mSelf.Novo.CopiaTolerancias.ToleranciaChegadaAtrasada);
            mSelf.Novo.ToleranciaSaidaAdiantada(mSelf.Novo.CopiaTolerancias.ToleranciaSaidaAdiantada);
            mSelf.Novo.ToleranciaSaidaAtrasada(mSelf.Novo.CopiaTolerancias.ToleranciaSaidaAtrasada);
        }
    }

    mSelf.limparRotograma = function () {

        if (mSelf.Novo.Rotogramas && mSelf.Novo.Rotogramas().length > 0) {

            ko.utils.arrayForEach(mSelf.Novo.Rotogramas(), function (rotograma) {

                rotograma.isRotogramaAtivo(false);
                rotograma.isRotogramasVisiveis(false);
                rotograma.isEditarPontosRotograma(false);
                rotograma.isConfigurarRotograma(false);
                rotograma.isExcluirRotograma(false);

                if (rotograma.polylineRotograma.infoWindow)
                    rotograma.polylineRotograma.infoWindow.setMap(null);

                rotograma.polylineRotograma.setMap(null);
            });
        }
    };

    mSelf.adicionarEventosPolilinhaDesvio = function (navegar) {

        ko.utils.arrayForEach(mSelf.Novo.Desvios.Lista(), function (desvio) {

            google.maps.event.clearListeners(desvio.Itinerario.Novo.polylinha, 'click');

            if (navegar)
                google.maps.event.addListener(desvio.Itinerario.Novo.polylinha, 'click', function (event) { desvio.Itinerario.Novo.clickRotograma(event); });

        });
    };

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

    mSelf.mostrarItinerarios = function () {
        var polyOptions = {
            strokeColor: "#4169E1",
            strokeOpacity: 0,
            icons: [{
                icon: {
                    path: 'M 0,-0.5 0,0.5',
                    strokeWeight: 5,
                    strokeOpacity: 1,
                    scale: 4
                },
                offset: '0',
                repeat: '20px'
            }],
            editable: false
        }

        for (var i in mSelf.Lista()) {
            var enlace = mSelf.Lista()[i];

            if (!enlace.Apagado()) {
                if (enlace.Itinerario.Lista().length > 0) {

                    if (enlace.Itinerario.Novo.polylinha == null) {
                        enlace.Itinerario.Novo.polylinha = new google.maps.Polyline(polyOptions);
                    } else {
                        enlace.Itinerario.Novo.polylinha.setOptions(polyOptions);
                    }

                    var path = enlace.Itinerario.Novo.polylinha.getPath();

                    if (path.length == 0) {
                        for (var item in enlace.Itinerario.Lista()) {
                            var coordenadas = new google.maps.LatLng(enlace.Itinerario.Lista()[item].Latitude() / 1000000, enlace.Itinerario.Lista()[item].Longitude() / 1000000);
                            coordenadas.CodigoRotograma = enlace.Itinerario.Lista()[item].CodigoRotograma();
                            path.push(coordenadas);
                        }
                    }
                    enlace.Itinerario.Novo.polylinha.setMap(map);
                }
            }
        }

        mSelf.setarEventosItinerarios();
    }

    mSelf.escoderItinerarios = function () {
        for (var item in mSelf.Lista()) {
            var enlace = mSelf.Lista()[item];
            var poly = enlace.Itinerario.Novo.polylinha;
            if (poly)
                poly.setMap(null);

            for (var index in enlace.Desvios.Lista()) {
                enlace.Desvios.Lista()[index].Itinerario.Novo.polylinha.setMap(null);
            }
        }
    }

    mSelf.salvarDesvio = function (index) {
        mSelf.Novo.Desvios.salvarDesvio(index);
        mSelf.Novo.fecharItensMenu("DesvioVisivel");

        var idx = vm.Enlaces.EnlaceEdicao();
        if (vm.Enlaces.Lista()[idx].Itinerario.Novo.polylinhaRange != null) {
            vm.Enlaces.Lista()[idx].Itinerario.Novo.polylinhaRange.setMap(null);
        }
        vm.Enlaces.Lista()[idx].Itinerario.Novo.polylinha.setMap(map);
    };

    mSelf.cancelarDesvio = function () {
        if (mSelf.Novo.isAdicionandoDesvio())
            mSelf.Novo.Desvios.cancelarAdicionar();
        else
            mSelf.Novo.Desvios.Novo.cancelarEdicao();

        vm.visualizaInformacoesDesvio(false);
        vm.visualizaInformacoesEnlaceParcial(false);
        mostrarGuia("guiamapa");
        var desvio = new DesvioModel();
        desvio.desabilitarDesvios(false);
        mSelf.Novo.Desvios.adicionarDesabilitado(false);

        var idx = vm.Enlaces.EnlaceEdicao();
        if (vm.Enlaces.Lista()[idx].Itinerario.Novo.polylinhaRange != null) {
            vm.Enlaces.Lista()[idx].Itinerario.Novo.polylinhaRange.setMap(null);
        }
        vm.Enlaces.Lista()[idx].Itinerario.Novo.polylinha.setMap(map);

    };

    mSelf.salvarInformacoesEnlace = function () {
        mSelf.preencheCadastroEnlace();
        clonarEntidadeVM(vm.CadastroEnlace, vm.Enlaces.Novo);
        mostrarGuia("guiamapa");
        vm.Enlaces.Novo.InformacoesEnlaceVisivel(false);
        mSelf.Novo.fecharItensMenu("InformacoesEnlaceVisivel");
        vm.visualizaBotoesEnlace(true);
        vm.visualizaInformacoesEnlace(false);

        mSelf.permiteAcaoInformacoesEnlace(true);

        vm.Enlaces.Novo.PossuiAlteracao(true);
    }

    mSelf.salvarInformacoesNovoEnlace = function () {
        mSelf.preencheCadastroEnlace();
        clonarEntidadeVM(vm.CadastroEnlace, vm.Enlaces.Novo);
        mostrarGuia("guiamapa");
        mSelf.InformacoesNovoEnlaceVisivel(false);
        vm.visualizaBotoesEnlace(true);
    }

    mSelf.cancelarInformacoesEnlace = function () {
        mostrarGuia("guiamapa");
        vm.Enlaces.Novo.InformacoesEnlaceVisivel(false);
        $("#txtIdentificadorEnlace").val(mSelf.Novo.Identificador());
        $("#txtDescricaoEnlace").val(mSelf.Novo.Descricao());
        $("#txtPlataforma").val(mSelf.Novo.Plataforma());
        vm.visualizaInformacoesEnlace(false);
        mSelf.Novo.fecharItensMenu("InformacoesEnlaceVisivel");
        vm.visualizaBotoesEnlace(true);

        mSelf.permiteAcaoInformacoesEnlace(true);

        mSelf.permiteAcao(true);
    }

    mSelf.desabilitarEnlaces = function (aux) {
        ko.utils.arrayForEach(vm.Enlaces.Lista(), function (enlace) {
            if (enlace != mSelf.Novo) {
                enlace.desabilitado(aux);
            }
        });
        if (!aux)
            mSelf.Novo.desabilitado(aux);
    }

    mSelf.listaCodigos = [];

    mSelf.restaurarEnlaceOriginal = function () {

        var clone = mSelf.Novo.clonarEnlace();

        var novoEnlace = new EnlaceModel(clone);

        mSelf.preencheEnlace(clone, novoEnlace);

        if (novoEnlace.Codigo() == 0) {
            var count = mSelf.listaCodigos.length;
            if (count == 0) {
                novoEnlace.Codigo(-1);
            }
            else {
                var ultimoCodigo = mSelf.listaCodigos[count - 1];
                novoEnlace.Codigo(ultimoCodigo + (-1));
            }

            mSelf.Novo.Codigo(novoEnlace.Codigo());
            mSelf.listaCodigos.push(novoEnlace.Codigo());

            novoEnlace.EnlaceAlterado(true);

            vm.CopiaLista.push(novoEnlace);
        } else {
            novoEnlace.EnlaceAlterado(mSelf.Novo.EnlaceAlterado());
            novoEnlace.ClonarEnlace(mSelf.Novo.ClonarEnlace());

            //replace na respectiva lista.
            for (var index in mSelf.Lista()) {
                if (mSelf.Lista()[index].Codigo() == novoEnlace.Codigo()) {
                    vm.CopiaLista.replace(vm.CopiaLista()[index], novoEnlace);
                    break;
                }
            }
        }

        vm.Enlaces.isEditandoEnlace(false);
        vm.Enlaces.Visible(false);
        vm.toggleEnlaces();
    };

    mSelf.restaurarEnlaceCopia = function () {

        var enlaceCopia = ko.utils.arrayFirst(vm.CopiaLista(), function (enlace) {
            return enlace.Codigo() == mSelf.Novo.Codigo();
        });

        if (enlaceCopia != null) {

            enlaceCopia.ListaRotogramasCopia(true);

            var clone = enlaceCopia.clonarEnlace();

            for (var p in clone.PontosOnibus) {
                var ponto = ko.utils.arrayFirst(mSelf.Novo.PontosOnibus.Lista(), function (item) {
                    return item.CodigoGrupoEntidade() == clone.PontosOnibus[p].CodigoGrupoEntidade
                });
                if (ponto) {
                    clone.PontosOnibus[p].Forma = ponto.Forma().salvarTerminal();
                }
            }

            var novoEnlace = new EnlaceModel(clone);

            //setar valores
            mSelf.preencheEnlace(clone, novoEnlace);

            enlaceCopia.ListaRotogramasCopia(false);

            novoEnlace.EnlaceAlterado(enlaceCopia.EnlaceAlterado());
            novoEnlace.ClonarEnlace(enlaceCopia.ClonarEnlace());

            //replace na respectiva lista.
            for (var index in vm.CopiaLista()) {

                if (vm.CopiaLista()[index].Codigo() == novoEnlace.Codigo()) {

                    mSelf.Lista.replace(mSelf.Lista()[index], novoEnlace);

                    break;
                }
            }

            vm.Enlaces.isEditandoEnlace(false);
            vm.Enlaces.Visible(false);
            vm.toggleEnlaces();
        }
    };

    mSelf.preencheEnlace = function (clone, novoEnlace) {

        mSelf.preencheTerminais(novoEnlace);

        novoEnlace.Desvios.Lista(mSelf.preencheDesvios(clone, novoEnlace));

        novoEnlace.Itinerario = mSelf.preencheItinerario(clone, novoEnlace);

        mSelf.preencheListaExclusao(clone, novoEnlace);

        mSelf.preencherListaRotogramas(clone, novoEnlace);

        novoEnlace.PontosOnibus.Lista(mSelf.preenchePontosOnibus(clone, novoEnlace));
    };

    mSelf.preencheTerminais = function (enlace) {
        var terminal = vm.TodosTerminaisSelecionados[enlace.CodigoGrupoEntidadeIni()];
        enlace.TerminalInicial(terminal);
        terminal = vm.TodosTerminaisSelecionados[enlace.CodigoGrupoEntidadeFim()];
        enlace.TerminalFinal(terminal);
        //ko.utils.arrayForEach(vm.Terminais.Lista(), function (terminal) {
        //    if (enlace.CodigoGrupoEntidadeIni() === terminal.CodigoGrupoEntidade()) {
        //        enlace.TerminalInicial(terminal);
        //    }

        //    if (enlace.CodigoGrupoEntidadeFim() === terminal.CodigoGrupoEntidade()) {
        //        enlace.TerminalFinal(terminal);
        //    }
        //    if (enlace.TerminalInicial() != null &&
        //        enlace.TerminalFinal() != null) {
        //        return;
        //    }
        //});
    }

    mSelf.preencheItinerario = function (clone, novoEnlace) {
        var itinerarioModel = new ItinerariosModel();
        itinerarioModel.Novo = new ItinerarioModel();
        itinerarioModel.Novo.polylinha = itinerarioModel.Novo.optionsPolylinha();

        var path = itinerarioModel.Novo.polylinha.getPath();

        for (var p in clone.EnlacesItinerarios) {
            var ponto = clone.EnlacesItinerarios[p];

            var pontoModel = new PontoItinerarioModel();
            pontoModel.Latitude(ponto.Latitude);
            pontoModel.Longitude(ponto.Longitude);
            pontoModel.Sequencia(ponto.Sequencia);
            pontoModel.CodigoRotograma(ponto.CodigoRotograma);
            itinerarioModel.Lista.push(pontoModel);

            var coordenadas = new google.maps.LatLng(ponto.Latitude / 1000000, ponto.Longitude / 1000000);

            if (ponto.CodigoRotograma)
                coordenadas.CodigoRotograma = ponto.CodigoRotograma;
            else
                coordenadas.CodigoRotograma = null;

            path.push(coordenadas);
        }

        return itinerarioModel;
    }

    mSelf.preencheDesvios = function (clone, novoEnlace) {
        var listDesvios = [];

        if (clone.Desvios != null) {
            for (var d in clone.Desvios) {
                var desvio = clone.Desvios[d];

                var desvioModel = new DesvioModel();
                var itinerario = new ItinerariosModel();
                itinerario.Novo = new ItinerarioModel();
                desvioModel.Itinerario = itinerario;
                desvioModel.Descricao(desvio.Descricao);
                desvioModel.Codigo(desvio.Codigo);

                if (desvio.Pontos != null) {
                    desvioModel.criarPolylinhaDesvio(desvio.Pontos);

                    for (var index in desvio.Pontos) {
                        var pontoModel = new PontoItinerarioModel();
                        pontoModel.Latitude(desvio.Pontos[index].Latitude);
                        pontoModel.Longitude(desvio.Pontos[index].Longitude);
                        pontoModel.Sequencia(desvio.Pontos[index].Sequencia);
                        pontoModel.CodigoRotograma(desvio.Pontos[index].CodigoRotograma);
                        desvioModel.Itinerario.Lista.push(pontoModel);
                    }
                }
                listDesvios.push(desvioModel);
            }
        }
        return listDesvios;
    };

    mSelf.preencheListaExclusao = function (clone, novoEnlace) {
        novoEnlace.ListaExclusao = new EntidadesExclusaoModel();
        for (var index in clone.LinhasEnlacesExclusao) {
            var exclusaoModel = new EntidadeExclusaoModel(clone.LinhasEnlacesExclusao[index]);
            novoEnlace.ListaExclusao.Lista.push(exclusaoModel);
        }
    };

    mSelf.preenchePontosOnibus = function (clone, novoEnlace) {
        var listPontos = [];

        if (clone.PontosOnibus != null) {
            for (var d in clone.PontosOnibus) {
                var ponto = clone.PontosOnibus[d];

                var pontoModel = new PontoOnibusModel(ponto);

                listPontos.push(pontoModel);
            }
        }
        return listPontos;
    };

    mSelf.preencherListaRotogramas = function (clone, novoEnlace) {

        if (clone.Rotogramas && clone.Rotogramas.length > 0) {
            for (var indexR in clone.Rotogramas) {
                var rotogramaEnlace = new RotogramaModel();

                rotogramaEnlace.Codigo(clone.Rotogramas[indexR].Codigo);
                rotogramaEnlace.Descricao(clone.Rotogramas[indexR].Descricao);
                rotogramaEnlace.VelocidadeSemChuva(clone.Rotogramas[indexR].VelocidadeSemChuva);
                rotogramaEnlace.VelocidadeComChuva(clone.Rotogramas[indexR].VelocidadeComChuva);
                rotogramaEnlace.ParadaPermitida(clone.Rotogramas[indexR].ParadaPermitida);
                rotogramaEnlace.PossuiRestricaoHorario(clone.Rotogramas[indexR].PossuiRestricaoHorario);
                rotogramaEnlace.RestricaoDe(clone.Rotogramas[indexR].RestricaoDe);
                rotogramaEnlace.RestricaoAte(clone.Rotogramas[indexR].RestricaoAte);
                rotogramaEnlace.SequenciaInicial(clone.Rotogramas[indexR].SequenciaInicial);
                rotogramaEnlace.SequenciaFinal(clone.Rotogramas[indexR].SequenciaFinal);

                novoEnlace.Rotogramas.push(rotogramaEnlace);
            }
        }

        if (clone.Desvios && clone.Desvios.length > 0) {
            for (var indexD in clone.Desvios) {
                if (clone.Desvios[indexD].Rotogramas && clone.Desvios[indexD].Rotogramas.length > 0) {
                    for (var indexDR in clone.Desvios[indexD].Rotogramas) {
                        var rotogramaDesvio = new RotogramaModel();

                        rotogramaDesvio.Codigo(clone.Desvios[indexD].Rotogramas[indexDR].Codigo);
                        rotogramaDesvio.Descricao(clone.Desvios[indexD].Rotogramas[indexDR].Descricao);
                        rotogramaDesvio.VelocidadeSemChuva(clone.Desvios[indexD].Rotogramas[indexDR].VelocidadeSemChuva);
                        rotogramaDesvio.VelocidadeComChuva(clone.Desvios[indexD].Rotogramas[indexDR].VelocidadeComChuva);
                        rotogramaDesvio.ParadaPermitida(clone.Desvios[indexD].Rotogramas[indexDR].ParadaPermitida);
                        rotogramaDesvio.PossuiRestricaoHorario(clone.Desvios[indexD].Rotogramas[indexDR].PossuiRestricaoHorario);
                        rotogramaDesvio.RestricaoDe(clone.Desvios[indexD].Rotogramas[indexDR].RestricaoDe);
                        rotogramaDesvio.RestricaoAte(clone.Desvios[indexD].Rotogramas[indexDR].RestricaoAte);
                        rotogramaDesvio.SequenciaInicial(clone.Desvios[indexD].Rotogramas[indexDR].SequenciaInicial);
                        rotogramaDesvio.SequenciaFinal(clone.Desvios[indexD].Rotogramas[indexDR].SequenciaFinal);

                        novoEnlace.Rotogramas.push(rotogramaDesvio);
                    }
                }
            }
        }
    };

    mSelf.plotarTodosDesvios = function () {
        for (var index in mSelf.Lista()) {
            for (var item in mSelf.Lista()[index].Desvios.Lista()) {
                var desvio = mSelf.Lista()[index].Desvios.Lista()[item];
                var polylinha = desvio.Itinerario.Novo.polylinha;
                polylinha.setEditable(false);
                polylinha.setMap(map);
                desvio.desvioVisivel(true);
            }
        }
    }

    mSelf.plotarTodosRotogramas = function () {

        for (var index in mSelf.Lista()) {

            ko.utils.arrayForEach(mSelf.Lista()[index].Rotogramas(), function (rotograma) {

                if (rotograma.polylineRotograma.getPath().length == 0)
                    rotograma.setarPontosPorRotograma(mSelf.Lista()[index]);

                rotograma.polylineRotograma.setMap(map);

                rotograma.isRotogramasVisiveis(true);


                google.maps.event.clearListeners(rotograma.polylineRotograma, 'click');

                google.maps.event.addListener(rotograma.polylineRotograma, 'click', function (event) { rotograma.setarClickRotograma(event); });
            });
        }
    }

    mSelf.esconderTodosRotogramas = function () {

        for (var index in mSelf.Lista()) {

            ko.utils.arrayForEach(mSelf.Lista()[index].Rotogramas(), function (rotograma) {

                rotograma.polylineRotograma.setMap(null);
                rotograma.polylineRotograma.infoWindow.setMap(null);

            });
        }
    }

    mSelf.setarEventosItinerarios = function () {
        ko.utils.arrayForEach(mSelf.Lista(), function (enlace) {
            if (enlace.Itinerario.Novo.polylinha) {
                google.maps.event.clearListeners(enlace.Itinerario.Novo.polylinha, 'click');

                google.maps.event.addListener(enlace.Itinerario.Novo.polylinha, 'click',
                    function (event) {
                        enlace.clickItinerario(event);
                    });
            }
        });
    };

    mSelf.setarEventosDesvios = function () {
        ko.utils.arrayForEach(mSelf.Lista(), function (enlace) {
            ko.utils.arrayForEach(enlace.Desvios.Lista(), function (desvio) {
                if (desvio.Itinerario.Novo.polylinha) {
                    google.maps.event.clearListeners(desvio.Itinerario.Novo.polylinha, 'click');

                    google.maps.event.addListener(desvio.Itinerario.Novo.polylinha, 'click',
                        function (event) {
                            enlace.clickDesvio(event, desvio);
                        });
                }
            });
        });
    };

    mSelf.fecharInfoWindows = function () {
        //oculta as infoWindows - itinerários e desvios

        ko.utils.arrayForEach(mSelf.Lista(), function (enlace) {
            if (enlace.Itinerario.Novo && enlace.Itinerario.Novo.infoWindow)
                enlace.Itinerario.Novo.infoWindow.setMap(null);

            ko.utils.arrayForEach(enlace.Desvios.Lista(), function (desvio) {
                if (desvio.infoWindow)
                    desvio.infoWindow.setMap(null);
            });
        });
    }
}
