    //	Variaveis
	///////////////
	var map;
    var directions;
	var route;
    var vertices;
    var vertexMap;
    var stepToVertex;
    var stepMap;
    var currentLatLng;
    var close = false;
    var bearing;
    var nextBearing;
    var nextVertexId;
    var nextVertex;
    var progressArray;
    var progressDistance;
    var currentStep;
    var carMarker;
    var selectedStep = null;
    var driving = false;

	//	Inicia o mapa
	///////////////////
    function load() {
      if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map"));
        map.setCenter(start, 17);
		map.addControl(new GLargeMapControl());
		map.addControl(new GMapTypeControl());

        carMarker = getCarMarker(start);
        map.addOverlay(carMarker);
        carMarker.hide();

		var loja1 = [
  			new GInfoWindowTab("Clínica Médica New Life", "Clínica Médica New Life - SP<br><br>R. José Policano 32, Embu-Guaçu - SP")
		];
        var ploja1 = new GLatLng(-23.807962,-46.812723);
		var loja2 = [
  			new GInfoWindowTab("Clinica NewLife", "Clinica NewLife - RJ<br><br>Av. Joaquim da Costa Lima 07, Belford Roxo - RJ")
		];
        var ploja2 = new GLatLng(-22.760462,-43.403689);
	/*	var loja3 = [
  			new GInfoWindowTab("Residência Terapêutica New Life - Embu Guaçu", "Residência Terapêutica New Life - Embu Guaçu<br><br>Estr. José Hessel, 70 - Embu Guaçu - SP")
		];
        var ploja3 = new GLatLng(-23.788992,-46.795664);*/

		var marker1 = new GMarker(ploja1);
		GEvent.addListener(marker1, "click", function() {
	  	marker1.openInfoWindowTabsHtml(loja1);
        document.getElementById("to").value = "R. José Policano 32, Embu-Guaçu - SP";
        document.getElementById("textTo").innerHTML = "Clinica NewLife - R. José Policano 32, Embu-Guaçu - SP";
		});
		map.addOverlay(marker1);

		var marker2 = new GMarker(ploja2);
		GEvent.addListener(marker2, "click", function() {
	  	marker2.openInfoWindowTabsHtml(loja2);
        document.getElementById("to").value = "Av. Joaquim da Costa Lima 07, Belford Roxo - RJ";
        document.getElementById("textTo").innerHTML = "Clinica NewLife - Av. Joaquim da Costa Lima 07, Belford Roxo - RJ";
		});
		map.addOverlay(marker2);

		/*var marker3 = new GMarker(ploja3);
		GEvent.addListener(marker3, "click", function() {
	  	marker3.openInfoWindowTabsHtml(loja3);
        document.getElementById("to").value = "Estr. José Hessel, 70 - Embu Guaçu - SP";
        document.getElementById("textTo").innerHTML = "Comunidade New Life - Estr. José Hessel, 70 - Embu Guaçu - SP";
		});
		map.addOverlay(marker3);*/
		
        directions = new GDirections(map);
        GEvent.addListener(directions, "load", function() {
          jumpInMyCar();
        });

        GEvent.addListener(directions, "error", function() {
          showStatus("O endereço de origem ou de destino não foram encontrados");               
        });
      }
    }

    //	Cria o icone do veiculo
	/////////////////////////////
    function getCarMarker(start) {
      /*@cc_on @*/
      /*@if (@_jscript_version < 5.7)
      return new GMarker(start);
      /*@end @*/ 
      return new GMarker(start, getArrowIcon(0.0));
    }
	
	//	Define a imagen para o icone do veiculo
    function setCarMarkerImage(bearing) {
      /*@cc_on @*/
      /*@if (@_jscript_version < 5.7)
      return;
      /*@end @*/
      carMarker.setImage(getArrowUrl(bearing));
    }
	
	//	Recebe o endereço de origem e destino para criar a rota
	//////////////////////////////////////////////////////////////
    function generateRoute() {
      var from = document.getElementById("from").value;
      var to = document.getElementById("to").value+", Brazil";
      directions.load("from: " + from + " to: " + to, { preserveViewport: true, getSteps: true });
    }

    function jumpInMyCar() {
      route = directions.getRoute(0);
      collapseVertices(directions.getPolyline());
      map.setCenter(vertices[0], 16);
      renderTextDirections();
      checkCoverage(0);
    }

    //	Checa a rota
    function checkCoverage(step) {
      if (step > route.getNumSteps()) {
        jumpToVertex(0);
      } else {
        if (step == route.getNumSteps()) {
          ll = route.getEndLatLng();
        } else {
          ll = route.getStep(step).getLatLng();
        }
      }
    }

   //	Pula para um determinado ponto da roda
    function jumpToVertex(idx) {
      currentLatLng = vertices[idx];
      nextVertex = vertices[idx + 1];
      nextVertexId = idx + 1;

          bearing = getBearingFromVertex(idx);
      nextBearing = getBearingFromVertex(idx + 1);

      setCarMarkerImage(bearing);
      carMarker.setLatLng(currentLatLng);
      carMarker.show();

      currentStep = stepMap[idx];

      map.panTo(currentLatLng, 16);
      highlightStep(currentStep);
      checkDistanceFromNextVertex();

    }

   

   // Checa distancia até o proximo vertex
   /////////////////////////////////////////
    function checkDistanceFromNextVertex() {
      close = false;
      var d = currentLatLng.distanceFrom(nextVertex);
      var b = getBearing(currentLatLng, nextVertex);

      if (getYawDelta(bearing, b) > 90) {
        incrementVertex();

        if (driving) {
          checkDistanceFromNextVertex();
        }

      } else {
        if (driving) {
          updateViewerDirections(progressDistance - d);
        }

        if (d < 10) {
          close = true;
        }
      }
    }

   
    function advance() {
      var selected = selectLink(bearing);

      if (close && nextBearing) {
        var selectedTurn = selectLink(nextBearing);
        if (selectedTurn.delta < 15) {
          selected = selectedTurn;
          incrementVertex();
        }
      }

      if (selected.delta > 40) {
        jumpToVertex(nextVertexId);
      }
    }


   
    function incrementVertex() {
      if (! vertices[nextVertexId + 1]) {
        /* we are at the end of the route */
        endReached();
      } else {
        nextVertexId++;
        nextVertex = vertices[nextVertexId];

            bearing = getBearingFromVertex(nextVertexId - 1);
        nextBearing = getBearingFromVertex(nextVertexId);
        setCarMarkerImage(bearing);

       
        setProgressDistance();
      }
    }

	//	Mostra os passos sobre a rota
    function showStatus(message) {
      document.getElementById("directions").innerHTML = message;
      document.getElementById("directions").style.display = "block";
    }

   
    function getBearingFromVertex(n) {
      var origin = vertices[n];
      var destination = vertices[n+1];
      if (destination != undefined) {
        return getBearing(origin, destination);
      } else {
        return null;
      }
    }

   
    function getYawDelta(a, b) {
      var d = Math.abs(sanitiseYaw(a) - sanitiseYaw(b));
      if (d > 180) {
        d = 360 - d;
      }
      return d;
    }

    function sanitiseYaw(yaw) {
      if (yaw > 360 || yaw < 360) {
        yaw = yaw % 360;
      }
      return yaw;
    }

	// Gera o icone para a seta
	//////////////////////////////
    function getArrowIcon(bearing) {
      var icon = new GIcon();
      icon.image = getArrowUrl(bearing);
      icon.iconSize = new GSize(24, 24);
      icon.iconAnchor = new GPoint(12, 12);
      return icon;
    }

	// Determina a url correta da seta
	////////////////////////////////////
   function getArrowUrl(bearing) {
      var id = (3 * Math.round(bearing / 3)) % 120;
      return "http://maps.google.com/mapfiles/dir_" + id + ".png";
    }

  
	// Constroi os vertices, vertexMap, stepToVertex e stepMap
	///////////////////////////////////////////////////////////
   function collapseVertices(path) {
     vertices = new Array();
     vertexMap = new Array(path.getVertexCount());

     vertices.push(path.getVertex(0));
     vertexMap[0] = 0;

     for (var i = 1; i < path.getVertexCount(); i++) {
       if (! path.getVertex(i).equals(vertices[vertices.length - 1])) {
         vertices.push(path.getVertex(i));
       }
       vertexMap[i] = vertices.length - 1;
     }

     stepToVertex = new Array(route.getNumSteps());
     stepMap      = new Array(vertices.length);

     for (var i = 0; i < route.getNumSteps(); i++) {
       stepToVertex[i] = vertexMap[route.getStep(i).getPolylineIndex()];
     }

     var step = 0;
     for (var i = 0; i < vertices.length; i++) {
       if (stepToVertex[step + 1] == i) {
         step++;
       }
       stepMap[i] = step;
     }
   }

    function renderTextDirections() {

      var startAddress = route.getStartGeocode().address;
      var   endAddress = route.getEndGeocode().address;

      var html  =  getDirectionsWaypointHtml(startAddress, "A");
          html +=  getDivHtml("summary", "", route.getSummaryHtml());

      for (var n = 0; n < route.getNumSteps(); n++) {
        html += '<a onclick="selectStep(' + n + ')">';
        html += getDivHtml("step" + n, "dstep", route.getStep(n).getDescriptionHtml());
        html += '</a>';
      }

      html += getDirectionsWaypointHtml(endAddress, "B");

      document.getElementById("directions").innerHTML = html;

      setWaypointIcon('A');
      setWaypointIcon('B');
    }

	//	Gera o html para o topo e rodape para as informações da rota
	//////////////////////////////////////////////////////////////////
    function getDirectionsWaypointHtml(address, letter) {
     var content = getDivHtml('letter' + letter, 'letterIcon', "");
         content += '<span class="waypointAddress">' + address + '</span>';
      return getDivHtml("wayPoint" + letter, "waypoint", content);
    }


	//	Define os icones a serem utilizado nas informações da rota
	///////////////////////////////////////////////////////////////
    function setWaypointIcon(letter) {
      var png = 'http://maps.google.com/intl/en_us/mapfiles/icon_green' + letter + '.png';
      /*@cc_on @*/
      /*@if (@_jscript_version < 5.7)
      document.getElementById('letter' + letter).style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + png + '", sizingMethod="scale");';
      return;
      /*@end @*/ 
      document.getElementById('letter' + letter).style.backgroundImage = 'url(' + png + ')';
    }

   function getDivHtml(id, cssClass, content) {
      var div = "<div";
      if (id != "") {
        div += ' id="' + id + '"';
      }

      if (cssClass != "") {
        div += ' class="' + cssClass + '"';
      }

      div += '>' + content + '</div>';
      return div;
    }


    function selectStep(i) {
      var vertex = vertexMap[route.getStep(i).getPolylineIndex()];
      jumpToVertex(vertex);
    }


    function highlightStep(i) {
      if (selectedStep != null) {
        document.getElementById("step" + selectedStep).style.backgroundColor = "white";
      }

      document.getElementById("step" + i).style.backgroundColor = "#eeeeff";
      selectedStep = i;
    }

    function getBearing(origin, destination) {
      if (origin.equals(destination)) {
        return null;
      }
      var lat1 = origin.lat().toRad();

      var lat2 = destination.lat().toRad();
      var dLon = (destination.lng()-origin.lng()).toRad();

      var y = Math.sin(dLon) * Math.cos(lat2);
      var x = Math.cos(lat1)*Math.sin(lat2) -
              Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon);
      return Math.atan2(y, x).toBrng();
    }
    
    Number.prototype.toRad = function() {
      return this * Math.PI / 180;
    }

    Number.prototype.toDeg = function() {
      return this * 180 / Math.PI;
    }

   Number.prototype.toBrng = function() {
      return (this.toDeg()+360) % 360;
    }