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

    ViewModelBase.apply(mSelf, arguments);

    mSelf.permiteSalvarItinerario = ko.observable(false);
    mSelf.hasItinerario = ko.observable(false);
    mSelf.isItinerarioManual = ko.observable(false);
    mSelf.importandoHistorico = ko.observable(false);
    mSelf.visualizarRotograma = ko.observable(false);
    mSelf.permiteAdicionarRotograma = ko.observable(false);
    mSelf.permiteAdicionarRotogramaAcao = ko.observable(false);
    mSelf.isEditando = ko.observable(false);
    mSelf.isAdicionando = ko.observable(false);

    mSelf.editarSelecionado = ko.observable(false);

    mSelf.isAdicionandoPontos = ko.observable(false);

    mSelf.infoWindow = null;

    //flags para controle do menu - Itinerario
    mSelf.editarDesabilitado = ko.observable(false);
    mSelf.excluirDesabilitado = ko.observable(false);
    mSelf.adicionarPontosDesabilitado = ko.observable(false);
    mSelf.importarPontosDesabilitado = ko.observable(false);

    mSelf.manualmenteDesabilitado = ko.observable(false);
    mSelf.importarDesabilitado = ko.observable(false);

    mSelf.CopiaPolylinha = [];

    mSelf.PermiteConfigurarRotograma = ko.observable(false);

    //flags para controlar o menu - Rotograma
    mSelf.adicionarDesabilitado = ko.observable(false);
    mSelf.configurarDesabilitado = ko.observable(false);

    mSelf.permiteAcaoAdicionarRotograma = ko.observable(true);

    mSelf.desabilitado = ko.observable(false);

    mSelf.polylinha = null;

    mSelf.sentido = false;

    mSelf.polylinhaSelecionada = new google.maps.Polyline({
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 10,
        map: map,
        zIndex: 4
    });

    google.maps.event.addListener(mSelf.polylinhaSelecionada, 'rightclick', function (event) { mSelf.rightClickSelecionada(event); });

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

    mSelf.sequencia = ko.observable(0);

    mSelf.substituirItinerario = ko.observable(false);

    mSelf.polylinhaPadrao = function () {
        return {
            strokeColor: '#000000',
            strokeOpacity: 1.0,
            editable: false,
            zIndex: 2,
            icon: null,
            icons: [],
            offset: '0',
            repeat: '0px'
        }
    }

    mSelf.optionsPolylinha = function (isEditable, color, weight) {
        var polyOptions = {
            strokeColor: checkValue(color, '#000000'),
            strokeOpacity: 1.0,
            strokeWeight: checkValue(weight, 3),
            editable: isEditable != null ? isEditable : true,
            zIndex: 2,
            icon: null,
            icons: [],
            offset: '0',
            repeat: '0px'
        }

        var poly = new google.maps.Polyline(polyOptions);


        google.maps.event.addListener(poly.getPath(), 'set_at', function (index, pontoAntigo) {
            mSelf.moverPonto(index, pontoAntigo);
            mSelf.setPathSelecionado();
        });

        google.maps.event.addListener(poly.getPath(), 'insert_at', function (index) {
            if (!vm.verificarCriacaoItinerario() && mSelf.isAdicionandoPontos()) {
                mSelf.inserirPonto(index);
                mSelf.setPathSelecionado();
            }
        });

        google.maps.event.addListener(poly.getPath(), 'remove_at', function (index, pontoRemovido) {
            mSelf.removerPontoRotograma(index, pontoRemovido);
        });

        return poly;
    };

    mSelf.moverPonto = function (index, pontoAntigo) {
        mSelf.polylinha.getPath().getArray()[index].CodigoRotograma = pontoAntigo.CodigoRotograma;
    };

    mSelf.inserirPonto = function (index) {

        if (index > 0 && index < (mSelf.polylinha.getPath().getArray().length - 1)) {

            if (mSelf.polylinha.getPath().getArray()[index - 1].CodigoRotograma && mSelf.polylinha.getPath().getArray()[index + 1].CodigoRotograma)
                mSelf.polylinha.getPath().getArray()[index].CodigoRotograma = mSelf.polylinha.getPath().getArray()[index - 1].CodigoRotograma;
            else
                mSelf.polylinha.getPath().getArray()[index].CodigoRotograma = null;
        }
        else
            mSelf.polylinha.getPath().getArray()[index].CodigoRotograma = null;
    };

    mSelf.removerPontoRotograma = function (index, pontoRemovido) {

        if (pontoRemovido.CodigoRotograma) {

            var rotograma = new RotogramaModel();

            rotograma.Codigo(pontoRemovido.CodigoRotograma);

            rotograma.ItinerarioRotograma = mSelf;

            if (rotograma.validarExclusaoPontosItinerario()) {

                var rotogramaExclusao = rotograma.getRotogramaExlusaoItinerario();

                if (rotogramaExclusao !== null) {

                    if (vm.mensagemExclusaoRotograma == "")
                        vm.mensagemExclusaoRotograma = "Devido a exclusão de ponto(s), o(s) seguinte(s) rotograma(s) foi(ram) excluído(s):<br /> - <strong>" + rotogramaExclusao.Descricao() + "</strong>";
                    else
                        vm.mensagemExclusaoRotograma += "<br /> - <strong>" + rotogramaExclusao.Descricao() + "</strong>";

                    vm.Enlaces.Novo.Rotogramas.remove(rotogramaExclusao);
                }
            }
        }
    };

    mSelf.verificarDesviosAlteracaoItinerario = function () {

        if (vm.Enlaces.Novo.Desvios.Lista && vm.Enlaces.Novo.Desvios.Lista().length > 0) {

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

                desvio.validarCriacaoDesvio(false);
            });
        }
    };

    mSelf.definirItinerarioManual = function () {
        if (!mSelf.manualmenteDesabilitado()) {

            var aux = vm.Enlaces.Novo.Itinerario.Novo.isItinerarioManual();

            if (aux || mSelf.hasItinerario()) {
                return;
            } else {
                vm.Enlaces.Novo.Itinerario.Novo.isItinerarioManual(!aux);
                if (aux) {
                    vm.isEditandoItinerario(false);
                    vm.Enlaces.Novo.Itinerario.Novo.isItinerarioManual(false);
                    if (vm.Enlaces.Novo.Itinerario.Novo.hasItinerario() || mSelf.polylinha != null) {
                        mSelf.vertexSelected(-1);
                        mSelf.polylinha.setEditable(false);
                    }
                } else {
                    if (vm.Enlaces.Novo.Itinerario.Novo.hasItinerario()) {
                        vm.Enlaces.Novo.Itinerario.Novo.editar();
                    } else {
                        if (!mSelf.importandoHistorico() && mSelf.polylinha == null) {
                            vm.Enlaces.Novo.Itinerario.Novo.listPaths = [];
                            vm.Enlaces.Novo.Itinerario.Novo.polylinha = vm.Enlaces.Novo.Itinerario.Novo.optionsPolylinha();
                            vm.Enlaces.Novo.Itinerario.Novo.polylinha.Pontos = null;
                            vm.Enlaces.Novo.Itinerario.Novo.polylinha.setMap(map);
                        } else {
                            mSelf.polylinha.setEditable(true);
                            mSelf.polylinha = mSelf.optionsPolylinha();
                        }

                        var fn = vm.Enlaces.Novo.Itinerario.Novo.addLatitudeLongitude
                        google.maps.event.clearListeners(map, 'click');
                        google.maps.event.addListener(map, 'click', fn);
                        vm.Terminais.setFormaEvents([
                            new Handler({
                                eventName: "click",
                                callback: fn
                            })
                        ]);

                        vm.Enlaces.Novo.Itinerario.Novo.permiteSalvarItinerario(true);
                        vm.Enlaces.Novo.Itinerario.Novo.hasItinerario(false);
                        vm.isEditandoItinerario(true);
                        vm.Enlaces.Novo.Itinerario.Novo.isItinerarioManual(true);
                        vm.Enlaces.Novo.Itinerario.Novo.importandoHistorico(false);

                        google.maps.event.clearListeners(mSelf.polylinha, 'click');

                        google.maps.event.addListener(mSelf.polylinha, 'click', function (event) { mSelf.click(event); });

                        mSelf.navegarTeclado(true);

                        mSelf.isAdicionandoPontos(true);

                        mSelf.polylinha.setMap(map);
                    }
                }
                mSelf.importarDesabilitado(!aux);
                mSelf.adicionarPontosDesabilitado(!aux);
                vm.Enlaces.permiteAcaoItinerario(aux);
            }
        }
    };

    mSelf.salvar = function () {
        if (vm.Enlaces.Novo.Itinerario.Novo.polylinha) {
            var itensPolilinha = vm.Enlaces.Novo.Itinerario.Novo.polylinha.getPath();
            if (vm.Enlaces.Novo.Itinerario.Lista().length < 2 && itensPolilinha.length < 2) {
                abrirModalMensagem("Alerta", "É necessário ter dois ou mais pontos para salvar um itinerário.");
            } else {
                if (vm.Enlaces.Novo.Itinerario.Novo.polylinha != null && vm.Enlaces.Novo.Itinerario.Novo.polylinha.Pontos == null) {
                    if (vm.Enlaces.Novo.TerminalInicial()) {
                        var latLngprincipal = vm.Enlaces.Novo.TerminalInicial().pontoReferencia();
                        var calculo = new DistanciaGPS();
                        var path = vm.Enlaces.Novo.Itinerario.Novo.polylinha.getPath().getArray();

                        //Verifica se o Terminal inicial é diferente do terminal final, isso evita que seja invertido o Itinerário para rotas circulares.
                        if (vm.Enlaces.Novo.TerminalInicial().pontoReferencia().lat() !== vm.Enlaces.Novo.TerminalFinal().pontoReferencia().lat() &&
                            vm.Enlaces.Novo.TerminalInicial().pontoReferencia().lng() !== vm.Enlaces.Novo.TerminalFinal().pontoReferencia().lng()) {
                            // Verificar se o Ponto inicial do enlace está perto do ponto inicial ou do ponto final (Terminais);
                            // Se o ponto inicial do itinerario estiver perto do ponto final, a lista deve ser reordenada;                     
                            if (calculo.LeiCosenosGMaps(latLngprincipal, path[path.length - 1]) < calculo.LeiCosenosGMaps(latLngprincipal, path[0])) {
                                var MVCArrayNovo = new google.maps.MVCArray();
                                var pontoPath = path.pop();
                                while (pontoPath != null) {
                                    MVCArrayNovo.push(pontoPath);
                                    pontoPath = path.pop();
                                }
                                vm.Enlaces.Novo.Itinerario.Novo.polylinha.setPath(MVCArrayNovo);
                            }
                        }
                    }
                    vm.Enlaces.Novo.Itinerario.Novo.polylinha.Pontos = vm.Enlaces.Novo.Itinerario.Novo.polylinha.getPath();
                }
                vm.Enlaces.Novo.Itinerario.Lista.removeAll();

                mSelf.atualizaListaPontosItinerario(vm.Enlaces.Novo.Itinerario.Novo.polylinha.getPath().getArray(), vm.Enlaces.Novo.Itinerario.Lista);

                vm.Enlaces.Novo.Itinerario.Novo.listPaths = [];
                vm.Enlaces.Novo.Itinerario.Novo.vertexSelected(-1);
                vm.Enlaces.Novo.Itinerario.Novo.polylinha.setEditable(false);

                vm.Enlaces.Novo.Itinerario.Novo.hasItinerario(true);
                vm.Enlaces.Novo.Itinerario.Novo.permiteSalvarItinerario(false);
                vm.isEditandoItinerario(false);
                vm.Enlaces.Novo.Itinerario.Novo.isItinerarioManual(false);
                vm.Enlaces.Novo.fecharItensMenu("");
                vm.visualizaBotoesEnlace(true);
                vm.visualizaHistoricoVeiculo(false);
                vm.Enlaces.Novo.ClonarEnlace(true);
                mSelf.editarSelecionado(false);
                mSelf.isAdicionandoPontos(false);

                google.maps.event.clearListeners(mSelf.polylinha, 'click');

                vm.Enlaces.permiteAcaoItinerario(true);
                vm.Enlaces.permiteAcao(true);

                mSelf.CopiaPolylinha = [];

                mSelf.polylinhaSelecionada.setPath([]);

                mSelf.adicionarPontosDesabilitado(false);
                mSelf.importarPontosDesabilitado(false);
                mSelf.importarDesabilitado(false);

                mSelf.excluirDesabilitado(false);

                vm.Enlaces.Novo.fecharItensMenu("ItinerarioVisivel");
                vm.visualizaBotoesEnlace(true);

                mSelf.manualmenteDesabilitado(false);
                mSelf.importarDesabilitado(false);

                var rotograma = new RotogramaModel();
                rotograma.verificarPosicaoRotogramaItinerario();

                vm.Enlaces.Novo.PossuiAlteracao(true);

                rotograma.mostrarTodosRotogramas();

            }
        } else {
            abrirModalMensagem("Alerta", "É necessário ter dois ou mais pontos para salvar um itinerário.");
        }
    };

    mSelf.atualizaListaPontosItinerario = function (pontos, lista) {
        lista.removeAll();
        for (var index in pontos) {
            var pontoModel = new PontoItinerarioModel();
            pontoModel.Latitude(parseInt(pontos[index].lat() * 1000000));
            pontoModel.Longitude(parseInt(pontos[index].lng() * 1000000));
            pontoModel.Sequencia(index);
            pontoModel.CodigoRotograma(pontos[index].CodigoRotograma);
            lista.push(pontoModel);
        }
    }

    mSelf.cancelar = function () {
        vm.Enlaces.Novo.Itinerario.Novo.listPaths = [];
        if (vm.Enlaces.Novo.Itinerario.Novo.hasItinerario()) {
            //vm.Enlaces.Novo.Itinerario.Novo.polylinha.setMap(map);
            vm.Enlaces.Novo.Itinerario.Novo.polylinha.setEditable(false);
        } else {
            if (vm.isEditandoItinerario()) {
                vm.Enlaces.Novo.Itinerario.Lista([]);
            }
            //  vm.Enlaces.Novo.Itinerario.Novo.polylinha.setMap(null);
            mSelf.idxIni = -1;
            mSelf.idxFim = -1;
            mSelf.setPathSelecionado();
            if (vm.Enlaces.Novo.Itinerario.Novo.polylinha != null) {
                vm.Enlaces.Novo.Itinerario.Novo.polylinha.setMap(null);
                vm.Enlaces.Novo.Itinerario.Novo.polylinha = null;
            }
        }

        mSelf.voltarPolylinha();

        vm.Enlaces.Novo.Itinerario.Novo.permiteSalvarItinerario(false);
        //vm.Enlaces.Novo.ItinerarioVisivel(false);
        vm.isEditandoItinerario(false);
        vm.Enlaces.Novo.DistanciaTotal(0);
        vm.Enlaces.Novo.Itinerario.Novo.sequencia(0);
        google.maps.event.clearListeners(map, 'click');

        mSelf.visualizarRotograma(false);

        mSelf.permiteAdicionarRotograma(false);

        mSelf.permiteAdicionarRotogramaAcao(false);

        vm.visualizarConfiguracaoRotograma(false);

        vm.visualizaHistoricoVeiculo(false);

        $('body').data("atualizarRotograma", null);

        mSelf.limparPolylinhaRotograma();

        mostrarGuia("guiamapa");

        vm.visualizaHistoricoVeiculo(false);
        mostrarGuia("guiamapa");
        mSelf.isItinerarioManual(false);
        mSelf.importandoHistorico(false);

        vm.visualizaBotoesEnlace(true);
        vm.Enlaces.Novo.ClonarEnlace(false);

        mSelf.editarSelecionado(false);
        mSelf.isAdicionandoPontos(false);

        if (mSelf.polylinha != null)
            google.maps.event.clearListeners(mSelf.polylinha, 'click');

        vm.Enlaces.permiteAcaoItinerario(true);
        vm.Enlaces.permiteAcao(true);

        mSelf.isAdicionando(false);
        mSelf.adicionarDesabilitado(false);
        mSelf.importarDesabilitado(false);
        mSelf.manualmenteDesabilitado(false);
        mSelf.excluirDesabilitado(false);

        var rotograma = new RotogramaModel();
        rotograma.mostrarTodosRotogramas();
    };

    mSelf.toogleSentido = function () {
        mSelf.sentido = !mSelf.sentido

        var lineSymbol = {
            path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
        };

        var icons = [{
            icon: lineSymbol,
            repeat: '100px',
            offset: '100%'
        }];

        if (mSelf.sentido) {
            mSelf.polylinha.setOptions({ icons: icons });
        } else {
            mSelf.polylinha.setOptions({ icons: null });
        }
    }

    mSelf.excluir = function () {

        if (!mSelf.excluirDesabilitado()) {

            var mensagem = "";

            if (mSelf.verificarExclusaoItinerario())
                mensagem = "Existe(m) rotograma(s) e/ou desvio(s) vinculados a este itinerário, confirma sua exclusão do enlace?"
            else
                mensagem = "Confirma remover o itinerário do enlace?";

            abrirModalMensagem("Confirmação", mensagem,
                {
                    resizable: false,
                    height: 190,
                    modal: true,
                    buttons: {
                        "Sim": function () {
                            vm.Enlaces.Novo.Itinerario.Novo.polylinha.setMap(null);
                            vm.Enlaces.Novo.Itinerario.Novo.polylinha = null;
                            vm.Enlaces.Novo.Itinerario.Novo.listPaths = [];
                            vm.Enlaces.Novo.Itinerario.Novo.hasItinerario(false);
                            vm.Enlaces.Novo.Itinerario.Novo.permiteSalvarItinerario(false);
                            vm.isEditandoItinerario(false);
                            vm.Enlaces.Novo.Itinerario.Novo.sequencia(0);

                            vm.Enlaces.Novo.Itinerario.Lista([]);
                            mSelf.visualizarRotograma(false);

                            mSelf.permiteAdicionarRotograma(false);

                            mSelf.permiteAdicionarRotogramaAcao(false);

                            vm.visualizarConfiguracaoRotograma(false);

                            vm.visualizaHistoricoVeiculo(false);

                            mSelf.limparPolylinhaRotograma();

                            $('body').data("atualizarRotograma", null);

                            mSelf.importandoHistorico(false);
                            mSelf.isItinerarioManual(false);

                            mostrarGuia("guiamapa");
                            vm.visualizaBotoesEnlace(true);
                            mSelf.hasItinerario(false);

                            vm.Enlaces.permiteAcaoItinerario(true);

                            vm.Enlaces.Novo.fecharItensMenu("");

                            mSelf.isAdicionando(false);
                            mSelf.importarDesabilitado(false);

                            mSelf.exluirTodosRotogramasDesvios();

                            vm.Enlaces.Novo.PossuiAlteracao(true);

                            $(this).dialog("close");
                        },
                        "Não": function () {
                            $(this).dialog("close");
                        }
                    }
                });
        }
    };

    mSelf.editar = function () {
        LoadingOn();

        var rotograma = new RotogramaModel();
        rotograma.esconderRotogramas();

        mSelf.vertexSelected(-1);

        mSelf.criarCopiaPolylinha();

        vm.Enlaces.Novo.Itinerario.Novo.vertexSelected(-1);
        if (!vm.Enlaces.Novo.Itinerario.Novo.polylinha.getMap())
            vm.Enlaces.Novo.Itinerario.Novo.polylinha.setMap(map);

        vm.Enlaces.Novo.visualizandoItinerarioEnlace(true);

        vm.Enlaces.Novo.Itinerario.Novo.polylinha.setEditable(true);
        vm.visualizaBotoesEnlace(false);
        vm.Enlaces.Novo.Itinerario.Novo.isItinerarioManual(true);

        vm.Enlaces.Novo.Itinerario.Novo.hasItinerario(true);
        vm.Enlaces.Novo.Itinerario.Novo.permiteSalvarItinerario(true);
        vm.isEditandoItinerario(true);

        var bounds = new google.maps.LatLngBounds();

        mSelf.excluirDesabilitado(true);

        google.maps.event.clearListeners(mSelf.polylinha, 'click');

        google.maps.event.addListener(mSelf.polylinha, 'click', function (event) { mSelf.click(event); });

        var fn = vm.Enlaces.Novo.Itinerario.Novo.addLatitudeLongitude
        google.maps.event.clearListeners(map, 'click');
        google.maps.event.addListener(map, 'click', fn);
        vm.Terminais.setFormaEvents([
            new Handler({
                eventName: "click",
                callback: fn
            })
        ]);

        mSelf.isAdicionandoPontos(true);

        mSelf.navegarTeclado(true);

        LoadingOff();
    };

    mSelf.addLatitudeLongitude = function (event) {
        if (vm.isEditandoItinerario() && mSelf.isAdicionandoPontos()) {
            var path = vm.Enlaces.Novo.Itinerario.Novo.polylinha.getPath();
            path.push(event.latLng);

            var itinerarioModel = new PontoItinerarioModel();
            itinerarioModel.Latitude(event.latLng.lat());
            itinerarioModel.Longitude(event.latLng.lng());
            itinerarioModel.Sequencia(vm.Enlaces.Novo.Itinerario.Novo.sequencia());

            vm.Enlaces.Novo.Itinerario.Lista().push(itinerarioModel);

            vm.Enlaces.Novo.Itinerario.Novo.sequencia(vm.Enlaces.Novo.Itinerario.Novo.sequencia() + 1);

            vm.Enlaces.Novo.Itinerario.Novo.listPaths.push(event.latLng);
        }
    };

    mSelf.finalizar = function () {
        vm.Enlaces.Novo.Itinerario.Novo.permiteSalvarItinerario(false);
        vm.isEditandoItinerario(false);
        if (vm.Enlaces.Novo.Itinerario.Novo.polylinha != null) {
            vm.Enlaces.Novo.Itinerario.Novo.vertexSelected(-1);
            vm.Enlaces.Novo.Itinerario.Novo.polylinha.setEditable(false);
        }
    }

    mSelf.importarItinerario = function () {
        if (!mSelf.importarDesabilitado() && !mSelf.importandoHistorico()) {
            var aux = vm.Enlaces.Novo.Itinerario.Novo.importandoHistorico();
            vm.Enlaces.Novo.Itinerario.Novo.importandoHistorico(!aux);

            vm.visualizaHistoricoVeiculo(!aux);
            mostrarGuia(aux ? "guiamapa" : "historicoVeiculo");
            vm.isEditandoItinerario(!aux);
            vm.Enlaces.Novo.Itinerario.Novo.isItinerarioManual(false);

            mSelf.manualmenteDesabilitado(!aux);
            vm.Enlaces.permiteAcaoItinerario(!aux);
            vm.Enlaces.permiteAcaoItinerario(false);
            mSelf.isAdicionandoPontos(aux);
        }
    };

    mSelf.cancelaEdicaoItinerario = function () {
        if (vm.Enlaces.Novo.Itinerario.Novo.hasItinerario()) {
            vm.Enlaces.Novo.Itinerario.Novo.vertexSelected(-1);
            vm.Enlaces.Novo.Itinerario.Novo.polylinha.setEditable(false);
        } else {
            vm.Enlaces.Novo.Itinerario.Novo.polylinha.setMap(null);
            vm.Enlaces.Novo.Itinerario.Novo.polylinha = null;
            vm.Enlaces.Novo.Itinerario.Novo.listPaths = [];
        }
        vm.Enlaces.Novo.Itinerario.Novo.isItinerarioManual(false);
        vm.isEditandoItinerario(false);
        //vm.Enlaces.Novo.ItinerarioVisivel(false);

        mSelf.visualizarRotograma(false);

        mSelf.permiteAdicionarRotograma(false);

        mSelf.permiteAdicionarRotogramaAcao(false);

        vm.visualizarConfiguracaoRotograma(false);

        vm.visualizaHistoricoVeiculo(false);

        mSelf.limparPolylinhaRotograma();

        mostrarGuia("guiamapa");

        mSelf.isItinerarioManual(false);
        mSelf.importandoHistorico(false);
        vm.visualizaHistoricoVeiculo(false);

        $('body').data("atualizarRotograma", null);

        vm.Enlaces.permiteAcaoItinerario(true);

        mSelf.excluirDesabilitado(false);

        mSelf.editarSelecionado(false);

        mSelf.adicionarDesabilitado(false);
    };

    mSelf.plotarItinerarioEdicao = function (pontos) {
        if (this.polylinha)
            this.polylinha.setMap(null);

        mSelf.polylinha = mSelf.optionsPolylinha(false);


        if (pontos && pontos.length > 0) {
            var path = mSelf.polylinha.getPath();

            var historicoBounds = new google.maps.LatLngBounds();

            vm.verificarCriacaoItinerario(true);

            for (var index in pontos) {

                var coordenadas = new google.maps.LatLng(pontos[index].Latitude() / 1000000, pontos[index].Longitude() / 1000000);

                if (pontos[index].CodigoRotograma())
                    coordenadas.CodigoRotograma = pontos[index].CodigoRotograma();
                else
                    coordenadas.CodigoRotograma = null;

                path.push(coordenadas);

                historicoBounds.extend(coordenadas);

                mSelf.listPaths.push(coordenadas);
            }

            vm.verificarCriacaoItinerario(false);

            map.setCenter(historicoBounds.getCenter());

            map.fitBounds(historicoBounds);

            mSelf.polylinha.setMap(map);

            mSelf.idxIni = -1;
            mSelf.idxFim = -1;
            mSelf.setPathSelecionado();

            mSelf.hasItinerario(true);
        }
    };

    mSelf.plotarItinerario = function (pontos) {
        if (this.polylinha == null)
            this.polylinha = this.optionsPolylinha();
        else
            this.polylinha.setOptions(this.optionsPolylinha());


        if (mSelf.substituirItinerario()) {
            if (this.polylinha)
                this.polylinha.setMap(null);

            this.polylinha = this.optionsPolylinha();
        }

        var path = vm.Enlaces.Novo.Itinerario.Novo.polylinha.getPath();


        if (pontos && pontos.length > 0) {
            var historicoBounds = new google.maps.LatLngBounds();

            for (var index in pontos) {

                var coordenadas = new google.maps.LatLng(pontos[index].lat, pontos[index].lng);

                path.push(coordenadas);

                historicoBounds.extend(coordenadas);
            }

            mostrarGuia("guiamapa");

            map.setCenter(historicoBounds.getCenter());

            map.fitBounds(historicoBounds);

            mSelf.polylinha.setMap(map);
            mSelf.vertexSelected(-1);
            mSelf.polylinha.setEditable(true);

            mSelf.idxIni = -1;
            mSelf.idxFim = -1;
            mSelf.setPathSelecionado();

            vm.visualizaHistoricoVeiculo(false);

            google.maps.event.clearListeners(mSelf.polylinha, 'click');

            google.maps.event.addListener(mSelf.polylinha, 'click', function (event) { mSelf.click(event); });

            mSelf.navegarTeclado(true);

            mSelf.isAdicionandoPontos(true);
        }
    };

    mSelf.adicionarItinerario = function () {
        var adicionando = mSelf.isItinerarioManual() || mSelf.importandoHistorico();
        if (!mSelf.adicionarDesabilitado()) {
            var aux = mSelf.isAdicionando();
            if (!adicionando) {
                mSelf.isAdicionando(!aux);
                vm.Enlaces.permiteAcaoItinerario(aux);
            }
        }
    }

    //    mSelf.adicionarPontos = function () {
    //        var aux = mSelf.isAdicionandoPontos();
    //        if (mSelf.importandoHistorico()) {
    //            vm.visualizaHistoricoVeiculo(false);
    //            mSelf.importandoHistorico(false);
    //            mostrarGuia("guiamapa");
    //        }
    //        mSelf.isAdicionandoPontos(!aux);
    //        if (mSelf.isAdicionandoPontos()) {
    //            var fn = vm.Enlaces.Novo.Itinerario.Novo.addLatitudeLongitude
    //            google.maps.event.clearListeners(map, 'click');
    //            google.maps.event.addListener(map, 'click', fn);
    //            vm.Terminais.setFormaEvents([
    //                        new Handler({
    //                            eventName: "click",
    //                            callback: fn
    //                        })
    //           ]);
    //        } else {
    //            google.maps.event.clearListeners(map, 'click');
    //        }

    //    };

    mSelf.editarItinerario = function () {
        var aux = mSelf.editarSelecionado();
        if (!aux) {
            mSelf.editarSelecionado(!aux);
            vm.Enlaces.permiteAcaoItinerario(aux);
            mSelf.editar();
        }

        mSelf.excluirDesabilitado(mSelf.editarSelecionado());
    };

    mSelf.rightClick = function (event) {

        if (event) {

            if (!mSelf.permiteAdicionarRotogramaAcao()) {

                var arrayItens = [];

                //if (!vm.Linha.IsAtiva()) {
                arrayItens.push({ Texto: "Remover Itinerário", Click: function () { vm.Enlaces.Novo.Itinerario.Novo.excluir(); } });
                if (!vm.isEditandoItinerario()) {
                    arrayItens.push({ Texto: "Editar Itinerário", Click: function () { vm.Enlaces.Novo.Itinerario.Novo.editar(); } });
                }
                //}

                if (vm.isEditandoItinerario()) {
                    arrayItens.push({ Texto: "Continuar itinerário" });
                    arrayItens.push({ Texto: "Excluir vértices" });
                }

                vm.MenuContexto.show(arrayItens, event);
            }
        }
    };

    mSelf.rightClickSelecionada = function (event) {

        if (event) {

            if (mSelf.permiteAdicionarRotogramaAcao()) {

                var temRotograma = false;

                if (mSelf.permiteAdicionarRotogramaAcao() && mSelf.polylinhaSelecionada) {

                    var path = mSelf.polylinhaSelecionada.getPath();

                    if (path.length >= 2)
                        temRotograma = true;
                }

                if (temRotograma) {

                    var arrayItens = [];

                    arrayItens.push({ Texto: "Configurar Rotograma", Click: function () { vm.Enlaces.Novo.Itinerario.Novo.configurarRotograma(); } });
                    arrayItens.push({ Texto: "Remover Rotograma", Click: function () { vm.Enlaces.Novo.Itinerario.Novo.limparPolylinhaRotograma(); } });

                    vm.MenuContexto.show(arrayItens, event);
                }
            }
        }
    };

    mSelf.idxIni = -1;
    mSelf.idxFim = -1;

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

    mSelf.latLngCheckKey = function (evt) {
        "use strict";
        var code = evt.keyCode;

        switch (code) {
            case 68:  // letra D
            case 46:  // delete
                mSelf.polylinha.getPath().removeAt(mSelf.vertexSelected());
                mSelf.vertexSelected(-1);
                break;
            case 13:  //enter
                mSelf.vertexSelected(-1);
                break;
            case 37:  // Seta esquerda (teclado alfanumérico)
            case 38:  // Seta cima     (teclado alfanumérico)
            case 39:  // Seta direita  (teclado alfanumérico)
            case 40:  // Seta baixo    (teclado alfanumérico)
            case 100: // Seta esquerda (teclado numérico)
            case 104: // Seta cima     (teclado numérico)
            case 102: // Seta direita  (teclado numérico)
            case 98:  // Seta baixo    (teclado numérico)
                var direcao = 0,
                    metros = 0;
                if (code == 39 ||  // Seta direita (teclado alfanumérico)
                    code == 102) { // Seta direita (teclado numérico)
                    direcao = 90;
                } else if (code == 40 ||  // Seta baixo (teclado alfanumérico)
                    code == 98) {  // Seta baixo (teclado numérico)
                    direcao = 180;
                } else if (code == 37 ||
                    code == 100) { // Seta esquerda (teclado alfanumérico)
                    direcao = 270;        // Seta esquerda (teclado numérico)
                }

                metros = evt.shiftKey ? 0.0001 : 0.001;
                mSelf.movimentarPonto(direcao, metros);
                break;
            default:
                break;
        }
    };


    mSelf.movimentarPonto = function (direcao, metros) {
        var latLng = mSelf.polylinha.getPath().getAt(mSelf.vertexSelected()),
            nvLatLng = null;

        if (latLng) {
            nvLatLng = addMetrosToLatLng(latLng, direcao, metros);
            nvLatLng.marker = latLng.marker;

            nvLatLng.CodigoRotograma = latLng.CodigoRotograma;

            mSelf.polylinha.getPath().setAt(mSelf.vertexSelected(), nvLatLng);
        }
    };

    /*
    *
    * @param: event : google.maps.PolyMouseEvent
    * google.maps.PolyMouseEvent properties:
    *   edge: 
    *   path: 
    *   vertex:
    */
    mSelf.click = function (event) {

        function findTrecho(posicao) {
            var bounds = null,
                array = mSelf.polylinha.getPath(),
                index = -1;

            for (var i = 0; i < array.length - 1; i++) {
                bounds = new google.maps.LatLngBounds();

                bounds.extend(array.getAt(i));
                bounds.extend(array.getAt(i + 1));

                if (bounds.contains(posicao)) {
                    index = i;
                    break;
                }
            }

            if (index > -1) {
                mSelf.idxIni = index;
                mSelf.idxFim = index + 1;
            }
        }

        if (isUndefined(event.vertex)) {
            event.vertex = -1;
        }

        if (mSelf.vertexSelected() == event.vertex) {
            event.vertex = -1;
        }

        mSelf.vertexSelected(event.vertex);

        mSelf.idxIni = -1;
        mSelf.idxFim = -1;
        if (event.vertex == -1) {
            findTrecho(event.latLng);
        }

        mSelf.setPathSelecionado();
    };

    mSelf.clickRotograma = function (event) {

        mSelf.ajustarPolilinhaSelecionada();

        mSelf.isEditando(true);

        mSelf.navegarTeclado(true);

        function findTrecho(posicao) {
            var bounds = null,
                array = mSelf.polylinha.getPath(),
                index = -1;

            for (var i = 0; i < array.length - 1; i++) {
                bounds = new google.maps.LatLngBounds();

                bounds.extend(array.getAt(i));
                bounds.extend(array.getAt(i + 1));

                if (bounds.contains(posicao)) {
                    index = i;
                    break;
                }
            }

            if (index > -1) {
                mSelf.idxIni = index;
                mSelf.idxFim = index + 1;
            }
        }

        if (isUndefined(event.vertex)) {
            event.vertex = -1;
        }

        if (mSelf.vertexSelected() == event.vertex) {
            event.vertex = -1;
        }

        mSelf.vertexSelected(event.vertex);

        mSelf.idxIni = -1;
        mSelf.idxFim = -1;
        if (event.vertex == -1) {
            findTrecho(event.latLng);
        }

        mSelf.setPathSelecionado();

        vm.Enlaces.Novo.ItinerarioSelecionado(mSelf);

        vm.Enlaces.Novo.Itinerario.Novo.PermiteConfigurarRotograma(true);
    };

    mSelf.ajustarPolilinhaSelecionada = function () {

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

            desvio.Itinerario.Novo.limparPolylinhaRotograma();
        });

        vm.Enlaces.Novo.Itinerario.Novo.limparPolylinhaRotograma();
    };

    mSelf.setPathSelecionado = function () {
        if (mSelf.polylinha && mSelf.isEditando()) {
            var pt = null,
                path = [],
                array = mSelf.polylinha.getPath(),
                ini = mSelf.idxIni,
                fim = mSelf.idxFim;

            if (ini > fim) {
                ini = mSelf.idxFim;
                fim = mSelf.idxIni;
            }

            if (ini > -1) {
                for (var i = ini; i <= fim; i++) {
                    if (pt === array.getAt(i)) {
                        i++;
                    }
                    pt = array.getAt(i);
                    path.push(pt);
                }
            }
            mSelf.polylinhaSelecionada.setPath(path);
            mSelf.setCenterSelecionado(path);
        }
    };

    mSelf.setCenterSelecionado = function (path) {
        if (path.length > 1) {
            var len = path.length,
                latlngRua = null;
            if (path.length == 2) {
                var lat = path[0].lat();
                lat = lat + path[len - 1].lat()
                lat /= 2;

                var lng = path[0].lng();
                lng = lng + path[len - 1].lng();
                lng /= 2;

                latlngRua = new google.maps.LatLng(lat, lng);
            } else {
                var ind = Math.round(len / 2);
                latlngRua = path[ind];
            };
            if (latlngRua) {
                if (!map.getBounds().contains(latlngRua)) {
                    map.setCenter(latlngRua);
                }
            }
        }
    };
    mSelf.navegarFrente = function () {
        var a = mSelf.polylinha.getPath();
        var inicio;
        var fim;
        if (mSelf.idxFim > mSelf.idxIni) {
            inicio = mSelf.idxIni;
            fim = mSelf.idxFim;
        } else {
            inicio = mSelf.idxFim;
            fim = mSelf.idxIni;
        }
        if (fim - inicio > 1) {
            inicio = fim - 1;
        }
        if (mSelf.idxFim - 1 > mSelf.idxIni) {
            mSelf.idxIni = mSelf.idxFim - 1;
        } else if (mSelf.idxFim - 1 < mSelf.idxIni) {
            mSelf.idxFim = mSelf.idxIni - 1;
        }
        if (fim + 1 < a.length) {
            mSelf.idxIni = fim;
            mSelf.idxFim = fim + 1;
        }
    };

    mSelf.navegarMultiFrente = function () {
        var a = mSelf.polylinha.getPath(),
            inicio = -1,
            fim = -1;
        if (mSelf.idxFim > mSelf.idxIni) {
            inicio = mSelf.idxIni;
            fim = mSelf.idxFim;
        } else {
            inicio = mSelf.idxFim;
            fim = mSelf.idxIni;
        }
        if (fim - inicio > 1) {
            inicio = fim - 1;
        }
        if (mSelf.idxFim + 1 < a.length) {
            if (mSelf.idxFim + 1 == mSelf.idxIni) {
                mSelf.idxIni = mSelf.idxFim;
                mSelf.idxFim = mSelf.idxFim + 1;
            } else {
                mSelf.idxFim++;
            }
        }
    };
    mSelf.navegarTras = function () {
        var a = mSelf.polylinha.getPath().length,
            inicio = -1,
            fim = -1;
        if (mSelf.idxFim > mSelf.idxIni) {
            inicio = mSelf.idxIni;
            fim = mSelf.idxFim;
        } else {
            inicio = mSelf.idxFim;
            fim = mSelf.idxIni;
        }
        if (fim - inicio > 1) {
            fim = inicio + 1;
        }
        if (inicio > 0) {
            if (mSelf.idxFim - 1 > mSelf.idxIni) {
                mSelf.idxFim = mSelf.idxIni + 1;
            } else if (mSelf.idxFim - 1 < mSelf.idxIni) {
                mSelf.idxIni = mSelf.idxFim + 1;
            }
            if (mSelf.idxIni - 1 > -1) {
                mSelf.idxIni--;
                mSelf.idxFim--;
            }
        }
    };
    mSelf.navegarMultiTras = function () {
        var a = mSelf.polylinha.getPath(),
            inicio = -1,
            fim = -1;
        if (mSelf.idxFim > mSelf.idxIni) {
            inicio = mSelf.idxIni;
            fim = mSelf.idxFim;
        } else {
            inicio = mSelf.idxFim;
            fim = mSelf.idxIni;
        }
        if (inicio > -1) {
            if (mSelf.idxFim - 1 > -1) {
                if (mSelf.idxFim - 1 == mSelf.idxIni) {
                    mSelf.idxIni = mSelf.idxFim;
                    mSelf.idxFim = mSelf.idxFim - 1;
                } else {
                    mSelf.idxFim--;
                }
            }
        };
    };

    mSelf.removerPontos = function () {
        var array = mSelf.polylinha.getPath(),
            invertido = false,
            ini = mSelf.idxIni,
            fim = mSelf.idxFim;

        if (ini > fim) {
            ini = mSelf.idxFim;
            fim = mSelf.idxIni;
            invertido = true;
        }

        for (var i = 0; i < array.length; i++) {
            if (i > ini &&
                i < fim) {
                array.removeAt(i);
                fim--;
            }
        }

        if (invertido) {
            mSelf.idxIni = fim;
        } else {
            mSelf.idxFim = fim;
        }
    };

    mSelf.criarPontos = function (num) {
        if (mSelf.isAdicionandoPontos()) {
            var inicio;
            var fim;
            var array = mSelf.polylinha.getPath();
            if (mSelf.idxFim > mSelf.idxIni) {
                inicio = mSelf.idxIni;
                fim = mSelf.idxFim;
            } else {
                inicio = mSelf.idxFim;
                fim = mSelf.idxIni;
            }
            if ((fim - inicio == 1)) {
                var posicoes = [];
                var divisao = num + 1;
                fim = inicio + divisao;
                var latDif = ((1 / divisao) * (array.getAt(inicio + 1).lat() - array.getAt(inicio).lat()));
                var lngDif = ((1 / divisao) * (array.getAt(inicio + 1).lng() - array.getAt(inicio).lng()));
                var posicaoInicio = array.getAt(inicio);
                var i = 0;
                for (i = 1; i <= num; i++) {
                    var posicao = new google.maps.LatLng(
                        posicaoInicio.lat() + i * latDif,
                        posicaoInicio.lng() + i * lngDif
                    );

                    posicao.CodigoRotograma = posicaoInicio.CodigoRotograma;

                    posicoes.push(posicao);
                };

                var a = [];
                a.type = "im";
                a.index = inicio;
                a.len = posicoes.length;
                a.inicio = mSelf.idxIni;
                a.fim = mSelf.idxFim;

                for (i = 0; i < posicoes.length; i++) {
                    array.insertAt(inicio + 1 + i, posicoes[i]);
                };
                mSelf.idxIni = inicio;
                mSelf.idxFim = fim;
            };
        }
    }

    mSelf.checkKey = function (evt) {
        "use strict";
        if (mSelf.vertexSelected() > -1) {
            mSelf.latLngCheckKey(evt);
        }

        if (mSelf.idxIni == -1) {
            return;
        }

        var code = evt.keyCode,
            fn = "navegar";

        if (evt.shiftKey) {
            fn += "Multi";
        }
        switch (code) {
            case 32: // espaço
                if (evt.shiftKey && mSelf.polylinha && mSelf.polylinha.getEditable())
                    fn = "removerPontos";
                break;
            case 38: // seta para direita
            case 39: // seta para cima
                if (mSelf.polylinha)
                    fn += "Frente";
                break;
            case 37: // seta para esquerda
            case 40: // seta para baixo
                if (mSelf.polylinha)
                    fn += "Tras";
                break;
            case 49: // 1 teclado alfa-numérico
                //case 97: // 1 teclado numérico
                if (event.shiftKey && mSelf.polylinha && mSelf.polylinha.getEditable()) {
                    mSelf.criarPontos(1);
                }
                break;
            case 50: // 2 teclado alfa-numérico
                //case 98: // 2 teclado numérico
                if (event.shiftKey && mSelf.polylinha && mSelf.polylinha.getEditable()) {
                    mSelf.criarPontos(2);
                }
                break;
            case 51: // 3 teclado alfa-numérico
                //case 99: // 3 teclado numérico
                if (event.shiftKey && mSelf.polylinha && mSelf.polylinha.getEditable()) {
                    mSelf.criarPontos(3);
                }
                break;
            case 52: // 4 teclado alfa-numérico
                //case 100: // 4 teclado numérico
                if (event.shiftKey && mSelf.polylinha && mSelf.polylinha.getEditable()) {
                    mSelf.criarPontos(4);
                }
                break;
            case 53:  // 5 teclado alfa-numérico
                //case 101: // 5 teclado numérico
                if (event.shiftKey && mSelf.polylinha && mSelf.polylinha.getEditable()) {
                    mSelf.criarPontos(5);
                }
                break;
            case 54:  // 6 teclado alfa-numérico
                //case 102: // 6 teclado numérico
                if (event.shiftKey && mSelf.polylinha && mSelf.polylinha.getEditable()) {
                    mSelf.criarPontos(6);
                }
                break;
            case 55:  // 7 teclado alfa-numérico
                //case 103: // 7 teclado numérico
                if (event.shiftKey && mSelf.polylinha && mSelf.polylinha.getEditable()) {
                    mSelf.criarPontos(7);
                }
                break;
            case 56:  // 8 teclado alfa-numérico
                //case 104: // 8 teclado numérico
                if (event.shiftKey && mSelf.polylinha && mSelf.polylinha.getEditable()) {
                    mSelf.criarPontos(8);
                }
                break;
            case 57:  // 9 teclado alfa-numérico
                //case 105: // 9 teclado numérico
                if (event.shiftKey && mSelf.polylinha && mSelf.polylinha.getEditable()) {
                    mSelf.criarPontos(9);
                }
                break;
            default:
                return;
        }

        if (isFunction(mSelf[fn])) {
            mSelf[fn]();
        }

        mSelf.setPathSelecionado();
    }

    var hasKeyDownListener = false;
    mSelf.navegarTeclado = function (navegar) {
        mSelf.idxIni = -1;

        google.maps.event.clearListeners(document, 'keydown');

        if (navegar) {
            google.maps.event.addDomListener(document, "keydown", mSelf.checkKey);
        }

        mSelf.setPathSelecionado();
    };

    mSelf.toggleAdicionarRotograma = function () {

        if (!vm.Enlaces.Novo.RotogramasDesabilitado() && vm.Enlaces.permiteAcaoRotogramas()) {

            var aux = mSelf.visualizarRotograma();

            mSelf.permiteAdicionarRotograma(!aux);

            mSelf.permiteAdicionarRotogramaAcao(false);

            mSelf.PermiteConfigurarRotograma(false);

            mSelf.permiteSalvarRotograma(false);

            if (vm.visualizarConfiguracaoRotograma()) {

                vm.visualizarConfiguracaoRotograma(false);

                mostrarGuia("guiamapa");
            }

            mSelf.visualizarRotograma(!aux);
            mSelf.navegarTeclado(!aux);

            vm.visualizaBotoesEnlace(aux);

            vm.Enlaces.Novo.fecharItensMenu("RotogramasVisivel");

            vm.escondeAbasConfiguracao();

            mSelf.vertexSelected(-1);
            mSelf.polylinha.setEditable(false);

            mSelf.limparEventosItinerario();

            var rotograma = new RotogramaModel();

            if (mSelf.visualizarRotograma()) {

                vm.Enlaces.Novo.Desvios.plotarDesvios();

                rotograma.setarAcoesTodosRotogramas();

                rotograma.habilitarRotogramasVisualizacaoMenu();

                if (mSelf.polylinha.getMap() == null) {
                    mSelf.polylinha.setMap(map);
                    vm.Enlaces.Novo.visualizandoItinerarioEnlace(true);
                }
            }

            vm.Enlaces.permiteAcao(aux);
        }
    };

    mSelf.adicionarRotograma = function () {
        if (!mSelf.adicionarDesabilitado() && mSelf.permiteAcaoAdicionarRotograma()) {
            var aux = mSelf.permiteAdicionarRotogramaAcao();

            mSelf.permiteAdicionarRotogramaAcao(!aux);

            vm.visualizarConfiguracaoRotograma(false);

            vm.Enlaces.adicionarEventosPolilinhaDesvio(!aux);

            mSelf.navegarTeclado(!aux);

            mSelf.adicionarEventosItinerario(!aux);

            mSelf.PermiteConfigurarRotograma(false);

            mSelf.permiteSalvarRotograma(false);

            vm.Enlaces.Novo.visualizandoItinerarios(false);

            mSelf.permiteAcaoConfigurar(true);

            mSelf.limparPolilinhaSelecaoRotograma();

            mostrarGuia("guiamapa");

            vm.Enlaces.permiteAcaoRotogramas(aux);

            if (aux && vm.Enlaces.Novo.Desvios.Novo != null)
                vm.Enlaces.Novo.Desvios.Novo.Itinerario.Novo.polylinhaSelecionada.setPath([]);

            // desabilita outros items do menu
            for (var index in vm.Enlaces.Novo.Rotogramas()) {
                vm.Enlaces.Novo.Rotogramas()[index].desabilitado(!aux);
            }
        }
    };

    mSelf.permiteSalvarRotograma = ko.observable(false);
    mSelf.permiteAcaoConfigurar = ko.observable(true);

    mSelf.configurarRotograma = function () {

        if (!mSelf.configurarDesabilitado() && mSelf.permiteAcaoConfigurar()) {

            if (vm.Enlaces.Novo.ItinerarioSelecionado().idxIni > -1 && vm.Enlaces.Novo.ItinerarioSelecionado().idxFim > -1) {

                var aux = mSelf.permiteSalvarRotograma();

                mSelf.permiteSalvarRotograma(!aux);

                var objRotograma = new RotogramaModel();

                objRotograma.ItinerarioRotograma = vm.Enlaces.Novo.ItinerarioSelecionado();

                if (!objRotograma.verificarGeracaoRotograma())
                    return;

                objRotograma.limparFormularioRotograma();

                vm.visualizarConfiguracaoRotograma(true);

                mostrarGuia("rotogramaItinerarioEnlace");

                $("#txtDescricaoTrecho").focus();

                // limpa o evento de navegação
                google.maps.event.clearListeners(document, 'keydown');

                mSelf.permiteAcaoConfigurar(false);

                mSelf.permiteAcaoAdicionarRotograma(false);
            }
            else
                abrirModalMensagem("Mensagem", "Não existe trecho selecionado!");
        }
    };

    mSelf.limparPolilinhaSelecaoRotograma = function () {

        vm.Enlaces.Novo.Itinerario.Novo.limparPolylinhaRotograma();

        for (var indexLista in vm.Enlaces.Novo.Desvios.Lista()) {

            var desvio = vm.Enlaces.Novo.Desvios.Lista()[indexLista];

            if (desvio && desvio.Itinerario && desvio.Itinerario.Novo)
                desvio.Itinerario.Novo.limparPolylinhaRotograma();
        }
    };

    mSelf.limparPolylinhaRotograma = function () {

        mSelf.idxIni = -1;

        mSelf.idxFim = -1;

        mSelf.setPathSelecionado();
    };

    mSelf.adicionarEventosItinerario = function (habilitar) {

        google.maps.event.clearListeners(mSelf.polylinhaSelecionada, 'click');

        google.maps.event.clearListeners(mSelf.polylinhaSelecionada, 'rightclick');

        google.maps.event.clearListeners(mSelf.polylinha, "click");

        if (habilitar)
            google.maps.event.addDomListener(mSelf.polylinha, "click", mSelf.clickRotograma);


        if (vm.Enlaces.Novo.Rotogramas && vm.Enlaces.Novo.Rotogramas().length > 0) {

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

                rotograma.limparEventosRotograma();

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

    mSelf.verificarEventosPolilinhaSelecaoRotograma = function () {

        if (mSelf.permiteAdicionarRotogramaAcao()) {

            google.maps.event.addListener(mSelf.polylinha, 'click', function (event) { mSelf.clickRotograma(event); });

            //google.maps.event.addListener(mSelf.polylinhaSelecionada, 'rightclick', function (event) { mSelf.rightClickSelecionada(event); });
        }
        else {

            google.maps.event.clearListeners(mSelf.polylinhaSelecionada, 'click');

            //google.maps.event.clearListeners(mSelf.polylinhaSelecionada, 'rightclick');

            mSelf.limparPolylinhaRotograma();
        }

        var rotograma = new RotogramaModel();

        rotograma.setarAcoesTodosRotogramas();
    };

    mSelf.limparEventosItinerario = function () {

        google.maps.event.clearListeners(vm.Enlaces.Novo.Itinerario.Novo.polylinhaSelecionada, 'click');

        google.maps.event.clearListeners(vm.Enlaces.Novo.Itinerario.Novo.polylinhaSelecionada, 'rightclick');

        google.maps.event.clearListeners(vm.Enlaces.Novo.Itinerario.Novo.polylinha, "click");

        for (var indexLista in vm.Enlaces.Novo.Desvios.Lista()) {

            var desvio = vm.Enlaces.Novo.Desvios.Lista()[indexLista];

            if (desvio && desvio.Itinerario && desvio.Itinerario.Novo) {

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

                google.maps.event.clearListeners(desvio.Itinerario.Novo.polylinhaSelecionada, 'rightclick');

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

    mSelf.criarCopiaPolylinha = function () {
        mSelf.CopiaPolylinha = [];
        for (var p in mSelf.polylinha.getPath().getArray()) {
            var ponto = mSelf.polylinha.getPath().getArray()[p];
            mSelf.CopiaPolylinha.push(ponto);
        }
    }

    mSelf.voltarPolylinha = function () {
        if (mSelf.polylinha != null && mSelf.CopiaPolylinha != null && mSelf.CopiaPolylinha.length > 0) {
            mSelf.polylinha.setPath([]);
            for (var p in mSelf.CopiaPolylinha) {
                mSelf.polylinha.getPath().push(mSelf.CopiaPolylinha[p]);
            }
            mSelf.CopiaPolylinha = [];
        }
    };

    mSelf.verificarExclusaoItinerario = function () {

        var existeRotogramasDesvios = false;

        if (vm.Enlaces.Novo.Rotogramas && vm.Enlaces.Novo.Rotogramas().length > 0)
            existeRotogramasDesvios = true;

        if (vm.Enlaces.Novo.Desvios.Lista && vm.Enlaces.Novo.Desvios.Lista().length > 0)
            existeRotogramasDesvios = true;

        return existeRotogramasDesvios;
    };

    mSelf.exluirTodosRotogramasDesvios = function () {

        if (vm.Enlaces.Novo.Rotogramas && vm.Enlaces.Novo.Rotogramas().length > 0) {

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

                if (rotograma.polylineRotograma) {

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

                    rotograma.polylineRotograma.setMap(null);
                }

                rotograma.ItinerarioRotograma = null;
            });

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

        if (vm.Enlaces.Novo.Desvios.Lista && vm.Enlaces.Novo.Desvios.Lista().length > 0) {

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

                if (desvio.Itinerario && desvio.Itinerario.Novo && desvio.Itinerario.Novo.polylinha)
                    desvio.Itinerario.Novo.polylinha.setMap(null);
            });

            vm.Enlaces.Novo.Desvios.Lista.removeAll();
        }
    };
}

function genericMatcher(obj) {

    var item = ko.toJS(obj);

    var itens = this.query.split(" ");

    var bool = false;

    for (var i in itens) {
        bool |= ~item.Identificador.toLowerCase().indexOf(itens[i].toLowerCase());
    }

    return bool;
}

function genericHighlighter(obj) {

    var itemHighlighter = JSON.parse(obj);

    return itemHighlighter.Identificador;
}

function genericUpdater(obj) {

    var itemUpdater = JSON.parse(obj);

    $('body').data("codVeiculoHistorico", itemUpdater.Codigo);

    $("#txtHistoricoDe").focus();

    return itemUpdater.Identificador;
}

function genericSorter(items) {

    var beginswith = [], caseSensitive = [], caseInsensitive = [], item;

    while (aItem = items.shift()) {

        var item = ko.toJS(aItem);

        if (!item.Identificador.toLowerCase().indexOf(this.query.toLowerCase()))
            beginswith.push(JSON.stringify(item));
        else if (~item.Identificador.indexOf(this.query))
            caseSensitive.push(JSON.stringify(item));
        else
            caseInsensitive.push(JSON.stringify(item));
    }

    return beginswith.concat(caseSensitive, caseInsensitive)
}