﻿var map;
var GGeo;
var RGeo1; //para geocode
var RGeo2; //para Ponto A  do traçar rota
var RGeoFrom;
var RGeoTo;
var GDir;
var allowGeocode = true;
var currentMapCenter;
var fromMarker, toMarker = null;
var placeMarker;
var stepMarkers = []; //array de marcadores dos passos
var stepMarkersHtml = []; //array com HTML de cada marcador

function GLoad() {
	if (GBrowserIsCompatible()) {
		map = new GMap2($('map'), {backgroundColor: '#f7f7f7'});
		
		//cria div para exibir a rota
		var divGDir = document.createElement('div');
		divGDir.id = 'divGDir';

		//instancia GDirections e GGeocoder
		GDir = new GDirections(map, divGDir);		
		GGeo = new GClientGeocoder();		
		
		//Verifica se veio da barra do google
		if (queryString('endereco')) {
			GGeo.geocodeAddress(queryString('endereco'));
		}
		//verifica se veio de um link direto
		else if (queryString('lat') && queryString('lng') && queryString('zoom')) {
			var centerFromQs = new GLatLng(queryString('lat'), queryString('lng'));
		   map.setCenter(centerFromQs, parseInt(queryString('zoom'), 10));
			
			var linkMarker = new GMarker(centerFromQs);
			map.addOverlay(linkMarker);
			
			linkMarker.openInfoWindowHtml('Esse ponto foi marcado para você!');
		}
		else {
		   map.setCenter(map.myLatLng(), 12);
      }

		
		GEvent.addListener(GDir, 'addoverlay', function(){
			replaceGDirMarkers();
		});
		GEvent.addListener(GDir,'load',function(){
			map.clearAll();
			//se incrementar <p>, depois incrementar <button />, depois incrementar </p>, buga css
			$('anexo').innerHTML += '<div style="border: 1px solid #c0c0c0; background: #eee; text-align: center; margin: 5px 5px 0px 5px;">'
										 + '<p><input type="button" id="btnInvert" class="routeBtn" value="" title="Inverter Rota" alt="Inverter Rota" onclick="invertRoute();" />'
										 + '<input type="button" id="btnStep" class="routeBtn" value="" title="Passo-a-passo" title="Passo-a-passo" onclick="GDir.changeStep(true, -1);" />'
										 + '<input type="button" id="btnMail" class="routeBtn" value="" title="Enviar rota" onclick="showLightbox(true); return false;" /></p></div>';
			$('anexo').appendChild(divGDir);
			GDir.formatRouteSteps();
		});
		GEvent.addListener(GDir,'error',handleErrors);
		
		//captura centro do mapa
		GEvent.addListener(map,'movestart',function(){currentMapCenter = map.getCenter();});
		
		GEvent.addListener(map, 'dblclick', function(overlay, clickLatLng) {
			//resgata centro do movestart e impede movimento do mapa
			map.setCenter(currentMapCenter);

			//INSERE MARCADORES NO CLIQUE DUPLO
			var fromIcon = new GIcon(G_DEFAULT_ICON);
			var toIcon = new GIcon(G_DEFAULT_ICON);
			fromIcon.image = 'http://www.zlink.com.br/images/markers/marker_route_from.png';
			toIcon.image = 'http://www.zlink.com.br/images/markers/marker_route_to.png';

			//se houver partida e não houver destino, insere destino e traça rota entre ambos
			if (fromMarker && !toMarker) {
				toMarker = new GMarker(clickLatLng, {icon: toIcon, draggable: true, bounceGravity: 2});
				map.addOverlay(toMarker);
				if (fromMarker.getLatLng() != toMarker.getLatLng()) {
					startLoading('Aguarde, traçando rota...', 2000);
					GDir.loadFromWaypoints([fromMarker.getLatLng(), toMarker.getLatLng()], {locale: 'pt_BR'});
				}
				else {alert('Por favor, informe dois pontos distintos para traçar uma rota entre eles.');}
			}
			//se não houver marcadores, insere partida
			else if (!fromMarker && !toMarker) {
				fromMarker = new GMarker(clickLatLng, {icon: fromIcon, draggable: true, bounceGravity: 2});
				map.addOverlay(fromMarker);
				fromMarker.openInfoWindowHtml('<label><span style="color: green;">Dica:</span> com um novo clique duplo em outro ponto, você traça uma rota!&nbsp;&nbsp;&nbsp;</label>');
				startLoading('Aguarde, localizando endereço...', 2000);
				RGeo2.reverseGeocode(fromMarker.getLatLng());
				
				GEvent.addListener(fromMarker, 'dragend', function(){
					map.removeOverlay(this.tooltip);
					this.tooltip = null;
					startLoading('Aguarde, localizando endereço...', 2000);
					RGeo2.reverseGeocode(this.getLatLng());
				});
				GEvent.addListener(fromMarker, 'drag', function(){
					map.removeOverlay(this.tooltip);
					map.addOverlay(this.tooltip);
					this.tooltip.show();
				});
			}
		});
		
		//habilita navegação por teclado
		var keyboard = new GKeyboardHandler(map);

		//reverse geocoding
		RGeo1 = new GReverseGeocoder(map);
		GEvent.addListener(RGeo1,'load',function(x){
		//bindar antes de abrir o infoWindow
			if (placeMarker) {
				map.panTo(placeMarker.getLatLng());
				placeMarker.bindInfoWindowHtml(html1(x.address));
				placeMarker.openInfoWindowHtml(html1(x.address));
				//se arrastar marcador, remove a div com textarea + link do anexo
				if ($('divLinkHtml')) {$('anexo').removeChild($('divLinkHtml'));}
			}
			else {
				GGeo.geocodeAddress(x.address + ' 1');
			}
		});
		GEvent.addListener(RGeo1,'error',function(x){
			if (placeMarker) {
				var html = '<form action="#" onsubmit="GGeo.geocodeAddress($(\'txtInfoWindow\').value); return false;">'
				+ '<p>Localidade desconhecida.</p><br />'
				+ '<p>Tente outro endereço:</p>'
				+ '<p style="margin-top: 5px;"><input type="text" id="txtInfoWindow" /><input type="submit" value="Localizar" /></p></form>';
				placeMarker.bindInfoWindowHtml(html);
				placeMarker.openInfoWindowHtml(html);
			}
		});
		
		RGeo2 = new GReverseGeocoder(map);
		GEvent.addListener(RGeo2, 'load', function(x) {
			if (fromMarker) {
				var tp = new Tooltip(fromMarker,'Partida: ' + x.address,4);
				fromMarker.tooltip = tp;
				map.addOverlay(tp);
				fromMarker.tooltip.show();
				map.panTo(fromMarker.getLatLng());
				showDivRoute();
				$('fromRoute').value = x.address;
				$('toRoute').focus();
			}
		});
		
		GEvent.addListener(RGeo2, 'error', function(x) {
			if (fromMarker) {
				fromMarker.tooltip = null;
				map.removeOverlay(fromMarker);
				fromMarker = null;
				alert('Endereço não localizado.');
			}
		});

		RGeoFrom = new GReverseGeocoder(map);
		GEvent.addListener(RGeoFrom, 'load', function(x) {
				$('route_a').src = 'http://www.zlink.com.br/images/t_marker_route_a.gif';
				$('fromRoute').value = x.address;
		});
		
		RGeoTo = new GReverseGeocoder(map);
		GEvent.addListener(RGeoTo, 'load', function(x) {
			$('route_b').src = 'http://www.zlink.com.br/images/t_marker_route_b.gif';
			$('toRoute').value = x.address;
		});
		
		//corrige o bug ao localizar endereço durante o zoom
		GEvent.addListener(map, 'zoomstart', function(){allowGeocode = false;});
		GEvent.addListener(map, 'zoomend', function(){allowGeocode = true;});

		//propriedades iniciais
		//map.enableContinuousZoom(); //memory leak
		map.enableScrollWheelZoom();
		map.disableDoubleClickZoom();
		
		map.addControl(new GMapTypeControl()); //maptype
		map.addControl(new GLargeMapControl()); //zoom
		map.addControl(new GScaleControl(200)); //scale
		map.addControl(new GOverviewMapControl()); //minimap
		
		
		//-------- não faz parte dos mapas, mas inicia no page load
		//não setta valor inicial se já houver algo digitado
		if (!$('addressToGeocode').value) {
			$('addressToGeocode').value = getStartValue();
			$('addressToGeocode').focus();
			setCursorPosition($('addressToGeocode'), 0);
		}
		$('addressToGeocode').onkeyup = function(){copyAddress(this);};
		
		$('fGeocode').onsubmit = function(){
			if ($('addressToGeocode').value != null) {
				GGeo.geocodeAddress($('addressToGeocode').value); }
			else {alert('Insira um endereço para realizar a busca.');}
			return false;
		}
		
		$('lnkShowDivRoute').onclick = function(){showDivRoute();return false;}
		$('lnkClearMap').onclick = function(){map.clearAll();return false;}
		$('lnkHelp').onclick = function(){showHelp();return false;}
		
		$('lnkSendMail').onclick = function(){showLightbox(true);return false;}
		$('lnkLink').onclick = function(){getLink();return false;}
		
		showDivRoute();
		
		var exemplo = document.getElementById('lblAddressToGeocode');
		var myCity = geoip_city();
		if (myCity == 'Santos' || myCity == 'Sao Vicente' || myCity == 'Guaruja' || myCity == 'Cubatao' || myCity == 'Praia Grande') {
			exemplo.innerHTML = 'Exemplo: Av. Conselheiro Nébias, 532 - Santos - SP';
		}
		else {
			exemplo.innerHTML = 'Exemplo: Av. Epitácio Pessoa, 10 - Centro, João Pessoa - PB';
		}
	}
	else{document.write('Seu navegador não é compatível com o serviço de mapas oferecido pelo Guia de Ruas. Por favor, atualize sua versão.');}
}

//inicia o geocode do endereço, chama geocodeAddressCallback() para resposta
GClientGeocoder.prototype.geocodeAddress = function(address) {
	if (GGeo && allowGeocode) {
		if (address) {
			startLoading('Aguarde, localizando endereço...', 1500);
			GGeo.setBaseCountryCode('br');
			GGeo.getLocations(address, geocodeAddressCallback);
		}
		else {alert('É necessário informar um endereço para realizar a consulta.');}
	}
	else {
		alert('O serviço de mapas ainda não está pronto. Por favor, aguarde alguns instantes ou tente recarregar a página.');
		return false;
	}
}

//pega a resposta do geocode, verifica múltiplos endereços, mostra resultados no mapa
function geocodeAddressCallback(response) {
	if (response.Placemark && response.Status.code == 200) {
		map.clearAll();
		var place = response.Placemark;
		var results = place.length;
		
		var divGeocode = document.createElement('div');
		divGeocode.id = 'divGeocode';
		divGeocode.style.padding = '10px';
		$('anexo').appendChild(divGeocode);

		var resultsToCompare = [];
		var resultsLatLng = [];

		//se encontrou resultados semelhantes, trata resposta
		if (results > 1) {
			var tooltip,addressLatLng = null;
			var markerIcon = new GIcon(G_DEFAULT_ICON);
			markers = [];
			var bounds = new GLatLngBounds();

			divGeocode.innerHTML = '<p style="color: red; font-style: italic; padding-bottom: 10px; font-weight: bold;">Você quis dizer...</p>';
			for (var i=0; i < results; i++) {
				addressLatLng = new GLatLng(place[i].Point.coordinates[1], place[i].Point.coordinates[0]);
				bounds.extend(addressLatLng);

				markerIcon.image = 'http://www.zlink.com.br/images/markers/marker_geocode_'+i+'.png';
				
				var marker = new GMarker(addressLatLng, {icon: markerIcon}); //settar GLOBAL se necessário
				map.addOverlay(marker);
				//não recupera o valor correto de i, tive que fazer callback para criar o evento
				markerListenersCallback(i,place,marker);
                   
                markers.push(marker);
				tooltip = new Tooltip(marker,place[i].address,4);
				marker.tooltip = tooltip;
				map.addOverlay(tooltip);
				
				//NÃO CONSEGUI ALTERAR O EVENTO ONCLICK DINAMICAMENTE NO CASO DE HAVER RESULTADOS DUPLICADOS COM STRING IDÊNTICA
				//POR ISSO USEI JS NO HREF
                divGeocode.innerHTML += '<a href="javascript:GGeo.geocodeAddress(\''+place[i].address+'\');" '
				                      + 'id="geo'+i+'" '
				                      + 'class="mGeocode" '
				                      + 'style="background: url(http://www.zlink.com.br/images/t_geocode_'+i+'.gif) no-repeat left center;" '
				                      + 'title="Clique para visualizar o endereço">'+place[i].address+'</a>';
				                      
				//popula os arrays de duplicações idênticas
				resultsToCompare[i] = place[i].address;
				resultsLatLng[i] = place[i].Point.coordinates[1]+ ','+ place[i].Point.coordinates[0];
			}
			
			//se houver resultados duplicados com string idêntica
			//altera o href para fazer reverseGeocode
			for (var x = 0; x < resultsToCompare.length; x++) {
				if (resultsToCompare.find(resultsToCompare[x]) && resultsToCompare.find(resultsToCompare[x]).length > 1) {
					$('geo'+x).href = 'javascript:RGeo1.reverseGeocode(new GLatLng('+resultsLatLng[x]+'));';
				}
			}
			divGeocode.innerHTML += '<p style="padding-top: 10px;">Foram encontrados <span style="font-weight: bold;">' + results + '</span> resultados semelhantes. Selecione o mais adequado.</p>';
			map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
		}

		//se é um resultado único, insere marcador
		else {
			if(tooltip){map.removeOverlay(tooltip);}
			
			//coordinates passa lng[1], lat[0], alt[2]
			var placePoint = new GLatLng(place[0].Point.coordinates[1], place[0].Point.coordinates[0]);
			
			//MARKER GLOBAL para ser capturado em outras functions
			//faz novo geocode no dragend
			placeMarker = new GMarker(placePoint, {draggable:true});
			
			//setta texto do input principal
			$('addressToGeocode').value = place[0].address;
			
			//setta o nível de zoom de acordo com o resultado
			var accuracyZoomLevel;
			switch (place[0].AddressDetails.Accuracy) {
				case 1: accuracyZoomLevel = 4; break; //país
				case 2: accuracyZoomLevel = 5; break; //estado
				case 3: case 4: accuracyZoomLevel = 12; break; //cidade
				case 5: case 6: case 7: case 8: case 9: accuracyZoomLevel = 15; break; //maior que cidade
				default: accuracyZoomLevel = 10; break; //outros
			}
			
			//centraliza o mapa e insere marcador
			map.setCenter(placePoint, accuracyZoomLevel);
			map.addOverlay(placeMarker);
			
			//abre a janela de informações da localidade (infos sobre o parâmetro nas functions)
			placeMarker.openInfoWindowHtml(html1(place[0].address));
			
			//binda o click do marcador para a infoWindowHtml
			placeMarker.bindInfoWindowHtml(html1(place[0].address));
	      
			showDivRoute();
			showDivLinkAnexo(place);
	      
			//se o input já tiver sido criado, foca e setta value para getStartValue()
			GEvent.addListener(placeMarker, 'infowindowopen', function() {
				var txt = $('txtInfoWindow');
				if(txt){
					txt.focus();
					txt.value = getStartValue();
					setCursorPosition(txt, 0);
				}
			});
			
			//localiza endereço no dragend
			GEvent.addListener(placeMarker,'dragstart',function(){this.closeInfoWindow();});
			GEvent.addListener(placeMarker,'dragend',function(){
				RGeo1.reverseGeocode(this.getLatLng());
				startLoading('Aguarde, localizando endereço...', 1500);
			});
		}
		$('toRoute').value = place[0].address;
	}
	else {
		alert('Endereço não encontrado. Por favor, tente ser mais específico em sua consulta informando uma cidade ou estado.');
		return false;
	}
}

//por problemas de áspas na string e referência de variáveis,
//foi necessário criar html1() e html2() que dão o retorno do html
function html1(address) {
	var html1 = '<b>' + address + '</b>&nbsp;&nbsp;&nbsp;<br /><br />'
				+ 'Deseja traçar uma rota?<br />'
				+ '<a href="#" onclick="placeMarker.openInfoWindowHtml(html2(\''+address+'\',true)); return false;">Deste ponto</a> | '
				+ '<a href="#" onclick="placeMarker.openInfoWindowHtml(html2(\''+address+'\',false)); return false;">Até este ponto</a>'
				+ '<br /><label style="margin-top: 10px;"><span style="color: green;">Dica:</span> arraste o marcador para localizar novos endereços!<label>';
   return html1;
}

function html2(address, isFrom) {
	var from, to = null;
	if (isFrom) {from = 'destino'; to = 'partida';}
	else {from = 'partida'; to = 'destino';}
	var html2 = '<label for="endereco">Endereço de '+to+':</label>'
				+ '<p id="endereco" style="font-weight: bold;">' + address + '</p><br />'
				+ '<label for="txtInfoWindow">Endereço de '+from+':</label>';
				
	//de address para textbox
	if (isFrom) {
		html2 += '<form id="fInfoWindow" action="#" onsubmit="startLoading(\'Aguarde, traçando rota...\', 2000); GDir.loadFromWaypoints([\''+address+'\', $(\'txtInfoWindow\').value]); return false;">';
	}
	//de textbox para address
	else {
		html2 += '<form id="fInfoWindow" action="#" onsubmit="startLoading(\'Aguarde, traçando rota...\', 2000); GDir.loadFromWaypoints([$(\'txtInfoWindow\').value, \''+address+'\']); return false;">';
	}
	
	html2 += '<input type="text" id="txtInfoWindow" />'
			+ '<input type="submit" id="btnInfoWindow" value="Traçar rota" />'
			+ '</form><br />'
			+ '<a href="#" onclick="placeMarker.openInfoWindowHtml(html1(\''+address+'\')); return false;">Voltar</a>';
	return html2;
}

//callback para inserção dos eventos no multiple geocode
//setta os ícones de A a J nos marcadores
function markerListenersCallback(i,place,marker) {
	GEvent.addListener(marker, 'mouseover', function(){this.tooltip.show(); this.setImage('http://www.zlink.com.br/images/markers/marker_yellow.png');});
	GEvent.addListener(marker, 'mouseout', function(){this.tooltip.hide(); this.setImage('http://www.zlink.com.br/images/markers/marker_geocode_'+i+'.png');});
	GEvent.addListener(marker, 'click', function(){GGeo.geocodeAddress(place[i].address);});
}

//resgata coordenadas do IP
GMap2.prototype.myLatLng = function() {
	var myPosition;
	//se carregar maxmind
	if(geoip_latitude() && geoip_longitude()){myPosition = new GLatLng(geoip_latitude(), geoip_longitude());}
	//senão
	else{myPosition = new GLatLng(-23.9500, -46.3333);}
	return myPosition;
}

//retorna cidade + estado do usuário, já formatado
function getStartValue() {
	var myCity = geoip_city();
	var myUF = geoip_region_name();
	switch(myUF) {
		case 'Acre': myUF = 'AC'; break;
		case 'Alagoas': myUF = 'AL'; break;
		case 'Amapa': myUF = 'AP'; break;
		case 'Amazonas': myUF = 'AM'; break;
		case 'Bahia': myUF = 'BA'; break;
		case 'Ceara': myUF = 'CE'; break;
		case 'Distrito Federal': myUF = 'DF'; break;
		case 'Goias': myUF = 'GO'; break;
		case 'Espirito Santo': myUF = 'ES'; break;
		case 'Maranhao': myUF = 'MA'; break;
		case 'Mato Grosso': myUF = 'MT'; break;
		case 'Mato Grosso do Sul': myUF = 'MS'; break;
		case 'Minas Gerais': myUF = 'MG'; break;
		case 'Para': myUF = 'PA'; break;
		case 'Paraiba': myUF = 'PB'; break;
		case 'Parana': myUF = 'PR'; break;
		case 'Pernambuco': myUF = 'PE'; break;
		case 'Piaui': myUF = 'PI'; break;
		case 'Rio de Janeiro': myUF = 'RJ'; break;
		case 'Rio Grande do Norte': myUF = 'RN'; break;
		case 'Rio Grande do Sul': myUF = 'RS'; break;
		case 'Rondonia': myUF = 'RO'; break;
		case 'Roraima': myUF = 'RR'; break;
		case 'Sao Paulo': myUF = 'SP'; break;
		case 'Santa Catarina': myUF = 'SC'; break;
		case 'Sergipe': myUF = 'SE'; break;
		case 'Tocantins': myUF = 'TO'; break;
	}
	var startValue = ' - ' + myCity + ' - ' + myUF;
	return startValue;
}

//setta posição do cursor no input
function setCursorPosition(obj, pos) {
	if(obj.createTextRange) {
		var range = obj.createTextRange();
		range.move('character', 0);
		range.select();
   } else if(obj.selectionStart) {
		obj.setSelectionRange(pos, pos);
   }
   obj.focus();
}

function $(id){return document.getElementById(id);}
function key(tap){if(tap.keyCode==27||tap.which==27){placeMarker.closeInfoWindow();}}

var isLoading = false;
var loading = document.createElement('div');
function startLoading(msg, timeout) {
	var parent = $('map');
	isLoading = !(isLoading);
	loading.id = 'loadingMessage';
	loading.onselectstart=function(){return false;};
	loading.onmousedown=function(){return false;};
	
	if (isLoading) {
		parent.appendChild(loading);
		loading.innerHTML = '<img src="http://www.zlink.com.br/images/loading.gif" alt="Carregando..." />&nbsp;&nbsp;&nbsp;' + msg;
		loading.style.left = (parent.clientWidth / 2) - (loading.clientWidth / 2) + 'px';
		loading.style.top = (parent.clientHeight / 2) - (loading.clientHeight / 2) + 'px';
		setTimeout('startLoading()', timeout);
	}
	else {loading.parentNode.removeChild(loading);}
}

function handleErrors(){
	var errorCode = GDir.getStatus().code;
	var errorMessage;
	
	switch (errorCode) {
		case G_GEO_BAD_REQUEST:
			errorMessage = 'Não foi possível traçar uma rota entre os pontos informados. Por favor, tente detalhar melhor sua consulta informando uma cidade ou estado.';
		break;
		case G_GEO_SERVER_ERROR:
			errorMessage = 'Ocorreu um erro no servidor de mapas. Por favor, atualize a página e tente novamente.';
		break;
		case G_GEO_MISSING_QUERY:
			errorMessage = 'É necessário fornecer ao menos um endereço para realizar a consulta.';
		break;
		case G_GEO_MISSING_ADDRESS:
			errorMessage = 'É necessário fornecer ao menos um endereço para realizar a consulta.';
		break;
		case G_GEO_UNKNOWN_ADDRESS:
			errorMessage = 'Nenhuma localidade geográfica corresponde ao endereço informado.\nTalvez o endereço seja relativamente novo ou incorreto.\n\nSoluções:\nCorrija eventuais erros ou tente detalhar sua consulta informando uma cidade ou estado.';
		break;
		case G_GEO_UNAVAILABLE_ADDRESS:
			errorMessage = 'O endereço solicitado não pode ser consultado devido a razões legais ou contratuais.';
		break;
		case G_GEO_UNKNOWN_DIRECTIONS:
			errorMessage = 'Não é possível traçar uma rota entre os pontos informados.\nTalvez não exista uma rota disponível ou o endereço ainda não está cadastrado no sistema.';
		break;			
		case G_GEO_BAD_KEY:
			errorMessage = 'Erro fatal. Por favor, contate a administração do Guia de Ruas e informe o código do erro para que o serviço seja atualizado.';
		break;
		case G_GEO_TOO_MANY_QUERIES:
			errorMessage = 'O sistema de mapas encontra-se indisponível temporariamente. Por favor, retorne dentro de algumas horas.';
		default:
			errorMessage = 'Ocorreu um erro inesperado. Por favor, tente novamente.';
		break;
	}
	alert(errorMessage + '\n\nCódigo do erro: ' + errorCode);
	
	var fromRouteText = $('fromRoute').value;
	var toRouteText = $('toRoute').value;
	
	map.clearAll();
	showDivRoute();
	
	$('fromRoute').value = fromRouteText;
	$('toRoute').value = toRouteText;
	
	return false;
}

function replaceGDirMarkers() {
	//remove os marcadores antigos (draggable false)
	var oldFromMarker = GDir.getMarker(0);
	var oldToMarker = GDir.getMarker(1);
	map.removeOverlay(oldFromMarker);
	map.removeOverlay(oldToMarker);
	
	//insere os novos marcadores draggable
	var newFromMarker = new GMarker(GDir.getRoute(0).getStep(0).getLatLng(), {icon: oldFromMarker.getIcon(), draggable: true, bounceGravity: 2});
	var newToMarker = new GMarker(GDir.getRoute(0).getEndLatLng(), {icon: oldToMarker.getIcon(), draggable: true, bounceGravity: 2});
	map.addOverlay(newFromMarker);
	map.addOverlay(newToMarker);
	
	//implementa tooltips
	var markerFromTooltip = new Tooltip(newFromMarker, 'Partida: ' + GDir.getGeocode(0).address, 4);
	newFromMarker.tooltip = markerFromTooltip;
	map.addOverlay(markerFromTooltip);
	newFromMarker.tooltip.show();
	GEvent.addListener(newFromMarker, 'drag', function(){
		map.removeOverlay(this.tooltip);
		map.addOverlay(this.tooltip);
		this.tooltip.show();
	});
	
	var markerToTooltip = new Tooltip(newToMarker,'Destino: ' + GDir.getGeocode(1).address,4);
	newToMarker.tooltip = markerToTooltip;
	map.addOverlay(markerToTooltip);
	newToMarker.tooltip.show();
	GEvent.addListener(newToMarker, 'drag', function(){
		map.removeOverlay(this.tooltip);
		map.addOverlay(this.tooltip);
		this.tooltip.show();
	});
	
	//implementa traçar rota no dragend dos marcadores
	GEvent.addListener(newFromMarker, 'dragend', function() {
		startLoading('Aguarde, traçando rota...', 2000);
		GDir.loadFromWaypoints([newFromMarker.getLatLng(), newToMarker.getLatLng()]);
		this.tooltip = null;
	});
	GEvent.addListener(newToMarker, 'dragend', function() {
		startLoading('Aguarde, traçando rota...', 2000);
		GDir.loadFromWaypoints([newFromMarker.getLatLng(), newToMarker.getLatLng()]);
		this.tooltip = null;
	});
	
	oldFromMarker = null;
	oldToMarker = null;
}

GMap2.prototype.clearAll = function() {
	//não usar GDir.clear();
	GGeo.reset();
	map.clearOverlays();
	placeMarker = null;
	fromMarker = null;
	toMarker = null;
	stepMarkers = [];
	stepMarkersHtml = [];
	$('anexo').innerHTML = '';
}


setFocus = false; //controla o foco no onload da página
function showDivRoute() {
	var divRoute = document.createElement('div');
	divRoute.id = 'divRoute';
	divRoute.style.padding = '10px';
	if (!$('divRoute')) {
		var oldHtml = $('anexo').innerHTML;
		//$('anexo').innerHTML = '';
		$('anexo').appendChild(divRoute);
		
		divRoute.innerHTML = ''
			+ '<form id="fRoute" action="#">'
				+ '<p style="padding-bottom: 10px;">Informe os endereços de partida e destino para traçar uma rota entre eles:</p>'
				+ '<label>Não esqueça de informar a cidade!</label>'
				+ '<div class="route">'
				+	 '<img src="http://www.zlink.com.br/images/t_marker_route_a.gif" id="route_a" alt="Partida" />'
				+	 '<input type="text" tabindex="1" id="fromRoute" />'
				+	 '<label for="fromRoute">partida...</label>'
				+ '</div>'
				+ '<div class="route">'
				+	 '<img src="http://www.zlink.com.br/images/t_marker_route_b.gif" id="route_b" alt="Destino" />'
				+	 '<input type="text" tabindex="2" id="toRoute" />'
				+	 '<label for="toRoute">destino...</label>'
				+ '</div>'
				+ '<p><input type="submit" value="Traçar rota" /></p>'
				+ '<hr />'
			+ '</form>';
		$('anexo').innerHTML += oldHtml;
		$('fRoute').onsubmit = function(){
			if ($('fromRoute').value != '' && $('toRoute').value != '') {
				GDir.loadFromWaypoints([$('fromRoute').value, $('toRoute').value]);
			}
			else {alert('Insira os endereços de partida e destino.');}
			return false;
		};
		$('toRoute').onkeyup = function(){copyAddress(this);};
		
		//não dá foco no page load, apenas depois
		if (setFocus){setCursorPosition($('fromRoute'),0);}
		setFocus = true;
		
		//SE HOUVER alguma rota traçada, faz reverseGeocode()
		//para obter o endereço formatado do início e do fim da rota
		if (GDir.getStatus()) {
			if (GDir.getStatus().code == 200) {
				if (GDir.getGeocode(0).address != 'Via desconhecida') {
					$('route_a').src = 'http://www.zlink.com.br/images/loading_text.gif';
					RGeoFrom.reverseGeocode(GDir.getRoute(0).getStep(0).getLatLng());
				}
				else {$('fromRoute').value = 'Endereço não identificado!';}
				
				if (GDir.getGeocode(1).address != 'Via desconhecida') {
					$('route_b').src = 'http://www.zlink.com.br/images/loading_text.gif';
					RGeoTo.reverseGeocode(GDir.getRoute(0).getEndLatLng());
				}
				else {$('toRoute').value = 'Endereço não identificado!';}
			}
		}
	}
	else {
		setCursorPosition($('fromRoute'),0);
	}
}

function showDivLinkAnexo(place) {
	var random = Math.ceil(Math.random() * 3);
	var message;
	switch (random) {
		case 1: message = 'Guia de Ruas: '; break;
		case 2: message = 'Guia no mapa: '; break;
		case 3: message = 'Ver no mapa: '; break;
	}

	var zoom = map.getBoundsZoomLevel(map.getBounds());
	linkHtml = '<textarea rows="3" style="width: 280px;padding: 0px; margin: 0px;" onfocus="this.select();">'
				+ '<a href="http://www.zlink.com.br/?lat=' + place[0].Point.coordinates[1] + '&lng='+ place[0].Point.coordinates[0] + '&zoom='+zoom+'">'
				+ message + place[0].address + '</a></textarea>'
				+ '<label><span style="color: green;">Dica: </span>copie o código acima para divulgar essa localidade em sua página!</label>';

	var divLinkHtml = document.createElement('div');
	divLinkHtml.id = 'divLinkHtml';
	divLinkHtml.style.padding = '0 10px 10px 10px';
	if (!$('divLinkHtml')) {
		divLinkHtml.innerHTML = linkHtml;
		$('anexo').appendChild(divLinkHtml);
	}
}

function sendMail(){
	var xmlhttp;
	if (window.XMLHttpRequest) { // Mozilla, Safari...
		xmlhttp = new XMLHttpRequest();
	}
	else if (window.ActiveXObject) { // IE
		xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
	}

	xmlhttp.open('POST', 'http://www.guiaderuas.com.br/sendMail.asp', true);
	xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=ISO-8859-1');	
	
	xmlhttp.onreadystatechange = function() {
		if (xmlhttp.readyState == 4) { 
			if (xmlhttp.responseText == 'false') {
				alert('E-mail enviado com sucesso!');
			}
			else {
				alert('Falha no envio. Por favor, tente novamente.');
			}
		}
	};
	
	var qs = saveQueryString(map.getCenter().lat(),map.getCenter().lng(),map.getBoundsZoomLevel(map.getBounds()),'');
	xmlhttp.send('fromName=' + escape(document.getElementById('fromName').value)
					 + '&fromMail=' + document.getElementById('fromMail').value
					 + '&toMail=' + document.getElementById('toMail').value
					 + '&toMsg=' + escape(document.getElementById('toMsg').value)
					 + '&' + qs.replace('?', ''));
}

function queryString(variable){
	var vars = location.search.replace(/\x3F/, '').replace(/\x2B/g, ' ').split('&');
	var nvar;
		if (vars != '') {
			var qs = [];
			for(var i = 0; i < vars.length; i++) {
				nvar = vars[i].split('=');
				qs[nvar[0]] = unescape(nvar[1]);
			}
			return qs[variable];
		}
	return null;
}

function saveQueryString(lat,lng,zoom,append) {
	var query = '?lat=' + lat + '&lng=' + lng + '&zoom='+ zoom + append;
	return query;
}

var divLightbox = document.createElement('div');
var content = document.createElement('div');
function showLightbox(show) {
	divLightbox.id = 'lightbox';
	divLightbox.onselectstart = function(){return false;};
	divLightbox.onmousedown = function(){return false;};
	if (show) {
		content.innerHTML = ''
		+'<div id="lightboxContent">'
		+'	  <div style="position: relative;">'
				+'<img id="closerLightbox" class="closer" src="http://www.zlink.com.br/images/close.gif" alt="Fechar" />'
			+'</div>'
			+'<h4>Envie a posição atual por e-mail!</h4>'
			+'<form action="#" onsubmit="return validate();" id="mail">'
				+'<div style="overflow: hidden;">'
					+'<fieldset>'
						+'<legend>De:</legend>'
						+'<label for="fromName">'
							+'Seu nome:</label><input type="text" id="fromName" />'
						+'<label for="fromMail">'
							+'Seu e-mail:</label><input type="text" id="fromMail" />'
					+'</fieldset>'
					+'<fieldset>'
						+'<legend>Para:</legend>'
						+'<label for="toMail">'
							+'E-mail do destinatário:</label><input type="text" id="toMail" />'
						+'<label for="toMsg">'
							+'Mensagem (opcional):</label><textarea id="toMsg" cols="20" rows="5"></textarea>'
					+'</fieldset>'
				+'</div>'
				+'<p style="margin: 0; padding: 0;">'
					+'<input type="submit" value="Enviar e-mail" /></p>'
			+'</form>'
		+'</div>';
		document.body.appendChild(divLightbox);
		document.body.appendChild(content);
		$('closerLightbox').onclick=function(){showLightbox();};
	}
	else {
		divLightbox.parentNode.removeChild(divLightbox);
		content.parentNode.removeChild(content);
	}
}

function validate() {
	var regexMail = /^[\w-]+(\.[\w-]+)*@([a-z0-9-]+(\.[a-z0-9-]+)*?\.[a-z]{2,6}|(\d{1,3}\.){3}\d{1,3})(:\d{4})?$/;
	if (document.getElementById('fromName').value != '') {
		if (document.getElementById('fromMail').value.match(regexMail)) {
			if (document.getElementById('toMail').value.match(regexMail)) {
				sendMail();
				//return true;
			}
			else {alert('Informe um e-mail válido!'); return false;}
		}
		else {alert('Informe um e-mail válido.'); return false;}
	}
	else {alert('Informe seu nome.'); return false;}
}

var divgetLink = document.createElement('div');
divgetLink.id = 'mapLink';
function getLink() {
	var link = 'http://www.zlink.com.br' + saveQueryString(map.getCenter().lat(),map.getCenter().lng(),map.getBoundsZoomLevel(map.getBounds()),'');
	divgetLink.innerHTML = '<img id="closerLink" class="closer" src="http://www.zlink.com.br/images/close.gif" alt="Fechar" />'
								 +'Copiar link:'
								 +'<br />'
								 +'<input id="txtLink" type="text" value="" onclick="this.select();" style="width: 280px;" />';
	$('map').appendChild(divgetLink);
	$('txtLink').value = link;
	$('closerLink').onclick = function(){divgetLink.parentNode.removeChild(divgetLink);};
}

function copyAddress(txt) {
	if ($('addressToGeocode') && $('toRoute')) {
		var txt1 = $('addressToGeocode');
		var txt2 = $('toRoute');
		
		if (txt.id == txt1.id) {
			txt2.value = txt1.value;
		}
		else {
			txt1.value = txt2.value;
		}
	}
}

var myMarker;
GMap2.prototype.showMyPlace = function() {
	var myMarkerIcon = new GIcon(G_DEFAULT_ICON);
	myMarkerIcon.image = 'http://www.zlink.com.br/images/markers/marker_my_place.png';
	myMarkerIcon.iconSize = new GSize(32, 32);
	myMarkerIcon.shadowSize = new GSize(32, 32);

	if (!myMarker) {
		map.setCenter(map.myLatLng(), 11);
		myMarker = new GMarker(map.myLatLng(), {icon: myMarkerIcon});
		map.addOverlay(myMarker);
	}
	GEvent.addListener(myMarker, 'click', function(){
		map.removeOverlay(myMarker);
		myMarker = null;
	});
}

function invertRoute() {
	if(GDir.getRoute(0)) {
		var reversePoints = [GDir.getRoute(0).getEndLatLng(), GDir.getRoute(0).getStep(0).getLatLng()];
		startLoading('Aguarde, invertendo rota...', 2000);
		GDir.loadFromWaypoints(reversePoints);
	}
}

GDirections.prototype.formatRouteSteps =  function() {
	if (GDir.getStatus().code == 200) {
		for (var x = 0; x < GDir.getRoute(0).getNumSteps(); x++) {
			var markerIcon = new GIcon(G_DEFAULT_ICON);
			markerIcon.image = 'http://www.zlink.com.br/images/markers/marker_route_step.gif';
			markerIcon.iconSize = new GSize(10, 10);
			markerIcon.shadowSize = new GSize(0, 0);
			markerIcon.iconAnchor = new GPoint(5, 5);
			markerIcon.infoWindowAnchor = new GPoint(5, 5);
			var marker = new GMarker(GDir.getRoute(0).getStep(x).getLatLng(), {icon: markerIcon});
			
			var tt = new Tooltip(marker, 'Passo ' + (x+1), 4);
			marker.tooltip = tt;
			map.addOverlay(tt);
			GEvent.addListener(marker, 'mouseover', function() {this.tooltip.show();});
			GEvent.addListener(marker, 'mouseout', function() {this.tooltip.hide();});
			
			var stepDurationHtml = GDir.getRoute(0).getStep(x).getDuration().html;
			var stepDistanceHtml = GDir.getRoute(0).getStep(x).getDistance().html;
			var stepDescriptionHtml = GDir.getRoute(0).getStep(x).getDescriptionHtml();
			
			var html = '<div style="background: url(http://www.zlink.com.br/images/footprint.gif) no-repeat right bottom;">' + stepDescriptionHtml + '<br /><br />'
						+ 'Tempo estimado: ' + stepDurationHtml + '<br />'
						+ 'Distância a percorrer: ' + stepDistanceHtml + '<br /> <br />';
			
			var last;
			var next;
			var between = ' | passo <b>' + (x+1) + '</b> de <b>' + GDir.getRoute(0).getNumSteps() + '</b> | ';
			
			if (x == GDir.getRoute(0).getNumSteps() -1) {
				last = '<a href="#" onclick="GDir.changeStep(false, '+x+'); return false;"><- anterior</a>';
				next = '<span style="color: #999;">próximo -></span>';
			}
			else if (x == 0) {
				last = '<span style="color: #999;"><- anterior</span>';
				next = '<a href="#" onclick="GDir.changeStep(true, '+x+'); return false;">próximo -></a>';
			}
			else if (x != 0 && x != GDir.getRoute(0).getNumSteps() -1) {
				last = '<a href="#" onclick="GDir.changeStep(false, '+x+'); return false;"><- anterior</a>';
				next = '<a href="#" onclick="GDir.changeStep(true, '+x+'); return false;">próximo -></a>';
			}
			
			html += '<center>' + last + between + next + '</center></div>';
						
			marker.bindInfoWindowHtml(html, {maxWidth: 250});
			map.addOverlay(marker);
			stepMarkers.push(marker);
			stepMarkersHtml.push(html);
		}
	}
}

GDirections.prototype.changeStep = function(isNext, step) {
	var modStep;
	if (isNext) { modStep = step + 1;}
	else {modStep = step - 1;}
	
	if(step >= 0){stepMarkers[step].setImage('http://www.zlink.com.br/images/markers/marker_route_step.gif');}
	stepMarkers[modStep].setImage('http://www.zlink.com.br/images/markers/marker_route_step_hover.gif');
	
	stepMarkers[modStep].openInfoWindowHtml(stepMarkersHtml[modStep], {maxWidth: 250});
	map.panTo(stepMarkers[modStep].getLatLng());
}

var divHelp = document.createElement('div');
function showHelp() {
	divHelp.id = 'divHelp';
	divHelp.style.padding = '10px';
	if (!$('divHelp')) {
		var oldHtml = $('anexo').innerHTML;
		$('anexo').innerHTML = '';
		$('anexo').appendChild(divHelp);
		
		divHelp.innerHTML = ''
			+	'<h4>Dicas no Mapa:</h4>'
			+	'<ul>'
			+	'	<li>Botão de Rolagem: Zoom</li>'
			+	'	<li>1º Duplo clique: Inicio Rota</li>'
			+	'	<li>2º Duplo clique: Final Rota</li>'
			+	'	<li>Puxe-Arraste: O Mapa</li>'
			+	'	<li>Puxe-Arraste: Indicadores A e B</li>'
			+	'	<li>Setas direcionais: No Mapa</li>'
			+	'</ul>';

		$('anexo').innerHTML += oldHtml;
	}
	else {
		$('divHelp').parentNode.removeChild($('divHelp'));
	}
}

//retorna query string com lat e lng dos dois pontos da rota
function querylizeRoute() {
	var qs, from, to;
	if (GDir.getRoute(0)) {
		lat1 = GDir.getRoute(0).getStep(0).getLatLng().lat();
		lng1 = GDir.getRoute(0).getStep(0).getLatLng().lng();
		lat2 = GDir.getRoute(0).getEndLatLng().lat();
		lng2 = GDir.getRoute(0).getEndLatLng().lng();
		qs = window.location + '?lat1='+lat1+'&lng1='+lng1+'&lat2='+lat2+'&lng2='+lng2;
	}
	window.location = qs;
}