function ControlePassagemViewModel(data) {
	var mSelf = this;

	mSelf.Permissoes = data.Data.permissoes;

	mSelf.Data = ko.observable(new FerramentaControlePassagemOpcoes(mSelf));

	mSelf.FerramentaId = data.FerramentaId;

	mSelf.Template = data.Template;

	mSelf.Nome = data.Nome;

	mSelf.Titulo = data.Titulo;

	mSelf.NomeBotao = data.NomeBotao;

	mSelf.Ordem = 1;

	mSelf.Icone = data.Icone;

	mSelf.Visivel = ko.observable(true);

	mSelf.Destroy = function () {
		mSelf.Data().Destroy();
		$(".simple_color").spectrum("destroy");
	};

	mSelf.Init = function () {
		mSelf.Data().Init();
	};
}

function FerramentaControlePassagemOpcoes(data) {
	var mSelf = this;
	var mapa = vm.Perspectiva.ControleMapa;
	var tzoffset = new Date().getTimezoneOffset() * 60000;
	var dataHoje = new Date();
	var dataOntem = new Date(new Date().setDate(new Date().getDate() - 1));
	var forma = [];
	var circulo = [];
	var limiteArea = 282;
	var limiteRaio = 300;
	var limiteMinimoRaio = 150;
	var radioManual = false;
	var index = 0;
	var polylineSelecionado = [];


	mSelf.Permissoes = data.Permissoes;

	mSelf.medidaEditavel = ko.observable(true);
	mSelf.TermoBusca = ko.observable();
	mSelf.DataInicio = ko.observable();
	mSelf.DataFim = ko.observable();
	mSelf.Raio = ko.observable();
	mSelf.FimDataMaxima = ko.observable();
	mSelf.InicioDataMaxima = ko.observable();
	mSelf.InicioDataMinima = ko.observable();
	mSelf.Pesquisa = ko.observable();
	mSelf.ListaResultados = ko.observableArray([]);
	mSelf.Minimizado = false;
	mSelf.TipoPesquisa = ko.observable();

	if (mSelf.Permissoes["Pesquisar por Referência"])
		mSelf.TipoPesquisa = ko.observable("referencia");
	else if (mSelf.Permissoes["Pesquisar por Endereço"])
		mSelf.TipoPesquisa = ko.observable("endereco");
	else if (mSelf.Permissoes["Pesquisar por Forma"])
		mSelf.TipoPesquisa = ko.observable("forma");

	mSelf.TituloMedida = ko.observable("Raio em metros");
	mSelf.TextoLimite = ko.observable("*Raio limite 300m");

	mSelf.FormaSelecionada = ko.observable();
	mSelf.Medida = ko.observable();

	mSelf.InfoWindowpontoParada = new google.maps.InfoWindow();

	mSelf.MedidaComputed = ko.computed(function () {

		if (mSelf.Medida() < limiteMinimoRaio) {

			mSelf.Medida(limiteMinimoRaio);

			radioManual = true;
			mSelf.AlteraFormaSelecionadaCirculo(parseInt(mSelf.Medida()), true);
			radioManual = false;
			mapa.map.fitBounds(circulo.getBounds());
		}

		return mSelf.Medida();
	}, this);

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

	mSelf.Init = function () {
		mapa.VincularAutocomplete($("#pesquisa-area")[0], mSelf.SelecionarLocalidadeGoogle);
		mSelf.SetupDatas();

		//google.maps.event.addDomListener(document, 'keydown', eventKeyDownPress)
		$('#btn_circle').click();

		var isFunction = typeof mSelf.Permissoes === "function";

		if (!mSelf.Permissoes || (isFunction && mSelf.Permissoes() == null)) {
			$("#ControlePassagem").css("display", "none");
		}
	};

	mSelf.SetupDatas = function () {
		mSelf.DataInicio(new Date(dataOntem - tzoffset).toISOString().substr(0, 16));
		mSelf.DataFim(new Date(dataHoje - tzoffset).toISOString().substr(0, 16));
	};

	mSelf.BuscarLocalidade = function (data, event) {
		if (!vm.usarGeoGoogle || mSelf.TipoPesquisa() !== "endereco") {
			clearTimeout(mSelf.Consulta);

			if (data.Pesquisa().length === 0) {
				mSelf.ListaResultados([]);
			}
			else {
				mSelf.Consulta = setTimeout(function () {
					mSelf.SendRequest();
				}, 1000);
			}
		}
		return true;
	};

	mSelf.ChangeOpcaoBusca = function () {
		mapa.PolylineHighlight.setMap(null);
		mapa.infoWindowPolylineSelecionada.open(null);
		mSelf.Pesquisa("");
		mSelf.ListaResultados([]);
		mSelf.DesfazerForma();
		$("#busca-raio").hide();

		if (forma.length > 0) {
			for (i = 0; i < forma.length; i++) {
				forma[i].setMap(null);
			}
		}

		if (mapa.MarkerGeocodeSearch)
			mapa.MarkerGeocodeSearch.setMap(null);

		//vm.Perspectiva.AlvoViewModel(false);

		$("#grid-controle-passagem").hide();
		$("#myGrid").show();
		vm.GetModulo("GridVeiculosViewModel").AlterarTituloGrid();
	}

	mSelf.SendRequest = function () {
		$(".loading-referencia").show();
		$("#pesquisa-area-setor-referencia")[0].disabled = true;
		$("#pesquisa-area-setor-referencia").css('background-color', 'white');
		var param = {
			'tipo': mSelf.TipoPesquisa(),
			'valor': mSelf.Pesquisa()
		};

		$.ajax({
			url: urlGlobal + "Veiculos/Veiculos/BuscarLocalidade",
			contentType: 'application/json; charset=utf-8',
			dataType: "json",
			type: "GET",
			data: param,
			success: function (result) {
				mSelf.ListaResultados(result);
				$("#pesquisa-area-setor-referencia")[0].disabled = false;
			},
			complete: function () {
				$(".loading-referencia").hide();
				$("#pesquisa-area-setor-referencia")[0].disabled = false;
			}
		});
	};

	mSelf.SelecionarLocalidadeGoogle = function () {
		mSelf.DesfazerForma();
		//mSelf.TituloMedida("Quilômetros quadrados");
		//mSelf.TextoLimite("*Área limite 282km²");
		var data = $("#pesquisa-area").val();
		mapa.GeocodeSearch(data);
		$("#busca-raio").show();
		mapa.map.setZoom(17);
	};

	mSelf.SelecionaLocalidade = function (data, evt) {
		mSelf.DesfazerForma();
		if ($('#alvo_menu').hasClass('active')) $('#alvo_menu').click();
		mSelf.ListaResultados([]);
		mSelf.Pesquisa(data.Descricao);

		if (forma.length > 0) {
			for (i = 0; i < forma.length; i++) {
				forma[i].setMap(null);
			}
		}

		if (mapa.MarkerGeocodeSearch)
			mapa.MarkerGeocodeSearch.setMap(null);

		var polygonForma = null;
		switch (mSelf.TipoPesquisa()) {
			case "endereco":
				//mSelf.TituloMedida("Quilômetros quadrados");
				//mSelf.TextoLimite("*Área limite 282km²");
				var latlng = new google.maps.LatLng(data.Latitude, data.Longitude);
				GeocodeSuccess(mapa, latlng);
				mapa.map.setZoom(17);
				//$("#raio-metros")[0].disabled = true;
				break;
			case "forma":
			case "referencia":
				//mSelf.TituloMedida("Quilômetros quadrados");
				//mSelf.TextoLimite("*Área limite 282km²");
				if (data.Coordenadas && data.Coordenadas.length > 0) {
					var bounds = new google.maps.LatLngBounds();
					var pts = [];
					for (var j = 0; j < data.Coordenadas.length; j++) {
						var ptAux = new google.maps.LatLng(data.Coordenadas[j].Latitude, data.Coordenadas[j].Longitude, false);
						pts.push(ptAux);
					}

					objetoForma = {
						fillOpacity: 0.4,
						fillColor: "#000000",
						strokeOpacity: 1.0,
						strokeWeight: 1.0,
						zIndex: 1,
						paths: pts,
						tipo: 1,
						map: mapa.map
					};

					forma.push(new google.maps.Polygon(objetoForma));

					//Seleção da forma
					var selecao = data;
					pts = [];
					for (j = 0; j < selecao.Coordenadas.length; j++) {
						ptAux = new google.maps.LatLng(selecao.Coordenadas[j].Latitude, selecao.Coordenadas[j].Longitude, false);
						bounds.extend(ptAux);
						pts.push(ptAux);
					}

					mSelf.FormaSelecionada(selecao);

					objetoForma = {
						strokeColor: '#FF0000',
						strokeOpacity: 0.8,
						strokeWeight: 2,
						fillColor: '#FF0000',
						fillOpacity: 0.35,
						zIndex: 1,
						paths: pts,
						tipo: 'draw',
						map: mapa.map,
						editable: true,
						suppressUndo: true,
						draggable: true
					};

					polygonForma = new google.maps.Polygon(objetoForma);

					forma.push(polygonForma);
					mapa.map.fitBounds(bounds);

					var areaPoligono = google.maps.geometry.spherical.computeArea(pts);
					mSelf.Medida((areaPoligono / 1000).toFixed(2));
					//$("#raio-metros")[0].disabled = true;
				} else {
					latlng = new google.maps.LatLng(data.Latitude, data.Longitude);
					GeocodeSuccess(mapa, latlng);
					mapa.map.setZoom(17);
				}
				break;
			default:
				break;
		}

		google.maps.event.clearListeners(mapa.map, 'set_at');
		google.maps.event.clearListeners(mapa.map, 'insert_at');
		if (polygonForma) {
			google.maps.event.addListener(polygonForma.getPath(), 'set_at', function (a, pos) {
				//mSelf.Pesquisa(pos.lat() + " - " + pos.lng());
				var areaPoligono = google.maps.geometry.spherical.computeArea(this);
				mSelf.Medida((areaPoligono / 1000).toFixed(2));
				//$("#raio-metros")[0].disabled = true;

				var coordenadas = [];
				this.getArray().forEach(function (data) {
					coordenadas.push({ Latitude: data.lat(), Longitude: data.lng() });
				});
				mSelf.FormaSelecionada({ Coordenadas: coordenadas });
			});
			google.maps.event.addListener(polygonForma.getPath(), 'insert_at', function (a, pos) {
				var areaPoligono = google.maps.geometry.spherical.computeArea(this);
				mSelf.Medida((areaPoligono / 1000).toFixed(2));
				pos = this.b[a];
				//mSelf.Pesquisa(pos.lat() + " - " + pos.lng());
				//$("#raio-metros")[0].disabled = true;

				var coordenadas = [];
				this.getArray().forEach(function (data) {
					coordenadas.push({ Latitude: data.lat(), Longitude: data.lng() });
				});
				mSelf.FormaSelecionada({ Coordenadas: coordenadas });
			});
		}

		$("#busca-raio").show();
	}

	mSelf.FiltrarContexto = function () {
		vm.FecharMensagemAlerta();

		mapa.PolylineHighlight.setMap(null);
		mapa.infoWindowPolylineSelecionada.open(null);
		google.maps.event.clearListeners(document, 'keydown', eventKeyDownPress);

		var isValid = mSelf.ValidarFormulario();

		if (isValid) {
			$(".loading-inlog").fadeIn("fast");
			if (alvo_circle.className === "circle") {
				$.ajax({
					url: urlGlobal + "Veiculos/Veiculos/BuscarPassagens?latitude=" + circulo.getCenter().lat() + "&longitude=" + circulo.getCenter().lng() + "&raio=" + circulo.radius + "&dataInicio=" + mSelf.DataInicio() + "&dataFim=" + mSelf.DataFim(),
					contentType: 'application/json; charset=utf-8',
					dataType: "json",
					type: "GET",
					success: function (ret) {
						mSelf.AplicarPassagens(ret);
					},
					complete: function () {
						$(".loading-inlog").fadeOut("fast");
					}
				});
			} else {
				$.ajax({
					url: urlGlobal + "Veiculos/Veiculos/BuscarPassagens",
					contentType: 'application/json; charset=utf-8',
					dataType: "json",
					type: "POST",
					data: JSON.stringify({
						area: mSelf.FormaSelecionada(),
						dataInicio: mSelf.DataInicio(),
						dataFim: mSelf.DataFim()
					}),
					success: function (ret) {
						mSelf.AplicarPassagens(ret);
					},
					complete: function () {
						$(".loading-inlog").fadeOut("fast");
					}
				});
			}
		}
	};

	mSelf.AplicarPassagens = function (passagens) {
		if (passagens == null) {
			vm.ShowMensagemAlerta("Ops! O período definido possui muitos dados. Defina um período menor.");
			return;
		}

		if (passagens.length === 0) {
			vm.ShowMensagemAlerta("Não temos informações de passagem de veículos nesse período e local");
			return;
		}

		if (vm.GetFerramenta("NovoFiltroVeiculos"))
			vm.GetFerramenta("NovoFiltroVeiculos").Visivel(false);

		$("#grid-controle-passagem").height($("#myGrid").height());
		$("#grid-controle-passagem tbody").height($("#myGrid").height());
		//$("#myGrid").hide();
		$("#grid-controle-passagem").show();

		vm.GetModulo("GridVeiculosViewModel").Titulo("Passagens (" + passagens.length + ")");
		mSelf.Passagens().forEach(function (passagem, index, passagens) {
			if (passagem.Polyline)
				passagem.Polyline.setMap(null);

			passagem.Historico.forEach(function (historico, index, historicos) {
				if (historico.pontoParada)
					historico.pontoParada.setMap(null);
			});
		});

		mSelf.Passagens(passagens);

		mSelf.Passagens().forEach(function (passagem, index, passagens) {
			var result = true;
			do {
				var color = getRandomColor();

				var hasColor = passagens.some(function (item) {
					return item.Polyline && item.Polyline.strokeColor === color;
				});

				if (!hasColor) {
					result = false;

					var path = [];
					passagem.Historico.forEach(function (historico, index, historicos) {
						//if (historico.Parado) {
						//    var proximoHistorico = historicos[index + 1];

						//    if (proximoHistorico) {
						//        historico.pontoParada = new google.maps.Marker({
						//            position: new google.maps.LatLng(historico.Latitude / 1000000, historico.Longitude / 1000000),
						//            icon: urlGlobal + 'Content/Setores/Images/pp.png'
						//        });

						//        historico.infoWindow = {};

						//        historico.infoWindow.DataHoraInicio = new Date(historico.DataHora).toLocaleString();

						//        historico.infoWindow.DataHoraFim = new Date(proximoHistorico.DataHora).toLocaleString();

						//        historico.infoWindow.TempoParado = mSelf.CalculaTempo(new Date(historico.DataHora), new Date(proximoHistorico.DataHora));

						//        historico.pontoParada.infoWindow = mSelf.MontarInfoWindowpontoParada(historico.infoWindow);

						//        google.maps.event.addListener(historico.pontoParada, 'click', function () {
						//            mSelf.InfoWindowpontoParada.setPosition(historico.pontoParada.getPosition());
						//            mSelf.InfoWindowpontoParada.setContent(historico.pontoParada.infoWindow);
						//            mSelf.InfoWindowpontoParada.open(mapa.map);
						//        });
						//    }
						//}
						path.push(new google.maps.LatLng(historico.Latitude / 1000000, historico.Longitude / 1000000));
					});

					passagem.Polyline = new google.maps.Polyline({
						path: path,
						strokeColor: color,
						strokeOpacity: 1.0,
						strokeWeight: 5
					});

					passagem.Polyline.strokeColorDefault = color,
						passagem.Polyline.setMap(mapa.map);
					passagem.Polyline.setOptions({ zIndex: 3 });
					passagem.Polyline.index = index;

					passagem.Historico.forEach(function (historico, index, historicos) {
						if (historico.pontoParada)
							historico.pontoParada.setMap(null);
					});

					google.maps.event.clearListeners(passagem.Polyline, 'click');
					google.maps.event.addListener(passagem.Polyline, 'click', function (event, passagem) {
						var poly = this;
						var fromMap = true;
						var pai = mSelf.Passagens().find(function (item, index) { return item.Polyline.index === poly.index });
						vm.abrirHistorico(pai, event, fromMap);
					});
				}
			} while (result);
		});
	};

	mSelf.CalculaTempo = function (dt1, dt2) {
		var now = dt1;
		var endDate = dt2
		var diff = endDate - now;

		var hours = '0000' + Math.floor(diff / 3.6e6);
		var minutes = '0000' + Math.floor((diff % 3.6e6) / 6e4);
		var seconds = '0000' + Math.floor((diff % 6e4) / 1000);

		hours = hours.substring(hours.length - 2, hours.length)
		minutes = minutes.substring(minutes.length - 2, minutes.length)
		seconds = seconds.substring(seconds.length - 2, seconds.length)

		return hours + ':' + minutes + ':' + seconds;
	}

	mSelf.MontarInfoWindowpontoParada = function (infoWindow) {
		var elemento = '<div class="infowindow-veiculos"><h1 class="sidebar-box-content-title">Ponto de Parada</h1><ul class="infowindow-table"><li class="title-mask"><span><i class="icon-clock"></i> Duração: <strong>{TempoParado}</strong></span></li>            <li><strong>Início:</strong> {Inicio}</li>            <li><strong>Fim:</strong> {Fim}</li>        </ul>    </div>';

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

		return elemento;
	};

	mSelf.CalculaPixelsToLatLng = function (offsetx, offsety) {

		// latlng is the apparent centre-point
		// offsetx is the distance you want that point to move to the right, in pixels
		// offsety is the distance you want that point to move upwards, in pixels
		// offset can be negative
		// offsetx and offsety are both optional

		var scale = Math.pow(2, mapa.map.getZoom());
		var nw = new google.maps.LatLng(
			mapa.map.getBounds().getNorthEast().lat(),
			mapa.map.getBounds().getSouthWest().lng()
		);

		var worldCoordinateCenter = mapa.map.getProjection().fromLatLngToPoint(mapa.map.getCenter());
		var pixelOffset = new google.maps.Point(offsetx / scale || 0, offsety / scale || 0);

		var worldCoordinateNewCenter = new google.maps.Point(
			worldCoordinateCenter.x - pixelOffset.x,
			worldCoordinateCenter.y + pixelOffset.y
		);

		return mapa.map.getProjection().fromPointToLatLng(worldCoordinateNewCenter);

		//return map.getProjection().fromPointToLatLng(new google.maps.Point(newLngInPx, newLatInPx));
	};

	mSelf.ValidarFormulario = function () {
		var valid = true;

		if ((!mSelf.FormaSelecionada() && !$("#alvo_circle")[0])) {
			vm.ShowMensagemAlerta("Selecione uma região para a busca.");
			return false;
		}

		if ($("#alvo_circle")[0].className === "circle" && !circulo) {
			vm.ShowMensagemAlerta("Selecione uma região para a busca.");
			return false;
		}

		//if (($("#alvo_circle")[0].className === "polygon" || $("#alvo_circle")[0].className === "normal") && (!mSelf.FormaSelecionada() || mSelf.FormaSelecionada().Coordenadas.length === 0)) {
		//    vm.ShowMensagemAlerta("Selecione uma região para a busca.");
		//    return false;
		//}

		if (!mSelf.FormaSelecionada() && (!circulo || circulo.length === 0)) {
			vm.ShowMensagemAlerta("Selecione uma região para a busca.");
			return false;
		}

		if (new Date(mSelf.DataFim()) < new Date(mSelf.DataInicio())) {
			vm.ShowMensagemAlerta("A data e hora inicial deve ser menor que a data e hora final.");
			return false;
		}

		dateMax = new Date(new Date().setHours(23, 59, 59, 0));
		if (new Date(mSelf.DataFim()) > dateMax) {
			vm.ShowMensagemAlerta("A data e hora final deve ser inferior à " + formatDate(dateMax));
			return false;
		}

		var tzoffset = new Date().getTimezoneOffset() * 60000;
		var dateMin = new Date(new Date(mSelf.DataFim()).setDate(new Date(mSelf.DataFim()).getDate() - 7) - tzoffset);
		if (new Date(mSelf.DataInicio()) < dateMin) {
			vm.ShowMensagemAlerta("A data e hora inicial deve ser superior à " + formatDate(dateMin));
			return false;
		}

		var polygonForma = forma.filter(function (item) {
			return item.tipo === 'draw';
		});

		//if (($("#alvo_circle")[0].className === "polygon" || (polygonForma && polygonForma.length > 0)) && mSelf.Medida() > limiteArea) {
		//    vm.ShowMensagemAlerta("A área ultrapassa o valor limite de " + limiteArea + "km².");
		//    return false;
		//}

		if (/*$("#alvo_circle")[0].className === "circle" &&*/ mSelf.Medida() > limiteRaio) {
			vm.ShowMensagemAlerta("O raio ultrapassa o valor limite de " + limiteRaio + "m.");
			return false;
		}

		if (/*$("#alvo_circle")[0].className === "circle" &&*/ mSelf.Medida() < limiteMinimoRaio) {
			vm.ShowMensagemAlerta("O raio é menor que o limite mínimo de " + limiteMinimoRaio + "m.");
			return false;
		}

		return valid;
	};

	function formatDate(date) {
		var dd = date.getDate();
		var mm = date.getMonth() + 1; //January is 0!

		var yyyy = date.getFullYear();
		if (dd < 10) {
			dd = '0' + dd;
		}
		if (mm < 10) {
			mm = '0' + mm;
		}
		return dd + '/' + mm + '/' + yyyy;
	}

	//converter objeto c# para padrão restfull
	function toCamel(o) {
		var newO, origKey, newKey, value
		if (o instanceof Array) {
			newO = []
			for (origKey in o) {
				value = o[origKey]
				if (typeof value === "object") {
					value = toCamel(value)
				}
				newO.push(value)
			}
		} else {
			newO = {}
			for (origKey in o) {
				if (o.hasOwnProperty(origKey)) {
					newKey = (origKey.charAt(0).toLowerCase() + origKey.slice(1) || origKey).toString()
					value = o[origKey]
					if (value !== null && value.constructor === Object) {
						value = toCamel(value)
					}
					newO[newKey] = value
				}
			}
		}
		return newO
	}

	mSelf.RegistrarAcoesAlvo = function () {
		vm.Perspectiva.AlvoViewModel(true);

		var top = ($('#mapa').outerHeight() - 422) / 2 + $('header').outerHeight();
		var left = ($('#mapa').outerWidth() - 422) / 2;
		$('#alvo').css('top', top).css('left', left);
		
		if(!mSelf.Minimizado){        

			mSelf.setarEventosAlvo();

			$('#alvo_active').unbind();
			$('#alvo_active').click(function (e) {
				mSelf.DesfazerForma(e);
				mSelf.AlvoPlotarForma(e);
			});

			$('#btn_undo').unbind();
			$('#btn_undo').click(function (e) {
				mSelf.DesfazerForma(e);
				mapa.PolylineHighlight.setMap(null);
				mapa.infoWindowPolylineSelecionada.open(null);
			});

			$('#btn_alvo').unbind();
			$('#btn_alvo').click(function (e) {
				mSelf.AlvoMarker();
				mSelf.AlvoReferenciaSelecionadaClick(true);
			});

			$('#alvo_menu').unbind();
			$('#alvo_menu').click(function (e) {
				mSelf.AcaoClickAlvo();
			});

			$('#btn_circle').click();
		}
	};

	mSelf.setarEventosAlvo = function () {
		$('#alvo_menu').unbind('click');

		$('#alvo_menu').click(function (e) {
			var L = ($('#alvo').outerWidth() - $('#alvo_options').outerWidth()) / 2;
			$('#alvo_options').css('left', L);
			$(this).toggleClass('active');
		});

		$('#alvo_options li.selectable').click(function (e) {
			$('#alvo_active').html($(this).children('svg').clone().attr('width', '34').attr('height', '34'));
		});

		$('#btn_alvo').click(function (e) {
			$('#alvo_circle').removeClass().addClass('normal');
			$('#alvo_menu').trigger('click');
		});

		$('#btn_circle').click(function (e) {
			$('#alvo_circle').removeClass().addClass('circle');
			if ($('#alvo_menu').hasClass('active')) $('#alvo_menu').click();

			google.maps.event.clearListeners(mapa.map, 'click');

			mSelf.DesfazerForma();
			//mSelf.TituloMedida("Raio em metros");
			//mSelf.TextoLimite("*Raio limite 300m");
			//$("#raio-metros")[0].disabled = false;
		});

		//$('#btn_polygon').click(function (e) {
		//    $('#alvo_circle').removeClass().addClass('polygon');
		//    if ($('#alvo_menu').hasClass('active')) $('#alvo_menu').click();

		//    google.maps.event.clearListeners(mapa.map, 'click');

		//    mSelf.DesfazerForma();
		//    mSelf.TituloMedida("Quilômetros quadrados");
		//    mSelf.TextoLimite("*Área limite 282km²");
		//    $("#raio-metros")[0].disabled = true;
		//});

		$('#btn_undo').click(function (e) {
			$('#alvo_circle').removeClass().addClass('normal');
		});

		$('.item').click(function (e) {
			var parent = $(this).parent('div');
			parent.children('.item').removeClass('active');
			$(this).addClass('active');
		});

		$('#raio-metros').keydown(function (e) {
			// Allow: backspace, delete, tab, escape, enter and .
			if ($.inArray(e.keyCode, [46, 8, 9, 27, 13, 110, 190]) !== -1 ||
				// Allow: Ctrl+A, Command+A
				(e.keyCode === 65 && (e.ctrlKey === true || e.metaKey === true)) ||
				// Allow: home, end, left, right, down, up
				(e.keyCode >= 35 && e.keyCode <= 40)) {
				// let it happen, don't do anything
				return;
			}
			// Ensure that it is a number and stop the keypress
			if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
				e.preventDefault();
			}
		});

		$("#raio-metros").keyup(function (e) {
			//if ($("#alvo_circle")[0] && alvo_circle.className === "circle") {
			radioManual = true;
			mSelf.AlteraFormaSelecionadaCirculo(parseInt(this.value), true);
			radioManual = false;
			mapa.map.fitBounds(circulo.getBounds());
			//}
		});
	};

	mSelf.AcaoClickAlvo = function () {
		var L = ($('#alvo').outerWidth() - $('#alvo_options').outerWidth()) / 2;
		$('#alvo_options').css('left', L);
		$('#alvo_options').toggle();
	};

	mSelf.DesfazerForma = function (event) {
		if (mSelf.FormaSelecionada()) {
			mSelf.FormaSelecionada().Coordenadas = [];
			forma.forEach(function (item) {
				if (item.tipo === 'draw') {
					item.setMap(null);
				}
			});

			forma = forma.filter(function (item) {
				return item.tipo !== 'draw';
			});
			mSelf.Pesquisa("");
			mSelf.Medida("");
		}

		if (circulo && circulo.setMap) {
			circulo.setMap(null);
			circulo = null;
		}

		mSelf.Passagens().forEach(function (passagem, index, passagens) {
			if (passagem.Polyline) {
				passagem.Polyline.setMap(null);
				passagem.selected = false;
			}
		});

		mSelf.FormaSelecionada(null);

		$("#grid-controle-passagem").hide();
		$("#myGrid").show();
		vm.GetModulo("GridVeiculosViewModel").AlterarTituloGrid();
	};

	mSelf.AlvoPlotarForma = function (event) {
		var tpAlvo = $("#alvo_active svg").attr("id");
		if (tpAlvo) {
			switch (tpAlvo) {
				case 'svgPoligono': {
					mSelf.AlteraFormaSelecionadaPoligono();
					break;
				}
			}
			mSelf.PlotarForma(tpAlvo);

			if (!$("#busca-raio").is(":visible"))
				$("#busca-raio").show();
		}
	};

	mSelf.AlteraFormaSelecionadaCirculo = function (raio, naoalterarcentro) {
		var pos1 = mSelf.CalculaPixelsToLatLng(27, -27);
		var pos2 = mSelf.CalculaPixelsToLatLng(-27, 27);
		if (!raio) raio = google.maps.geometry.spherical.computeDistanceBetween(pos1, pos2);

		var center = null;
		if (naoalterarcentro) {
			if (circulo) {
				if (circulo && circulo.getCenter)
					center = circulo.getCenter();
				else
					center = mSelf.CalculaPixelsToLatLng(0, 0);
			} else
				center = mSelf.CalculaPixelsToLatLng(0, 0);
		}
		else
			center = mSelf.CalculaPixelsToLatLng(0, 0);

		if (circulo && circulo.setMap) circulo.setMap(null);
		circulo = new google.maps.Circle({
			strokeColor: '#FF0000',
			strokeOpacity: 0.8,
			strokeWeight: 2,
			fillColor: '#FF0000',
			fillOpacity: 0.35,
			map: mapa.map,
			zIndex: 2,
			center: center,
			radius: raio,
			suppressUndo: true,
			editable: true,
			draggable: true
		});

		//mSelf.Pesquisa(circulo.getCenter().lat() + " - " + circulo.getCenter().lng());
		if (!radioManual) mSelf.Medida(raio.toFixed(2));

		google.maps.event.clearListeners(mapa.map, 'click');
		google.maps.event.clearListeners(circulo, 'center_changed');
		google.maps.event.addListener(circulo, 'center_changed', function (a, pos) {
			//mSelf.Pesquisa(circulo.getCenter().lat() + " - " + circulo.getCenter().lng());
		});
		google.maps.event.clearListeners(circulo, 'radius_changed');
		google.maps.event.addListener(circulo, 'radius_changed', function (a, pos) {
			if (!radioManual) {
				mSelf.Medida(circulo.radius.toFixed(2));
				mapa.map.fitBounds(circulo.getBounds());
			}
		});
	};

	mSelf.AlteraFormaSelecionadaPoligono = function () {

		var pos1 = mSelf.CalculaPixelsToLatLng(+75, -75);
		var pos2 = mSelf.CalculaPixelsToLatLng(-75, -75);
		var pos3 = mSelf.CalculaPixelsToLatLng(-75, +75);
		var pos4 = mSelf.CalculaPixelsToLatLng(+75, +75);

		if (!mSelf.FormaSelecionada()) {
			mSelf.FormaSelecionada({ Coordenadas: [] });
		}

		mSelf.FormaSelecionada().Coordenadas.push({ Latitude: pos1.lat(), Longitude: pos1.lng() });
		mSelf.FormaSelecionada().Coordenadas.push({ Latitude: pos2.lat(), Longitude: pos2.lng() });
		mSelf.FormaSelecionada().Coordenadas.push({ Latitude: pos3.lat(), Longitude: pos3.lng() });
		mSelf.FormaSelecionada().Coordenadas.push({ Latitude: pos4.lat(), Longitude: pos4.lng() });

		google.maps.event.clearListeners(mapa.map, 'click');
	};

	vm.obterEndereco = function (lat, lng) {
		var lat = lat / 1000000;
		var lng = lng / 1000000;
		var latLng = new google.maps.LatLng(lat, lng);
		var view = event.target;

		return mapa.EfetuarBuscaGeoCodeReversoGenerico(latLng)
			.then(function (result) {
				view.innerText = result;
				view.style.color = 'initial';
				view.style.textDecoration = 'none';
			})
			.catch(function (reason) {
				console.log(reason);
			});
	};

	vm.navegarInfoWindowFrente = function () {
		index++;

		mapa.infoWindowPolylineSelecionada.setContent(montarInfoWindow());
		mapa.infoWindowPolylineSelecionada.setPosition(polylineSelecionado.Polyline.getPath().getAt(index));
		mapa.infoWindowPolylineSelecionada.open(mapa.map);

		if (index - 1 !== 0 && index < polylineSelecionado.Polyline.getPath().getLength())
			mapa.PolylineHighlight.setPath([polylineSelecionado.Polyline.getPath().getArray()[index], polylineSelecionado.Polyline.getPath().getArray()[index - 1]]);
	};

	vm.navegarInfoWindowTras = function (direcao) {
		index--;

		mapa.infoWindowPolylineSelecionada.setContent(montarInfoWindow());
		mapa.infoWindowPolylineSelecionada.setPosition(polylineSelecionado.Polyline.getPath().getAt(index));
		mapa.infoWindowPolylineSelecionada.open(mapa.map);

		mapa.PolylineHighlight.setPath([polylineSelecionado.Polyline.getPath().getArray()[index], polylineSelecionado.Polyline.getPath().getArray()[index + 1]]);
	};

	function montarInfoWindow() {

		var content = polylineSelecionado.Historico[index];

		var elemento = '\
				<div style="width: 210px;  margin-top: 10px;">\
					<span style="display: inline-block; width: 100px; text-align: right; margin-top: 5px;">Data:</span> <span style="font-weight: bold;">{Data}</span><br />\
					<span style="display: inline-block; width: 100px; text-align: right; margin-top: 5px;">Hora:</span> <span style="font-weight: bold;">{Hora}</span><br />\
					<span style="display: inline-block; width: 100px; text-align: right; margin-top: 5px;">Velocidade:</span> <span style="font-weight: bold;">{Velocidade} Km/h</span><br />\
					<span style="display: inline-block; width: 100px; text-align: right; margin-top: 5px;">Endereço:</span> <span style="font-weight: bold; color: #4da5d1; text-decoration: underline;" onClick="vm.obterEndereco({lat}, {lng})">{Endereco}</span><br />\
					<p>\
						<button onClick="vm.navegarInfoWindowTras()" style="margin-top: 10px; padding: 4px 7px !important;" ' + (index === 0 ? 'disabled' : '') + ' type="button" class="btn btn-default btn-sm pull-left">\
							<i style="vertical-align: text-top;" class="text-primary glyphicon glyphicon-chevron-left"></i></button>\
						<button onClick="vm.navegarInfoWindowFrente()" style="margin-top: 10px; padding: 4px 7px !important;" ' + (index === polylineSelecionado.Polyline.getPath().getLength() - 1 ? 'disabled' : '') + ' type="button" class="btn btn-default btn-sm pull-right">\
							<i style="vertical-align: text-top;" class="text-primary glyphicon glyphicon-chevron-right"></i></button>\
					</p>\
				</div>';

		//elemento = elemento.replace("{Hora}", new Date(content.dataHora).toLocaleTimeString().slice(0, 5));
		elemento = elemento.replace("{Data}", new Date(content.dataHora).toLocaleDateString());
		elemento = elemento.replace("{Hora}", content.dataHora.slice(11, 19));
		elemento = elemento.replace("{Velocidade}", content.velocidade);
		elemento = elemento.replace("{lat}", content.latitude);
		elemento = elemento.replace("{lng}", content.longitude);
		elemento = elemento.replace("{Endereco}", 'Ver endereço');

		return elemento;
	}


	function eventKeyDownPress(e) {

		var code = (e.keyCode ? e.keyCode : e.which);

		if (polylineSelecionado && polylineSelecionado.length !== 0) {
			if (code === 39 && index < polylineSelecionado.Polyline.getPath().getLength() - 1) // Left
				vm.navegarInfoWindowFrente();
			else if (code === 37 && index > 0) // Right
				vm.navegarInfoWindowTras();
		}
	}

	vm.abrirHistorico = function (passagemData, e, fromMap) {

		google.maps.event.addListener(mapa.infoWindowPolylineSelecionada, 'closeclick', function () {
			mapa.PolylineHighlight.setMap(null);
			mapa.infoWindowPolylineSelecionada.open(null);
		});

		polylineSelecionado = passagemData;

		//remover evento de key up

		google.maps.event.clearListeners(document, 'keydown', eventKeyDownPress)
		mapa.PolylineHighlight.setMap(null);
		mapa.infoWindowPolylineSelecionada.open(null);
		google.maps.event.clearListeners(polylineSelecionado.Polyline, 'click');
		google.maps.event.addListener(polylineSelecionado.Polyline, 'click', function (event, dados) {

			var latlng = event.latLng;
			var minDistance = Number.MAX_VALUE;

			index = mapa.verificarIdx(this, event.latLng);

			if (mapa.PolylineHighlight) mapa.PolylineHighlight.setMap(null);
			mapa.PolylineHighlight = new google.maps.Polyline({
				strokeColor: 'yellow',
				strokeOpacity: 1.0,
				zIndex: 99,
				path: [this.getPath().getAt(index), this.getPath().getAt(index + 1)]
			});
			mapa.PolylineHighlight.setMap(mapa.map);

			google.maps.event.addDomListener(document, 'keydown', eventKeyDownPress);

			mapa.infoWindowPolylineSelecionada.setContent(montarInfoWindow());
			mapa.infoWindowPolylineSelecionada.setPosition(this.getPath().getAt(index));
			mapa.infoWindowPolylineSelecionada.open(mapa.map);
		});

		var idx = mSelf.Passagens().indexOf(passagemData);

		mSelf.Passagens().forEach(function (item) {
			item.Historico.forEach(function (historico) {
				if (historico.pontoParada) historico.pontoParada.setMap(null);
			});
		});

		mSelf.InfoWindowpontoParada.setMap(null);

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

		for (var i = 0; i < passagemData.Historico.length; i++) {
			//passagemData.Historico[i].DataHora = new Date(passagemData.Historico[i].DataHora).toLocaleString()
			passagemData.Historico[i] = toCamel(passagemData.Historico[i]);
		}

		if (passagemData.selected && !fromMap) {
			mSelf.Passagens().forEach(function (passagem, index, passagens) {
				passagem.Historico.forEach(function (historico) {
					if (historico.pontoParada)
						historico.pontoParada.setMap(null);
				});
				if (passagem.Polyline) {
					google.maps.event.clearListeners(passagem.Polyline, 'click');
					passagem.Polyline.setOptions({ strokeColor: passagem.Polyline.strokeColorDefault });
					passagem.Polyline.setOptions({ icons: [] });
					passagem.Polyline.setOptions({ zIndex: 3 });
					passagem.Polyline.setMap(mapa.map);

					passagem.selected = false;
					var points = passagem.Polyline.getPath().getArray();
					for (var n = 0; n < points.length; n++) {
						bounds.extend(points[n]);
					}

					google.maps.event.addListener(passagem.Polyline, 'click', function (event, passagem) {
						var poly = this;
						var fromMap = true;
						var pai = mSelf.Passagens().find(function (item, index) { return item.Polyline.index === poly.index });
						vm.abrirHistorico(pai, event, fromMap);
					});
				}
			});
			mapa.map.fitBounds(bounds);

			//$("#detalhes-passagem-" + idx).hide();
			$("#detalhes-passagem-" + idx).prev().removeClass('linha-selecionada');
		} else {
			mSelf.Passagens().forEach(function (passagem, index, passagens) {
				//$("#detalhes-passagem-" + index).hide();
				if (passagem.Polyline) {
					passagem.Polyline.setMap(null);
					passagem.selected = false;
				}
				passagem.Historico.forEach(function (historico) {
					if (historico.pontoParada)
						historico.pontoParada.setMap(null);
				});
			});

			var points = passagemData.Polyline.getPath().getArray();

			for (var n = 0; n < points.length; n++) {
				var infoWindowData = {}

				for (var n = 0; n < points.length; n++) {
					var infoWindowData = {};
					points[n].InfoWindow = '';

					for (var prop in passagemData.Historico[n]) {
						if (passagemData.Historico[n].hasOwnProperty(prop)) {
							points[n][prop] = passagemData.Historico[n][prop];
							if (prop == 'dataHora' || prop == 'velocidade' || prop == 'latitude' || prop == 'longitude' || prop == 'apontamento') {
								infoWindowData[prop] = passagemData.Historico[n][prop];
							}
						}
					}

					//points[n].InfoWindow = montarInfoWindow(infoWindowData);
					bounds.extend(points[n]);
				}
			}

			mapa.map.fitBounds(bounds);
			passagemData.Polyline.setOptions({ strokeColor: "#000000" });
			passagemData.Polyline.setOptions({ zIndex: 3 });
			passagemData.Polyline.setOptions({
				icons: [{
					icon: {
						size: new google.maps.Size(20, 20),
						scaledSize: new google.maps.Size(20, 20),
						path: google.maps.SymbolPath.FORWARD_OPEN_ARROW
					},
					offset: '90%',
					repeat: '20%'
				},
				{ icon: { path: google.maps.SymbolPath.FORWARD_OPEN_ARROW }, offset: '0%' },
				{ icon: { path: google.maps.SymbolPath.FORWARD_OPEN_ARROW }, offset: '100%' }]
			});
			passagemData.Polyline.setMap(mapa.map);
			passagemData.Historico.forEach(function (historico, index) {
				if (historico.parado) {
					var proximoHistorico = passagemData.Historico[index + 1];
					if (proximoHistorico) {
						if (!historico.pontoParada) {
						
							historico.pontoParada = new google.maps.Marker({
								position: new google.maps.LatLng(historico.latitude / 1000000, historico.longitude / 1000000),
								icon: urlGlobal + 'Content/Setores/Images/pp.png'
							});

							historico.infoWindow = {};

							historico.infoWindow.DataHoraInicio = new Date(historico.dataHora).toLocaleString();

							historico.infoWindow.DataHoraFim = new Date(proximoHistorico.dataHora).toLocaleString();

							historico.infoWindow.TempoParado = mSelf.CalculaTempo(new Date(historico.dataHora), new Date(proximoHistorico.dataHora));

							historico.pontoParada.infoWindow = mSelf.MontarInfoWindowpontoParada(historico.infoWindow);

							google.maps.event.addListener(historico.pontoParada, 'click', function () {
								mSelf.InfoWindowpontoParada.setPosition(historico.pontoParada.getPosition());
								mSelf.InfoWindowpontoParada.setContent(historico.pontoParada.infoWindow);
								mSelf.InfoWindowpontoParada.open(mapa.map);
							});
						}
						historico.pontoParada.setMap(mapa.map);
					}
				}
			});
			mapa.map.fitBounds(bounds);
			passagemData.selected = true;
			//$("#detalhes-passagem-" + idx).show();
			$("#grid-controle-passagem").find('.linha-selecionada').removeClass('linha-selecionada');
			$("#detalhes-passagem-" + idx).prev().addClass('linha-selecionada');
			$('#tbodyControlePassagem').scrollTop(0);
			$('#tbodyControlePassagem').scrollTop($('.linha-selecionada').position().top - $('#tbodyControlePassagem').position().top);

			if (!passagemData.Detalhes) {
				//var param = {
				//    'veiculo': passagemData.Veiculo,
				//    'dataInicio': passagemData.DataInicio,
				//    'dataFim': passagemData.DataFim
				//};

				//$.ajax({
				//    url: urlGlobal + "Veiculos/Veiculos/BuscarDetalhesPassagem",
				//    contentType: 'application/json; charset=utf-8',
				//    dataType: "json",
				//    type: "GET",
				//    data: param,
				//    success: function (result) {
				//        if (result) {
				//            passagemData.Detalhes = result;
				//            $("#cp-operacao-" + idx).text(result.Operacao);
				//            $("#cp-linha-" + idx).text(result.Linha);
				//            $("#cp-motorista-" + idx).text(result.Motorista);
				//        } else {
				//            var notFound = "Não encontrado";
				//            $("#cp-operacao-" + idx).text(notFound);
				//            $("#cp-linha-" + idx).text(notFound);
				//            $("#cp-motorista-" + idx).text(notFound);
				//        }
				//    },
				//    complete: function () {
				//    }
				//});
			}
		}
	};

	mSelf.PlotarForma = function (tpAlvo) {
		var polygonForma = null;
		switch (tpAlvo) {
			case 'svgCirculo': {
				mSelf.AlteraFormaSelecionadaCirculo(150, false);
				break;
			}
			case 'svgPoligono': {
				pts = [];
				for (j = 0; j < mSelf.FormaSelecionada().Coordenadas.length; j++) {
					ptAux = new google.maps.LatLng(mSelf.FormaSelecionada().Coordenadas[j].Latitude, mSelf.FormaSelecionada().Coordenadas[j].Longitude, false);
					pts.push(ptAux);
				}

				objetoForma = {
					strokeColor: '#FF0000',
					strokeOpacity: 0.8,
					strokeWeight: 2,
					fillColor: '#FF0000',
					fillOpacity: 0.35,
					zIndex: 1,
					paths: pts,
					tipo: 'draw',
					map: mapa.map,
					editable: true,
					suppressUndo: true,
					draggable: true
				};

				polygonForma = new google.maps.Polygon(objetoForma);
				forma.push(polygonForma);

				var areaPoligono = google.maps.geometry.spherical.computeArea(pts);
				mSelf.Medida((areaPoligono / 1000).toFixed(2));
				//$("#raio-metros")[0].disabled = true;
				break;
			}
		}

		if (polygonForma) {
			google.maps.event.clearListeners(mapa.map, 'set_at');
			google.maps.event.addListener(polygonForma.getPath(), 'set_at', function (a, pos) {
				//mSelf.Pesquisa(pos.lat() + " - " + pos.lng());
				var areaPoligono = google.maps.geometry.spherical.computeArea(this);
				mSelf.Medida((areaPoligono / 1000).toFixed(2));
				//$("#raio-metros")[0].disabled = true;

				var coordenadas = [];
				this.getArray().forEach(function (data) {
					coordenadas.push({ Latitude: data.lat(), Longitude: data.lng() });
				});
				mSelf.FormaSelecionada({ Coordenadas: coordenadas });
			});
			google.maps.event.clearListeners(polygonForma, 'insert_at');
			google.maps.event.addListener(polygonForma.getPath(), 'insert_at', function (a, pos) {
				var areaPoligono = google.maps.geometry.spherical.computeArea(this);
				mSelf.Medida((areaPoligono / 1000).toFixed(2));
				//$("#raio-metros")[0].disabled = true;
				pos = this.b[a];
				//mSelf.Pesquisa(pos.lat() + " - " + pos.lng());

				var coordenadas = [];
				this.getArray().forEach(function (data) {
					coordenadas.push({ Latitude: data.lat(), Longitude: data.lng() });
				});
				mSelf.FormaSelecionada({ Coordenadas: coordenadas });
			});
		}
	};

	function getRandomColor() {
		var letters = '0123456789ABCDEF';
		var color = '#';
		for (var i = 0; i < 6; i++) {
			color += letters[Math.floor(Math.random() * 16)];
		}
		return color;
	}

	mSelf.Cancelar = function () {
		mapa.PolylineHighlight.setMap(null);
		mapa.infoWindowPolylineSelecionada.open(null);
		vm.Perspectiva.AlvoViewModel(false);
		$("#grid-controle-passagem").hide();
		// $("#myGrid").show();
		vm.GetModulo("GridVeiculosViewModel").AlterarTituloGrid();
		mSelf.ChangeOpcaoBusca();
		mSelf.Passagens().forEach(function (passagem, index, passagens) {
			if (passagem.Polyline) {
				passagem.Polyline.setMap(null);
				passagem.selected = false;
			}
			passagem.Historico.forEach(function (historico) {
				if (historico.pontoParada)
					historico.pontoParada.setMap(null);
			});
		});
		mSelf.Passagens([]);

		if (vm.GetFerramenta("NovoFiltroVeiculos"))
			vm.GetFerramenta("NovoFiltroVeiculos").Visivel(true);

		mSelf.Minimizado = false;
	}

	mSelf.Minimizar = function () {
		mSelf.Minimizado = true;
	}

	mSelf.AbrirRelatorio = function (data, ev) {
		data.Historico.forEach(function (item) { delete item.infoWindow; delete item.pontoParada; });
		ev.stopPropagation();
		$.ajax({
			url: urlGlobal + "Veiculos/Veiculos/CarregaHistorico",
			contentType: 'application/json; charset=utf-8',
			dataType: "json",
			type: "POST",
			data: JSON.stringify(data.Historico),
			success: function (result) {
				window.open(urlGlobal + "Veiculos/Veiculos/RelatorioControlePassagem", "_blank");
			},
			complete: function () {
			}
		});
	}
}