  var map = null;
  var geocoder = null;
  var gdir = null;
  var html;
  var to_html;
  var from_html;
  var theMarker;
  var reasons=[];

  function load() {
	  if (GBrowserIsCompatible()) {
		  if(geocoder == null) {
			  geocoder=new GClientGeocoder();
		  }
		  if(null == map) {
			  map = new GMap2(document.getElementById("map"));
			  map.addControl(new GLargeMapControl());
			  map.addControl(new GMapTypeControl());
		  }
		  showAddress(mapAddress, true);
		  if(null == gdir) {
			  // === create a GDirections Object ===
			  gdir=new GDirections(map,document.getElementById("directions"));
			  // === Array for decoding the failure codes ===
			  reasons[G_GEO_SUCCESS]            = "Success";
			  reasons[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
			  reasons[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
			  reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
			  reasons[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
			  reasons[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
			  reasons[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
			  reasons[G_GEO_BAD_REQUEST]        = "A directions request could not be successfully parsed.";
			  reasons[G_GEO_MISSING_QUERY]      = "No query was specified in the input.";
			  reasons[G_GEO_UNKNOWN_DIRECTIONS] = "The GDirections object could not compute directions between the points.";
				  // === catch Directions errors ===
			  GEvent.addListener(gdir, "error", handleErrors);
		  }
	  }
  }

  function handleErrors() {
	  var code = gdir.getStatus().code;
	  var reason="Code "+code;
	  if (reasons[code]) {
		  reason = reasons[code]
	  }
	  alert("Failed to obtain directions, "+reason);
  }

  function setDirections(fromAddress, toAddress) {
	  var directions = document.getElementById("directions");
	  directions.innerHTML = '';
	  gdir.load("from: " + fromAddress + " to: " + toAddress);
	  directions.innerHTML = "<h3><center>Driving Directions:</center><h3><hr>" + directions.innerHTML;
  }

  function showAddress(address, shouldCenterMap) {
	  if (geocoder) {
		  geocoder.getLatLng(
			  address,
			  function(point) {
				  if (!point) {
					  theMarker=null;
				  } else {
					  if(shouldCenterMap) {
						  map.setCenter(point, 13);
					  }
					  theMarker = createMarker(point);
					  map.addOverlay(theMarker);
					  theMarker.openInfoWindowHtml(html);
				  }
			  }
		  );
		  //if address match failed the first time, try to drop the ", USA" country and match again
		  if(null == theMarker) {
			  var newAddress=address.replace(/,\s+[uU][sS][aA]*$/,'');
			  //alert("newAddress = " + newAddress);
			  geocoder.getLatLng(
				  newAddress,
				  function(point) {
					  if (!point) {
						  alert(address + " not found");
					  } else {
						  if(shouldCenterMap) {
							  map.setCenter(point, 13);
						  }
						  theMarker = createMarker(point);
						  map.addOverlay(theMarker);
						  theMarker.openInfoWindowHtml(html);
					  }
				  }
			  );
		  }
	  }
  }

  function createMarker(point) {
	  var marker = new GMarker(point);
	  html = '<h4>Address:</h4>' + displayAddress;
	  var name = displayAddress.replace('<br>', ' ');
	  // The info window version with the "to here" form open
	  to_html = html + '<br><br>Directions: <b>To here</b> - <a href="javascript:fromhere()">From here</a>' +
		  '<br>Start address:<form action="#" onsubmit="setDirections(this.saddr.value, this.daddr.value); return false">' +
		  '<input type="text" SIZE=40 MAXLENGTH=40 name="saddr" id="saddr" value="" /><br>' +
		  '<INPUT value="Get Directions" TYPE="SUBMIT">' +
		  '<input type="hidden" name="daddr" id="daddr" value="'+name+"@"+ point.lat() + ',' + point.lng() + '"/>' +
		  '</form>';
	  // The info window version with the "to here" form open
	  from_html = html + '<br><br>Directions: <a href="javascript:tohere()">To here</a> - <b>From here</b>' +
		  '<br>End address:<form action="#" onsubmit="setDirections(this.saddr.value, this.daddr.value); return false">' +
		  '<input type="text" SIZE=40 MAXLENGTH=40 name="daddr" id="daddr" value="" /><br>' +
		  '<INPUT value="Get Directions" TYPE="SUBMIT">' +
		  '<input type="hidden" name="saddr" id="saddr" value="'+name+"@"+ point.lat() + ',' + point.lng() + '"/>' +
		  '</form>';
	  // The inactive version of the direction info
	  html = html + '<br>Directions: <a href="javascript:tohere()">To here</a> - <a href="javascript:fromhere()">From here</a>';
	  GEvent.addListener(marker, 'click', function () {
		  marker.openInfoWindowHtml(html);
	  });
	  return marker;
  }

  // functions that open the directions forms
  function tohere() {
	  theMarker.openInfoWindowHtml(to_html);
  }

  function fromhere() {
	  theMarker.openInfoWindowHtml(from_html);
  }
    
  function theGUnload() {
	  try {
		  GUnload();
	  } catch (e) {}
	}
	


