function PlanejamentoHistorico(viewModel, controleMapa) {

    this.PolylineHistorico = null;

    this.MarkersHistorico = {};

    this.ControleMapa = controleMapa;

    this.viewModel = null;

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

    this.infoWindowPontoParada = new google.maps.InfoWindow();

    this.NovaPolyline = ko.observable();

    this.Init(viewModel);

};

PlanejamentoHistorico.prototype.Init = function (viewModel) {
    var mSelf = this;


    this.PlotarHistorico(viewModel);
};

PlanejamentoHistorico.prototype.OnMapClick = function (event) {
    this.ControleMapa.LimparComponentes();

    //this.infoWindowPontoParada.setMap(null);
    //this.infoWindowPontoParada.setContent("");
};

PlanejamentoHistorico.prototype.PlotarHistorico = function (data) {
    this.Destroy();

    this.viewModel = data;

    var mSelf = this;

    if (this.viewModel.PontosParada) {
        var pontosP = this.viewModel.PontosParada();
        for (var i in pontosP) {
            mSelf.AdicionarMarker(this.PolylineHistoricoId() + "PontoParada" + i, pontosP[i], urlGlobal + 'Content/SetoresShape/Images/pp.png', true, true);
        }
    }

    mSelf.AdicionarPolyline(this.PolylineHistoricoId(), this.viewModel.Lista(), true, '#FF0000', false, true, true);
};

PlanejamentoHistorico.prototype.AdicionarMarker = function (id, ponto, icone, addToMap, criarInfoWindow) {
    var mSelf = this;
    var newMarker = new google.maps.Marker({
        position: new google.maps.LatLng(ponto.Latitude(), ponto.Longitude()),
        map: addToMap == null ? this.ControleMapa.map : (addToMap ? this.ControleMapa.map : null),
        icon: icone
    });

    if (this.MarkersHistorico[id] != null) {
        this.MarkersHistorico[id].setMap(null);
        this.MarkersHistorico[id] = null;
    }

    if (criarInfoWindow) {
        newMarker.infoWindow = this.MontarInfoWindowPontoParada(ponto.InfoWindow);

        google.maps.event.addListener(newMarker, 'click', function () {
            mSelf.infoWindowPontoParada.setPosition(newMarker.getPosition());
            mSelf.infoWindowPontoParada.setContent(newMarker.infoWindow);
            mSelf.infoWindowPontoParada.open(mSelf.ControleMapa.map);
        });
    }

    this.MarkersHistorico[id] = newMarker;
};

PlanejamentoHistorico.prototype.AdicionarPolyline = function (id, latLngArray, addToMap, cor, usarSymbol, fitBounds, permitirNavegacao) {
    var pts = [];
    var latLng = null;
    var bounds = new google.maps.LatLngBounds();
    var mSelf = this;

    for (var j = 0; j < latLngArray.length; j++) {
        if (latLngArray[j].Latitude() < -90 || latLngArray[j].Latitude() > 90)
            latLng = new google.maps.LatLng(latLngArray[j].Latitude() / 1000000, latLngArray[j].Longitude() / 1000000);
        else
            latLng = new google.maps.LatLng(latLngArray[j].Latitude(), latLngArray[j].Longitude());

        latLng.InfoWindow = this.MontarInfoWindow(latLngArray[j].InfoWindow);
        latLng.dataHora = latLngArray[j].DataHora();

        pts.push(latLng);

        if (fitBounds)
            bounds.extend(latLng);
    }

    if (fitBounds) {
        this.ControleMapa.map.fitBounds(bounds);
    }

    var newPolyline = new google.maps.Polyline({
        strokeColor: cor,
        path: pts,
        map: addToMap == null ? this.ControleMapa.map : (addToMap ? this.ControleMapa.map : null),
        zIndex: 9000
    });

    this.NovaPolyline(newPolyline);

    google.maps.event.addListener(newPolyline, 'click', function (event) {
        mSelf.ControleMapa.Selecao(event, mSelf.ControleMapa, mSelf.NovaPolyline(), null,
                                            function (idxInicial, idxFinal) {
                                                if (mSelf.NovaPolyline().getPath().getArray()[idxFinal])
                                                    return mSelf.NovaPolyline().getPath().getArray()[idxFinal].InfoWindow;
                                                //return newPolyline.getPath().getArray()[idxFinal].InfoWindow;
                                            });
    });

    this.PolylineHistorico = newPolyline;
};

PlanejamentoHistorico.prototype.SelecaoMultipla = function (polyline, latLng, criarInfoWindow, index, zIndex, weightLine) {

    this.ControleMapa.SelecaoMultipla(polyline, latLng, criarInfoWindow, index, zIndex, weightLine);

};

PlanejamentoHistorico.prototype.MontarInfoWindow = function (infoWindow) {
    var elemento = $("#template-infoWindow-historico").html();

    elemento = elemento.replace("{Identificacao}", infoWindow.Identificacao());
    elemento = elemento.replace("{Descricao}", infoWindow.Descricao());
    elemento = elemento.replace("{Placa}", infoWindow.Placa());
    elemento = elemento.replace("{DataHora}", infoWindow.DataHora());
    elemento = elemento.replace("{Velocidade}", infoWindow.Velocidade());
    elemento = elemento.replace("{Distancia}", infoWindow.Distancia());
    elemento = elemento.replace("{Tempo}", infoWindow.Duracao());

    return elemento;
}

PlanejamentoHistorico.prototype.MontarInfoWindowPontoParada = function (infoWindow) {
    var elemento = $("#template-infoWindow-ponto-parada").html();

    elemento = elemento.replace("{DataHoraInicio}", infoWindow.DataHoraInicio());
    elemento = elemento.replace("{DataHoraFim}", infoWindow.DataHoraFim());
    elemento = elemento.replace("{Tempo}", infoWindow.TempoParado());

    return elemento;
}

PlanejamentoHistorico.prototype.Destroy = function () {
    if (this.PolylineHistorico) {
        this.PolylineHistorico.setMap(null);
        this.PolylineHistorico.setPath([]);

        for (var p in this.viewModel.PontosParada()) {
            this.MarkersHistorico[this.PolylineHistoricoId() + "PontoParada" + p].setMap(null);
        }

        if (this.ControleMapa.PolylineHighlight) {
            this.ControleMapa.PolylineHighlight.setMap(null);
            this.ControleMapa.PolylineHighlight.setPath([]);
        }

        if (this.infoWindowPontoParada)
            this.infoWindowPontoParada.setMap(null);

        if (this.ControleMapa.infoWindowPolylineSelecionada)
            this.ControleMapa.infoWindowPolylineSelecionada.setMap(null);

        for (var x in this.ControleMapa.ListPolylineHighlight()) {
            this.ControleMapa.ListPolylineHighlight()[x].setMap(null);
        }
        this.ControleMapa.ListPolylineHighlight([]);

        for (var i in this.ControleMapa.ListInfoWindows()) {
            this.ControleMapa.ListInfoWindows()[i].setMap(null);
        }
        this.ControleMapa.ListInfoWindows([]);
    }
}

PlanejamentoHistorico.prototype.FocarPosicaoMapa = function (listaIndex, listaPosicoes, limparInfoWindow) {
    var bounds = new google.maps.LatLngBounds();

    var pts = [];
    for (var index in listaIndex) {
        var posicao = listaPosicoes[listaIndex[index]];

        bounds.extend(new google.maps.LatLng(posicao.Latitude(), posicao.Longitude()));

        this.ControleMapa.Selecao(null, this.ControleMapa, this.PolylineHistorico, new google.maps.LatLng(posicao.Latitude(), posicao.Longitude()));
    }

    if (listaIndex.length == 0) {
        for (var p in listaPosicoes) {
            bounds.extend(new google.maps.LatLng(listaPosicoes[p].Latitude(), listaPosicoes[p].Longitude()));
        }
    }

    this.ControleMapa.map.fitBounds(bounds);

    if (limparInfoWindow) {
        this.ControleMapa.infoWindowPolylineSelecionada.setMap(null);
        this.ControleMapa.PolylineHighlight.setMap(null);
        this.ControleMapa.PolylineSelecionada = null;
    }

}

PlanejamentoHistorico.prototype.FiltrarPorVelocidade = function (posicoes, velocidadeInicial, velocidadeFinal) {
    for (var x in posicoes) {
        if (posicoes[x].Velocidade() >= velocidadeInicial && posicoes[x].Velocidade() <= velocidadeFinal) {
            this.SelecaoMultipla(this.PolylineHistorico, new google.maps.LatLng(posicoes[x].Latitude(), posicoes[x].Longitude()), false, x, -5, 8);
        }
    }
};

PlanejamentoHistorico.prototype.FiltrarPontosParada = function (listaPontosParada, tempoParametro, tipoFiltro) {
    if (this.infoWindowPontoParada) {
        this.infoWindowPontoParada.setMap(null);
    }
    for (var x in listaPontosParada) {
        if (tipoFiltro == "maior") {
            if (listaPontosParada[x].TempoParado() <= tempoParametro) {
                this.EsconderMarker(this.PolylineHistoricoId() + "PontoParada" + x);
            } else {
                this.MostrarMarker(this.PolylineHistoricoId() + "PontoParada" + x);
            }
        } else {
            if (listaPontosParada[x].TempoParado() >= tempoParametro) {
                this.EsconderMarker(this.PolylineHistoricoId() + "PontoParada" + x);
            } else {
                this.MostrarMarker(this.PolylineHistoricoId() + "PontoParada" + x);
            }
        }

    }
};

PlanejamentoHistorico.prototype.EsconderMarker = function (markerId) {
    if (this.MarkersHistorico[markerId] != null) {
        this.MarkersHistorico[markerId].setMap(null);
    }
};

PlanejamentoHistorico.prototype.MostrarMarker = function (markerId) {
    if (this.MarkersHistorico[markerId] != null) {
        this.MarkersHistorico[markerId].setMap(this.ControleMapa.map);
    }
};

PlanejamentoHistorico.prototype.MostrarPontosParada = function (lista) {
    for (var i in lista) {
        this.MostrarMarker(this.PolylineHistoricoId() + "PontoParada" + i);
    }
};

PlanejamentoHistorico.prototype.DesmarcarPonto = function (index) {

    for (var x in this.ControleMapa.ListInfoWindows()) {
        if (this.ControleMapa.ListInfoWindows()[x].Id == index) {
            this.ControleMapa.ListInfoWindows()[x].setMap(null);
            this.ControleMapa.ListInfoWindows.remove(this.ControleMapa.ListInfoWindows[x]);
        }
    }

    for (var x in this.ControleMapa.ListPolylineHighlight()) {
        if (this.ControleMapa.ListPolylineHighlight()[x].Id == index) {
            this.ControleMapa.ListPolylineHighlight()[x].setPath([]);
            this.ControleMapa.ListPolylineHighlight()[x].setMap(null);
            this.ControleMapa.ListPolylineHighlight.remove(this.ControleMapa.ListPolylineHighlight[x]);
        }
    }
}

PlanejamentoHistorico.prototype.LimparPolylinesHighlight = function (opcaVerInicioSelecionado, opcaoVerFimSelecionado) {
    var index = this.PolylineHistorico.getPath().getArray().length - 1;
    for (var x in this.ControleMapa.ListPolylineHighlight()) {
        var id = this.ControleMapa.ListPolylineHighlight()[x].Id;
        if (((id == 0 && !opcaVerInicioSelecionado) || id > 0) && ((id == index && !opcaoVerFimSelecionado) || id != index)) {
            this.ControleMapa.ListPolylineHighlight()[x].setPath([]);
            this.ControleMapa.ListPolylineHighlight()[x].setMap(null);
        }
    }
}

PlanejamentoHistorico.prototype.AlterarIconePolylinha = function (sentidoSelecionado) {
    var lineSymbol = {
        path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
    };

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

    if (sentidoSelecionado) {
        this.PolylineHistorico.setOptions({ icons: icons });
    } else {
        this.PolylineHistorico.setOptions({ icons: null });
    }
};

PlanejamentoHistorico.prototype.DestacarPosicoes = function (quantidade) {
    this.PosicoesDestacadas = [];
    for (var x = this.PolylineHistorico.getPath().getArray().length - 1; this.PosicoesDestacadas.length < quantidade ; x--) {
        this.PosicoesDestacadas.push(this.PolylineHistorico.getPath().getArray()[x]);
    }
    for (var i in this.PosicoesDestacadas) {
        this.ControleMapa.SelecaoMultipla(this.PolylineHistorico, this.PosicoesDestacadas[i], false, i, "#0C5A8A");
    }
};

PlanejamentoHistorico.prototype.LimparPosicoesDestacadas = function () {
    var ferramenta = vm.GetFerramenta("FerramentaVisualizacao");
    if (ferramenta) {
        this.LimparPolylinesHighlight(ferramenta.Data().VerInicioSelecionado(), ferramenta.Data().VerFimSelecionado());
    }
};

