// This code was derived from the help documentation located at
// http://code.google.com/apis/maps/documentation/
// It appears that you may use the code and its derivations as long as it
// meets the terms of service:
// http://code.google.com/apis/maps/faq.html#tos_commercial
// It appears that the code is available as open-source; which open-source license,
// though, is unclear.
//
// The root page is http://code.google.com/apis/maps/

var goGoogleMap = null;
var goGeocoder = null;
var goDirectionRenderer = null;
var goDirectionsService = null;
var goInfoWindow = null;

var gcDestination = "";
var gcOldMultipleLocationsEntries = "";

var PUSHPIN_BASEPATH = "http://maps.google.com/intl/en_us/mapfiles/";
var SELECT_DIRECTIONS = "DirectionsSelect";
var MULTIPLE_DIV_DIRECTIONS = "DirectionsMultiple";
var MULTIPLE_DIV_DIRECTIONS_LABEL = "DirectionsMultipleLabel";

var PUSHPIN_DESTINATION = 0;
var PUSHPIN_ORIGIN = 1;

var gaPushPins = new Array();

// Example useage: http://www.beowurks.com/Directions/Directions.htm?AddressStem=HOTWDC-Lessons
// -------------------------------------------------------------------------------------------------------------------
// I learned to use jQuery from the following link:
// http://gmaps-samples-v3.googlecode.com/svn/trunk/xmlparsing/jqueryget.html
function loadDirectionsMap()
{
  goDirectionRenderer = new google.maps.DirectionsRenderer();
  goDirectionsService = new google.maps.DirectionsService();
  goInfoWindow = new google.maps.InfoWindow();

  gaPushPins[PUSHPIN_DESTINATION] = null;
  gaPushPins[PUSHPIN_ORIGIN] = null;

  resizeElements();

  var lcAddressStem = getHTMLQueryString("AddressStem");
  var lcXMLPath = "DirectionsXML.php?AddressStem=" + lcAddressStem;

  // Center of Austin, TX
  var loOptions =
  {
    zoom: 14,
    center: new google.maps.LatLng(30.268735, -97.745209),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    streetViewControl: true
  }

  goGoogleMap = new google.maps.Map(getGoogleMapDiv(), loOptions);

  jQuery.get(lcXMLPath, {}, function(data)
  {
    jQuery(data).find("locationinfo").each(function()
    {
      var loJQuery = jQuery(this);

      loLatLng = new google.maps.LatLng(parseFloat(loJQuery.attr("latitudey")), parseFloat(loJQuery.attr("longitudex")));
      var lcHint = loJQuery.attr("name");

      var lcInformation = "<p>";
      var lcText;

      gcDestination = "";

      lcText = loJQuery.attr("name");
      if (lcText != null)
      {
        lcInformation += "<b>" + lcText + "</b><br>";
      }

      lcText = loJQuery.attr("street");
      if (lcText != null)
      {
        lcInformation += lcText + "<br>";
        gcDestination += lcText + ", ";
      }

      lcText = loJQuery.attr("city");
      if (lcText != null)
      {
        lcInformation += lcText + ", ";
        gcDestination += lcText + ", ";
      }

      lcText = loJQuery.attr("state");
      if (lcText != null)
      {
        lcInformation += lcText + " ";
        gcDestination += lcText + " ";
      }

      lcText = loJQuery.attr("zip");
      if (lcText != null)
      {
        lcInformation += lcText + "<br>";
        gcDestination += lcText;
      }

      lcText = loJQuery.attr("phone");
      if (lcText != null)
      {
        lcInformation += lcText + "<br>";
      }

      lcText = loJQuery.attr("website");
      if (lcText != null)
      {
        lcInformation += "<br><a href=\"" + lcText + "\"target=\"_blank\">" + lcText + "</a><br>";
      }

      lcInformation += "</p>";

      goGoogleMap.setCenter(loLatLng);
      
      gaPushPins[PUSHPIN_DESTINATION] = createPushPin(loLatLng, lcHint, lcInformation, "");
    });
  });
}
// -------------------------------------------------------------------------------------------------------------------
// Called when the form is submitted.
function getDirections()
{
  var lcOriginAddress = getOriginAddress();

  if (lcOriginAddress.length == 0)
  {
    alert("You must enter a 'From' address to determine directions.");
    return;
  }

  resizeElements();

  goDirectionRenderer.setMap(goGoogleMap);
  goDirectionRenderer.setPanel(getDirectionsDiv());

  var loRequest = {
    origin: lcOriginAddress,
    destination: gcDestination,
    travelMode: google.maps.DirectionsTravelMode[getTravelModeValue()]
  };

  goDirectionsService.route(loRequest, function(toResult, toStatus)
  {
    if (toStatus == google.maps.DirectionsStatus.OK)
    {
      goInfoWindow.close();
      clearPushPins();

      goDirectionRenderer.suppressMarkers = true;
      goDirectionRenderer.setDirections(toResult);

      var loOriginLatLng = toResult.routes[0].overview_path[0];
      var loLeg =  toResult.routes[0].legs[0];
      var loStartLatLng = loLeg.start_location;
      var lcDescription = "<br><b>" + loLeg.start_address + "</b><br><br>Latitude (Y): <b>" + loStartLatLng.lat() + "</b><br>Longitude (X): <b>"  + loStartLatLng.lng() + "</b>";
      gaPushPins[PUSHPIN_ORIGIN] = createPushPin(loOriginLatLng, lcOriginAddress, lcDescription, "marker_greenA.png");

      gaPushPins[PUSHPIN_DESTINATION].setIcon(PUSHPIN_BASEPATH + "marker_greenB.png");
      gaPushPins[PUSHPIN_DESTINATION].setMap(goGoogleMap);

      setOriginAddress(loLeg.start_address);
    }
    else
    {
      StatusError(toStatus);
    }
  });
}
// -------------------------------------------------------------------------------------------------------------------
// clearOverlays no longer works in v3
function clearPushPins()
{
  var lnLength = gaPushPins.length;
  for(i = 0; i < lnLength; i++)
  {
    if (gaPushPins[i] != null)
    {
      gaPushPins[i].setMap(null);
    }
  }
}
// -------------------------------------------------------------------------------------------------------------------
// This function creates a balloon push pin on the map.
// I got the icons from places like
// http://maps.google.com/intl/en_us/mapfiles/marker_greenA.png
// http://maps.google.com/intl/en_us/mapfiles/marker_greenB.png
// http://maps.google.com/intl/en_us/mapfiles/marker.png
function createPushPin(toLatLng, tcTextTip, tcInformation, tcImage)
{
  var loMarker = new google.maps.Marker(
  {
    title :tcTextTip,
    position: toLatLng,
    map: goGoogleMap
  });

  if (tcImage.length > 0)
  {
    loMarker.setIcon(PUSHPIN_BASEPATH + tcImage);
  }

  google.maps.event.addListener(loMarker, "click", function()
  {
    goInfoWindow.close();
    goInfoWindow.setContent(tcInformation);
    goInfoWindow.open(goGoogleMap, loMarker);
  });

  return (loMarker);
}
// -------------------------------------------------------------------------------------------------------------------
// This routine parses for a tag's value. In this example, 'AddressStem' is a
// tag.
// http://www.beowurks.com/Directions/index.htm?AddressStem=RiverViewBandB
function getHTMLQueryString(tcTag)
{
  var lcTemp = window.location.search;
  var lcSearch = lcTemp.substring(1);

  var laPairs = lcSearch.split('&');

  for ( var i = 0; i < laPairs.length; i++)
  {
    var lnIndex = laPairs[i].indexOf('=');
    var lcKey = laPairs[i].substring(0, lnIndex);
    var lcValue = laPairs[i].substring(lnIndex + 1);

    if (lcKey == tcTag)
    {
      return (lcValue);
    }
  }

  return ("");
}
// -------------------------------------------------------------------------------------------------------------------
function areDirectionsRequested()
{
  var lcDrivingFromAddress = getOriginAddress();

  return (lcDrivingFromAddress.length > 0);
}
// -------------------------------------------------------------------------------------------------------------------
function setOriginAddress(tcAddress)
{
  window.document.forms[0].originaddress.value = tcAddress;
}
// -------------------------------------------------------------------------------------------------------------------
function getOriginAddress()
{
  return (allTrim(window.document.forms[0].originaddress.value));
}
// -------------------------------------------------------------------------------------------------------------------
function getCopyrightCell()
{
  return (window.document.getElementById("CellCopyright"));
}
// -------------------------------------------------------------------------------------------------------------------
function getGoogleMapDiv()
{
  return (window.document.getElementById("DivGoogleMap"));
}
// -------------------------------------------------------------------------------------------------------------------
function getDirectionsDiv()
{
  return (window.document.getElementById("DivMapRoute"));
}
// -------------------------------------------------------------------------------------------------------------------
function getTravelModeValue()
{
  return (window.document.getElementById("cboTravelNode").value);
}
// -------------------------------------------------------------------------------------------------------------------
// By the way, using tables and setting td width="25%" does not appear to work
// as the empty cell will not size to 25%. And the maps will not resize the
// cells: they just try to squeeze into the available space. Thus the below
// routine that uses actual pixel size.
function resizeElements()
{
  var loGoogleMapDiv = getGoogleMapDiv();
  var loDirectionsDiv = getDirectionsDiv();
  var loCopyrightCell = getCopyrightCell();
  var llDirectionsRequested = areDirectionsRequested();

  var lnHeight = window.document.body.clientHeight;
  var lnWidth = window.document.body.clientWidth;

  var lnCopyRightHeight = 20;

  loGoogleMapDiv.style.width = Math.ceil(lnWidth * (llDirectionsRequested ? 0.71 : 0.95)) + "px";
  loGoogleMapDiv.style.height = Math.ceil(lnHeight * 0.85) - lnCopyRightHeight + "px";

  loDirectionsDiv.style.width = Math.ceil(lnWidth * (llDirectionsRequested ? 0.25 : 0.01)) + "px";
  // loGoogleMapDiv.style.height already contains the 'px'.
  loDirectionsDiv.style.height = loGoogleMapDiv.style.height;

  loCopyrightCell.height = lnCopyRightHeight + "px";

  if (!goGoogleMap)
  {
    return;
  }

  var loCenter = goGoogleMap.getCenter();
  var loZoom = goGoogleMap.getZoom();

  goGoogleMap.setCenter(loCenter, loZoom);
}
// -------------------------------------------------------------------------------------------------------------------
//
function StatusError(tnStatusCode)
{
  switch (tnStatusCode)
  {
    case google.maps.DirectionsStatus.INVALID_REQUEST:
      alert("The request provided was invalid.");
      break;

    case google.maps.DirectionsStatus.MAX_WAYPOINTS_EXCEEDED:
      alert("Too many DirectionsWaypoints were provided in the DirectionsRequest. The total allowed waypoints is 8, plus the origin and destination.");
      break;

    case google.maps.DirectionsStatus.NOT_FOUND:
      alert("At least one of the origin, destination, or waypoints could not be geocoded.");
      break;

    case google.maps.DirectionsStatus.OVER_QUERY_LIMIT:
      alert("The webpage has gone over the requests limit in too short a period of time.");
      break;

    case google.maps.DirectionsStatus.REQUEST_DENIED:
      alert("The webpage is not allowed to use the directions service.");
      break;

    case google.maps.DirectionsStatus.UNKNOWN_ERROR:
      alert("A directions request could not be processed due to a server error. The request may succeed if you try again.");
      break;

    case google.maps.DirectionsStatus.ZERO_RESULTS:
      alert("No route could be found between the origin and destination.");
      break;

    default:
      alert("Unknown error in determing directions")
  }
}
// -------------------------------------------------------------------------------------------------------------------
function allTrim(tcString)
{
  while (tcString.substring(0, 1) == ' ')
  {
    tcString = tcString.substring(1, tcString.length);
  }
  while (tcString.substring(tcString.length - 1, tcString.length) == ' ')
  {
    tcString = tcString.substring(0, tcString.length - 1);
  }

  return (tcString);
}
// -------------------------------------------------------------------------------------------------------------------
