var closest_point = null;
var contentDiv = null;
var end_address = null;
var geocoder = null;
var map = null;
var search_address = null;
var search_directions = null;
var search_marker = null;
var sorted_points = null;
G_END_ICON.image = "nada.png"; 

function showAddress (address) {
  search_address = address;
  if (geocoder) {
    geocoder.getLatLng(
      address,
      function (point) {
        if (!point) {
          alert(address + " not found");
        } else {
          if (search_directions != null) search_directions.clear ();
          if (search_marker != null) {
            map.removeOverlay (search_marker);
            search_marker = null;
          }
          var closest = 1000000000000000000;
          for (var i in points) {
          	var g = new GLatLng (points[i].lat, points[i].lon);
          	var distance = g.distanceFrom (point);
            points[i].distance = Math.round (((distance / 1000) / 1.6) * 100) / 100;
          	if (distance < closest) {
          	  closest = distance;
          	  closest_point = i;
            }
          }
          map.setCenter (point, 11);
          search_marker = new GMarker (point);
          GEvent.addListener (search_marker, 'click', searchMarkerClickHandler);
          map.addOverlay (search_marker);
          search_marker.content =  '<br><span style="font-size: 10px;"><table ><tr><td align="right">Your search:</td><td> ' + address + '</td>' +
            '<tr><td align="right">Closest PAL:</td><td> <div style="cursor: pointer; text-decoration: underline; color: #0000FF;" onclick="go_to_point (0);">' + points[closest_point].PALName + '</div><div style="cursor: pointer; text-decoration: underline; color: #0000FF;" onclick="route_to_point (' + points[closest_point].indexId + ');"> Driving directions</div></td>' +
            '<tr><td align="right">Distance:</td><td> ' + points[closest_point].distance + ' miles</td>' +
            '</tr></table></span>'
          search_marker.openInfoWindowHtml (search_marker.content);
          clear_points_div ();
          var count = 0;
          sorted_points = points.concat ();
          sorted_points.sort (sortByDistance);
          for (var i in sorted_points) {
          	if (count++ == 5) break;
            var n = document.createElement ('div');
            n.innerHTML = '<table><tr>' +
              '<td valign="top"><div style="cursor: pointer;" onclick="go_to_point (' + i + ');"><img src="/images/mappin.png"></div></td>' + 
              '<td style="font-size: 10px;">' +
                sorted_points[i].PALName +
                '<br>Distance: ' + sorted_points[i].distance + ' miles' +
                '<br><div style="cursor: pointer; text-decoration: underline; color: #0000FF;" onclick="route_to_point (' + sorted_points[i].indexId + ');">Driving directions</div>'
              '</td></tr></table><br>';
            contentDiv.appendChild (n);  
          }
        }
      }
    );
  }
}

function printable_directions () {
  printWindow = window.open ("", "printWindow","menubar=0,resizable=1,width=800,height=500");
  printWindow.document.write (contentDiv.innerHTML.toString().replace (/printable directions/, ''));  
}

function sortByDistance (a, b) {
  var x = a.distance;
  var y = b.distance;
  return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}

function clear_points_div () {
  while (contentDiv.firstChild) {
  	contentDiv.removeChild (contentDiv.firstChild);
  }
}

function route_to_point (i) {
  clear_points_div ();
  end_address = points[i].Address + ' ' + points[i].City + ', ' + points[i].State;
  var pointsArray = new Array (search_marker.getLatLng(), points[i].marker.getLatLng());
  search_directions.clear ();
  search_directions.loadFromWaypoints (pointsArray, {getSteps:true});
}

function go_to_point (i) {
  html = '<span style="font-size: 1em;"><span style="font-weight: bold;">' + sorted_points[i].PALName;
  html += '</span><br>' + sorted_points[i].Address;
  html += '<br>' + sorted_points[i].City + ', ' + sorted_points[i].State + ' ' + sorted_points[i].Zip;
  html += '<br>' + sorted_points[i].Phone;
  if (sorted_points[i].Email != "") {
    html += '<br><a href="mailto:' + sorted_points[i].Email + '">' + sorted_points[i].Email + '</a>';
  }
  
  
  if (points[i].distance != null) html += '<br>Distance: ' + sorted_points[i].distance + ' miles<div style="cursor: pointer; text-decoration: underline; color: #0000FF;" onclick="route_to_point (' + sorted_points[i].indexId + ');"> Driving directions</div></span>';
  sorted_points[i].marker.openInfoWindow (html);
  map.setCenter (points[i].point, 11);
}

function initialize() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById("map_canvas"));
    geocoder = new GClientGeocoder();
    map.enableContinuousZoom();
    map.enableScrollWheelZoom();
    map.addControl (new GLargeMapControl ());
    map.addControl (new GMapTypeControl ());
    map.addControl(new GScaleControl());
    map.setCenter(new GLatLng (37.6, -119.5), 6);
    GEvent.addListener (map, 'dragend', displayBounds);
    loadPoints ();
    GEvent.addListener (map, 'singlerightclick', markerRightClickHandler);
    displayBounds ();
    contentDiv = document.getElementById ('points_div');
    search_directions = new GDirections(map); //, contentDiv);
    // ========== launch the custom Panel creator a millisecond after the GDirections finishes loading ==========
    // == The delay is required in case we rely on GDirections to perform the initial setCenter ==
    GEvent.addListener (search_directions,"load", function() {
      setTimeout('customPanel(map,"map", search_directions, document.getElementById ("points_div"))', 1);
    });
  } else {
    document.write ('Your browser does not support Google maps');
  }
}

function loadPoints () {
  for (var i in points) {
    p = points[i];
    p.indexId = i;
    if (p.lat == null || p.lon == null) {
      p.icon = new GIcon (G_DEFAULT_ICON, 'yellow.png');
  	  p.lon = -118.7841796875;
  	  p.lat = 37.07271048132946;
    } else {
      p.icon = new GIcon (G_DEFAULT_ICON, '/images/mappin.png');
      p.icon.iconSize = new GSize(33,  28)
	  
	  
    }
    p.point = new GLatLng (p.lat, p.lon);
    p.marker = new GMarker (p.point, p.icon);
    p.marker.enableDragging ();
    p.marker.markerId = i;
    p.marker.pointData = p;
    p.marker.urlHandler = markerUrlHandler;
    GEvent.addListener (p.marker, 'click', markerClickHandler);
    map.addOverlay (p.marker);
  }
}

function customPanel (map, mapname, dirn, div) {
  var html = "";

  // ===== local functions =====

  // === waypoint banner ===
  function waypoint(point, type, address, i) {
  	icon = 'http://www.google.com/intl/en_ALL/mapfiles/icon-dd-' + type + '-trans.png';
  	extra = null;
  	if (type == 'play') {
  	  address = search_address;
  	  extra = '<div style="cursor: pointer; text-decoration: underline; color: #0000FF; font-size: 8px" onclick="printable_directions ()">printable directions</div>';
  	}
  	if (type == 'stop') {
  	  icon = 'mappin.png';
  	  address = end_address;
  	}
    var target = '"' + mapname+".showMapBlowup(new GLatLng("+point.toUrlValue(6)+"))"  +'"';
    html += '<table style="border: 1px solid silver; margin: 1px 0px; background-color: rgb(238, 238, 238); border-collapse: collapse; color: rgb(0, 0, 0);">';
    html += '  <tr>';
    html += '    <td rowspan="2" onclick='+target+' style="cursor: pointer; padding: 4px 15px 0px 5px; vertical-align: middle; width: 20px;">';
    html += '      <img src="' + icon + '">'
    html += '    </td>';
    html += '    <td style="vertical-align: middle; width: 100%;">' + address + '</td></tr>';
    if (extra != null) {
      html += '  <tr><td style="padding: 0px 10px 10px 0px; text-align: center; vertical-align: top;">' + extra + '</td></tr>';
    } else {
      html += '  <tr><td></td></tr>';
    }
    html += '</table><br>';
  }

  // === route distance ===
  function routeDistance(dist) {
    html += '<div style="text-align: right; padding-bottom: 0.3em;">' + dist + '</div>';
  }      

  // === step detail ===
  function detail(point, num, description, dist) {
    var target = '"' + mapname+".showMapBlowup(new GLatLng("+point.toUrlValue(6)+"))"  +'"';
    html += '<table style="margin: 0px; padding: 0px; border-collapse: collapse;">';
    html += '  <tr style="cursor: pointer;" onclick='+target+'>';
    html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; text-align: right;">';
    html += '      <a href="javascript:void(0)"> '+num+'. </a>';
    html += '    </td>';
    html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; width: 100%;">';
    html +=        description;
    html += '    </td>';
    html += '    <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px 0.3em 0.5em; vertical-align: top; text-align: right;">';
    html +=        dist;
    html += '    </td>';
    html += '  </tr>';
    html += '</table>';
  }

  // === Copyright tag ===
  function copyright(text) {
    html += '<div style="font-size: 0.86em;">' + text + "</div>";
  }
  

  // === read through the GRoutes and GSteps ===

  for (var i=0; i<dirn.getNumRoutes(); i++) {
    if (i==0) {
      var type="play";
    } else {
      var type="pause";
    }
    var route = dirn.getRoute(i);
    var geocode = route.getStartGeocode();
    var point = route.getStep(0).getLatLng();
    // === Waypoint at the start of each GRoute
    waypoint(point, type, geocode.address);
    routeDistance(route.getDistance().html+" (about "+route.getDuration().html+")");

    for (var j=0; j<route.getNumSteps(); j++) {
      var step = route.getStep(j);
      // === detail lines for each step ===
      detail(step.getLatLng(), j+1, step.getDescriptionHtml(), step.getDistance().html);
    }
  }
  
  // === the final destination waypoint ===   
  var geocode = route.getEndGeocode();
  var point = route.getEndLatLng();
  waypoint(point, "stop", geocode.address);
           
  // === the copyright text ===
  copyright(dirn.getCopyrightsHtml());

  // === drop the whole thing into the target div
  div.innerHTML = html;

} // ============ end of customPanel function ===========

function markerClickHandler () {
  html = '<span style="font-size: 1em;"><span style="font-weight: bold;">' + this.pointData.PALName;
  html += '</span><br>' + this.pointData.Address;
  html += '<br>' + this.pointData.City + ', ' + this.pointData.State + ' ' + this.pointData.Zip;
  html += '<br>' + this.pointData.Phone;
  if (this.pointData.Email != "") {
    html += '<br><a href="mailto:' + this.pointData.Email + '">' + this.pointData.Email + '</a>';
  }
  if (this.pointData.distance != 0) html += '<br>Distance: ' + this.pointData.distance + ' miles';
  if (search_marker != null ) html += '<div style="cursor: pointer; text-decoration: underline; color: #0000FF;" onclick="route_to_point (' + this.pointData.indexId + ');"> Driving directions</div>';
  html += '</span>';
  this.openInfoWindow (html);
}

function searchMarkerClickHandler () {
  this.openInfoWindowHtml (this.content);
}

function markerRightClickHandler (point, src, overlay) {
//  text = '<form id="editForm" action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post" onsubmit="return savePoint ();">';
//  text += '<table>';
//  for (k in overlay.pointData) {
//    v = overlay.pointData[k];
//    text += '<tr><td align="right">' + k + '</td><td><input name="' + k + '" size="30" value="' + v + '"></td></tr>';
//  }
//  text += '<tr><td align="center" colspan="2"><input type="submit" name="submit" value="Save"></td></tr>';
//  text += '</table></form>';
//  overlay.openInfoWindowHtml (text);
  form = document.createElement ('form');
  form.id = 'editForm';
  form.marker = overlay;
  GEvent.addDomListener (form, 'submit', savePoint);
  table = document.createElement ('table');
  for (k in overlay.pointData) {
    v = overlay.pointData[k];
    text = document.createTextNode (k);
    td = document.createElement ('td');
    td.setAttribute ('align', 'right');
    td.appendChild (text);
    tr = document.createElement ('tr');
    tr.appendChild (td);
    input = document.createElement ('input');
  	input.type = 'text';
  	input.size = '30';
    input.value = v;
    form.appendChild (input);
    td = document.createElement ('td');
    td.setAttribute ('align', 'left');
    td.appendChild (input);
    tr.appendChild (td);
    table.appendChild (tr);
  }
  input = document.createElement ('input');
  input.type = 'submit';
  input.value = 'Save';
  input.id = 'submitButton';
  form.appendChild (input);
  td = document.createElement ('td');
  td.setAttribute ('align', 'center');
  td.setAttribute ('colspan', '2');
  td.appendChild (input);
  tr = document.createElement ('tr');
  tr.appendChild (td);
  table.appendChild (tr);
  form.appendChild (table)
  overlay.openInfoWindow (form);
//  url = '<?php echo $_SERVER['PHP_SELF'] ?>?markerId=' + overlay.markerId + '&rightClick=true';
//  hitHttp (url, overlay, stuff);
}

function savePoint () {
  alert ('Made it here: ' + this);
  return false;
}

function markerUrlHandler (content) {
  this.openInfoWindowHtml (content);
}

function hitHttp (url, object, callback) {
  var req;
  if (window.XMLHttpRequest) {
    req = new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    req = new ActiveXObject("Microsoft.XMLHTTP");
  } else {
    alert ('Unsupported browser!');
    return;
  }
  req.marker = marker;
  req.onreadystatechange = function () {
    if (req.readyState == 4) {
      if (req.status == 200) {
        callback (object, req.responseText);
      }
    }
  }
  req.open ("GET", url, true);
  req.send (null);
}

function stuff (object, responseText) {
  object.urlHandler (responseText);
}

function displayBounds () {
  bounds = map.getBounds();
  center = map.getCenter();
  myDump ("Bounds: " + bounds + "\nCenter:" + center + "\n");
}

function myDump (text) {
  //dump (text);
}