// Used by multiple pages involving maps

 var map;
 var points = [];
 var polyline;
 var bounds = new GLatLngBounds();
 var start_marker;
 var stop_marker;
 var new_marker;
 var current_marker;
 var current_point;
 var current_html;
 var icons = [];
 var icon = new GIcon(G_DEFAULT_ICON, "/images/d110.png");
 icon.iconSize = new GSize(34,45);
 icon.shadowSize = new GSize(0,0);
 icon.iconAnchor = new GPoint(17, 45);
 icon.infoWindowAnchor = new GPoint(9, 2);
 icons["d110"] = icon;
 
 icon = new GIcon(G_DEFAULT_ICON, "/images/marker_34_red.png");
 icon.shadow = "/images/shadow50.png";
 icon.iconSize = new GSize(20, 34);
 icon.shadowSize = new GSize(37, 34);
 icon.iconAnchor = new GPoint(6, 34);
 icon.infoWindowAnchor = new GPoint(5, 1);
 icons["stop"] = icon;
 
 icon = new GIcon(icons["stop"]);
 icon.image = "/images/marker_34_green.png";
 icons["start"] = icon;
 
 var gicons = ["icon10","icon13","icon14","icon28","icon29","icon41","icon44","icon45",
     "icon46","icon56","icon6"];
    for(var i=0; i<gicons.length; i++)
    {
       icon = new GIcon(icons["stop"]);
       icon.image = "/images/" + gicons[i] + ".png";
       icon.shadow  = "/images/" + gicons[i] + "s.png";
       icon.iconSize=new GSize(32,32);
       icon.shadowSize=new GSize(56,32);
       icon.iconAnchor=new GPoint(16,32);
       icon.infoWindowAnchor=new GPoint(16,0);
       icons[gicons[i]] = icon;
    }

// Class to reperesent a Marker
function TrackerMarker(id,trackerPoint, name, comment, iconName)
{
   this.id = id;
   this.trackerPoint = trackerPoint;
   this.name = name || "";
   this.comment = comment || "";
   this.iconName = iconName || "d110";
}
TrackerMarker.prototype.getId = function () { return this.id; }
TrackerMarker.prototype.getTrackerPoint = function () { return this.trackerPoint; }
TrackerMarker.prototype.getPoint = function () { return this.trackerPoint.getPoint(); }
TrackerMarker.prototype.getName = function () { return this.name; }
TrackerMarker.prototype.getComment = function () { return this.comment; }
TrackerMarker.prototype.getIcon = function () { return this.iconName; }

// Class to represent GPS points
function TrackerPoint(xml,i) {
   if ( xml )
   {
    this.id = parseInt(xml[i].getAttribute("id"));
    this.speed = parseInt(xml[i].getAttribute("speed"));
    this.time = xml[i].getAttribute("time");
    var lat = parseFloat(xml[i].getAttribute("lat"));
    var lon = parseFloat(xml[i].getAttribute("lon"));
    this.point = new GLatLng(lat,lon);
    this.type = xml[i].getAttribute("type");
    this.accuracy = parseFloat(xml[i].getAttribute("accuracy"));
    this.direction = xml[i].getAttribute("direction");
    this.altitude = parseFloat(xml[i].getAttribute("altitude"));
    this.altitudeUncertainty = parseFloat(xml[i].getAttribute("altitude_uncertainty"));
    this.speedUncertainty = parseFloat(xml[i].getAttribute("speed_uncertainty"));
   } else {
      this.id = 0;  
      this.speed = 0;
      this.time = "Unknown";
      this.point = null;
      this.accuracy = 0;
      this.direction = "Unknown";
      this.altitude = 0;
      this.altitudeUncertainty = 0;
      this.speedUncertainty = 0;
   }
}
TrackerPoint.prototype.setPoint = function (point) { this.point = point; }
TrackerPoint.prototype.getBalloonHtml = function () {
 return "Last seen on " + this.time + "<br/>" + this.point.toString();
}
TrackerPoint.prototype.getHelp = function () {
 return "Janey was last seen on " + this.time + " traveling at " + this.speed + " mph.";
}
TrackerPoint.prototype.getGeekHtml = function () {
 return "<table>"
   + "<tr><td><b>Id</b></td><td>" + this.id + "</td></tr>"
   + "<tr><td><b>Time</b></td><td>" + this.time + "</td></tr>"
   + "<tr><td><b>Speed</b></td><td>" + this.speed + " mph (+/- " + this.speedUncertainty + ")</td></tr>"
   + "<tr><td><b>Direction</b></td><td>" + this.direction + "</td></tr>"
   + "<tr><td><b>Altitude</b></td><td>" + this.altitude + " meters (+/- " + this.altitudeUncertainty  + ")</td></tr>"
   + "<tr><td><b>Latitude</b></td><td>" + this.getPoint().lat() + "</td></tr>"
   + "<tr><td><b>Longitude</b></td><td>" + this.getPoint().lng() + "</td></tr>"
   + "<tr><td><b>Accuracy</b></td><td>" + this.accuracy + " meters</td></tr>"
   + "</table>";
}
TrackerPoint.prototype.getId = function() { return this.id; }
TrackerPoint.prototype.getPoint = function() { return this.point; }
TrackerPoint.prototype.getTime = function() { return this.time; }
TrackerPoint.prototype.getAccuracy = function() { return this.accuracy; }
TrackerPoint.prototype.getDirection = function() { return this.direction; }
TrackerPoint.prototype.getType = function() { return this.type; }
TrackerPoint.prototype.getSpeed = function() { return this.speed; }
TrackerPoint.prototype.getSpeedUncertainty = function() { return this.speedUncertainty; }
TrackerPoint.prototype.getAltitude = function() { return this.altitude; }
TrackerPoint.prototype.getAltitudeUncertainty = function() { return this.altitudeUncertainty; }
    
function updateLegs()
{
   // Get the legs from the database
   today=new Date()
   var request = GXmlHttp.create();
   request.open("GET", "/track/legs.php?t=" + today.getTime(), true);
   request.onreadystatechange = function() {
     if (request.readyState == 4) {
       var xmlDoc = request.responseXML;
       var legs = xmlDoc.documentElement.getElementsByTagName("leg");
       //GLog.write("legs.length=" + legs.length);
          
       var leg_html="";
       for (var i = 0; i < legs.length; i++) {
         var id = parseInt(legs[i].getAttribute("id"));
         var name = legs[i].getAttribute("name");
         leg_html += getLegHtml(id,name);
       }
       
       if ( leg_html == "" )
       {
         leg_html = "No trip legs defined - check back later.";
       } 
       document.getElementById("trip_legs").innerHTML = leg_html;
     }
   }
   request.send(null);      
}

function getLegHtml(id,name)
{
   return "<a href='javascript:setMode(" 
                  + '"show_leg"' + "," + id + ")'>" + name + "</a><br/>";
}

function updateMarkers()
{
   // Get the legs from the database
   today=new Date()
   var request = GXmlHttp.create();
   request.open("GET", "/track/markers.php?t=" + today.getTime(), true);
   request.onreadystatechange = function() {
     if (request.readyState == 4) {
       var xmlDoc = request.responseXML;
       var markers = xmlDoc.documentElement.getElementsByTagName("marker");
          
       var marker_html="";
       for (var i = 0; i < markers.length; i++) {
         var id = parseInt(markers[i].getAttribute("id"));
         var name = markers[i].getAttribute("name");
         marker_html += getMarkerHtml(id,name)
       }
       
       if ( marker_html == "" )
       {
         marker_html = "No markers defined - check back later.";
       } 
       document.getElementById("markers").innerHTML = marker_html;
     }
   }
   request.send(null);      
}

function getMarkerHtml(id,name)
{
   return "<a href='javascript:setMode(" 
                  + '"show_marker"' + "," + id + ")'>" + name + "</a><br/>";
}

function clearMap()
{
   map.clearOverlays();
   new_marker=null;
   start_marker=null;
   stop_marker=null;
   bounds=null;
   polyline=null;
   
   if ( document.getElementById("start_lat") )
   {
      document.getElementById("start_lat").innerHTML = "";
      document.getElementById("start_lon").innerHTML = "";  
      document.getElementById("stop_lat").innerHTML = "";
      document.getElementById("stop_lon").innerHTML = ""; 
   }
   setHelp("Map Cleared");
}

function createStartMarker(point)
{
   var html = "<div id='MarkerInfo'>" +  
   "This Start location is <br/>" + point.toString()
   + "</div>";
   start_marker = createDraggableMarker(point, "start", html);
   start_marker.id="start_marker";
   map.addOverlay(start_marker);
   if ( document.getElementById("start_lat") )
   {
      document.getElementById("start_lat").innerHTML = point.y;
      document.getElementById("start_lon").innerHTML = point.x;  
   }
}
function createStopMarker(point)
{
   var html = "<div id='MarkerInfo'>" +  
   "This Stop location is <br/>" + point.toString()
   + "</div>";
   stop_marker = createDraggableMarker(point, "stop", html);
   stop_marker.id="stop_marker";
   map.addOverlay(stop_marker);
   if ( document.getElementById("stop_lat") )
   {
      document.getElementById("stop_lat").innerHTML = point.y;
      document.getElementById("stop_lon").innerHTML = point.x;  
   }
}

// Creates a marker whose info window displays the given html
function createMarker(point, html) {
  current_html = "<div id='MarkerInfo'>" + html + "</div>";
  var marker = new GMarker(point, {icon: icons["d110"], title: "Janey"});

  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml(current_html);
  });

  return marker;
}

// Creates a marker whose info window displays the given html
function createTabbedMarker(tp) {

   var marker = new GMarker(tp.getPoint(), {icon: icons["d110"], title: "Janey"});
   
   GEvent.addListener(marker, "click", function() {
     var tabs = [];
     var html = "<div id='MarkerInfo'>" + current_point.getBalloonHtml() + "</div>";
     tabs.push(new GInfoWindowTab("Summary",html));
     var geek = "<div id='MarkerInfo'>" + current_point.getGeekHtml() + "</div>";
     tabs.push(new GInfoWindowTab("Geek out",geek));
     marker.openInfoWindowTabsHtml(tabs);
   });
   
   return marker;
}


function createDraggableMarker(point, type, html) {
   
  var marker = new GMarker(point, {icon: icons[type], title: type, draggable: true});

  // Show this marker's index in the info window when it is clicked
  GEvent.addListener(marker, "click", function() {
    var html = "This location is <br/>" + marker.getPoint().x + "," + marker.getPoint().y;
    marker.openInfoWindowHtml(html);
    setHelp("");
  });

  GEvent.addListener(marker, "dragstart", function() {
     map.closeInfoWindow();
     setHelp("");
     });
   
   GEvent.addListener(marker, "dragend", function() {
     if ( marker.id == "start_marker" )
     {
        label = "start"; 
     } else {
        label = "stop";
     }
     document.getElementById(label+"_lat").innerHTML = marker.getPoint().y;
     document.getElementById(label+"_lon").innerHTML = marker.getPoint().x;
     snapToPolyline(marker);
     setHelp("");
   });


  return marker;
}

function snapToPolyline(marker)
{
  var point = getClosestPointToPolyline(marker);
  marker.setPoint(point);
  marker.redraw(true);   
}

// x == lng, y ==lat
// Returns a GLatLng
function getClosestPointToPolyline(marker)
{
   var closest = 0;
   var min_dist = 9999999999;
   if ( polyline && polyline.getVertexCount() > 0 )
   {
      for (var i = 0; i < polyline.getVertexCount(); i++) {
         var vert = polyline.getVertex(i);
         var dist = Math.abs(marker.getPoint().x - vert.x) + Math.abs(marker.getPoint().y - vert.y);
         
         if ( dist < min_dist )
         {
            min_dist = dist;
            closest = i;
         }
      }
      return polyline.getVertex(closest);
   } else {
      return marker.getPoint();  
   }
   
}
   
function drawPolyline(type,id)
{
   today=new Date()
   var url = "/track/points.php?t=" + today.getTime();
   if ( type && id )
   {
      url += "&type=" + type + "&id=" + id;  
   }
   // Read the points from the db
   var request = GXmlHttp.create();
   request.open("GET", url, true);
   request.onreadystatechange = function() {
   if (request.readyState == 4) {
       var xmlDoc = request.responseXML;
   
       // obtain the array of markers and loop through it
       var markers = xmlDoc.documentElement.getElementsByTagName("point");
       
       points = [];
       bounds = new GLatLngBounds();
       for (var i = 0; i < markers.length; i++) {
         var id = parseInt(markers[i].getAttribute("id"));
         var lat = parseFloat(markers[i].getAttribute("lat"));
         var lon = parseFloat(markers[i].getAttribute("lon"));
         var p = new GLatLng(lat,lon);
         p.internalId = id; // db id
         p.indexId = i; // index into points
         points.push(p);
         bounds.extend(p);
         //GLog.write("Adding point " + p.toString() 
         //   + "(" + p.internalId + "," + p.indexId + ")");
         
         if ( i == 0 && type != 'leg' && type != 'todate')
         {
             var current_marker = createMarker(p,lat + "," + lon);
             current_marker.id='current';
             map.addOverlay(current_marker);   
             //GLog.write("Added marker at " + p.toString());
         }
       }
       
       // add the line
       //GLog.write("Creating polyline with " + points.length + " points");
       polyline = new GPolyline(points);
       map.addOverlay(polyline);
       map.setZoom(map.getBoundsZoomLevel(bounds));
       map.setCenter(bounds.getCenter());
       
       if ( type == "leg" )
       {
          createStartMarker(points[points.length-1]);
          createStopMarker(points[0]);
       }
     }
   }
   request.send(null);       
}

function getLegData(id)
{
   today=new Date()
   var url = "/track/legs.php?t=" + today.getTime() + "&id=" + id;
   var request = GXmlHttp.create();
   request.open("GET", url, true);
   request.onreadystatechange = function() {
     if (request.readyState == 4) {
       var xmlDoc = request.responseXML;
       var legs = xmlDoc.documentElement.getElementsByTagName("leg");
          
       if ( legs.length > 0 ) {
         var id = parseInt(legs[0].getAttribute("id"));
         var name = legs[0].getAttribute("name");
         var comment = GXml.value(legs[0].getElementsByTagName("comment")[0]);
         
         if ( document.CreateLeg )
         {  // admin
            document.CreateLeg.name.value = name;
            document.CreateLeg.comment.value = comment;
            document.CreateLeg.id.value = id;
         } else {
            // tracker
            document.getElementById("mode").innerHTML = name;
            setHelp(comment);  
         }
       }
     }
   }
   request.send(null);      
}

function unload() {
 GUnload();
}
function setHelp(msg) { 
 document.getElementById("help").innerHTML = "<p>" + msg + "</p>";
}
