/* Google Map Generator (JavaScript) ([...]/httpdocs/resources/journal/map.js)
 *
 * DESCRIPTION:
 * This file contains the javascript component of AJAX code facilitating
 * display of a google map, with the most recent locations and the day's GPS-
 * tracked activities marked, in the user interface for my online journal.
 *
 * AUTHOR:
 * The Confessor <http://confessor.org/contact.php>
 *
 * COPYRIGHT:
 * 2007-2010 The Confessor
 *
 * LICENSE:
 * Use of all or portions of my website source code in your own projects is
 * subject to the terms and conditions listed here:
 * <http://confessor.org/termsofuse.php>
 *
 */

var mapdata_request = null;
var mapdata = {};

var map = null;
var totalbounds = null;

function mapbox_onshow() {
  preservestatus('mapbox','shown');

  if (mapdata_request == null) {
    request_mapdata();
    return;
  }

  initialize_map();
  map.checkResize();
}

function mapbox_onhide() {
  preservestatus('mapbox','hidden');
}

function request_mapdata() {
  mapdata_request = new XMLHttpRequest();
  mapdata_request.onreadystatechange = get_mapdata;
  mapdata_request.open('GET','/resources/journal/map.php?Entry_Date='+dateforreq,true);
  mapdata_request.send(null);
}

function get_mapdata() {
  if(mapdata_request.readyState == 4 && mapdata_request.status == 200) {
    mapdata = eval(mapdata_request.responseText);

    load_script();
  }
}

function load_script() {
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = 'http://maps.google.com/maps?file=api&v=2.x&key=ABQIAAAAQqiDPO0zA8tfKOsT3qzSKhSRg-D7mw3BMRCSivTg3CUZKzQwTBSVkpATDGzMB1zB7nkbqWRe6DzoEA&async=2&callback=load_map';
  document.body.appendChild(script);
}

function load_map() {
  map = new GMap2(document.getElementById('mapdiv'));
  map.addControl(new GSmallZoomControl());

  totalbounds = new GLatLngBounds();

  format_locations(mapdata.locations);
  populate_totalbounds(mapdata.locations);

  format_tracks(mapdata.tracks);
  populate_totalbounds(mapdata.tracks);

  initialize_map();

  populate_map_with_locations(mapdata.locations);
  populate_map_with_tracks(mapdata.tracks);

  map_loaded = true;
}

function format_locations(locations) {
  for(counter=0;counter<locations.length;counter++) {
    locations[counter].coordinates = new GLatLng(locations[counter].latitude, locations[counter].longitude);
    locations[counter].bounds = new GLatLngBounds();
    locations[counter].bounds.extend(locations[counter].coordinates);

    if (locations[counter].isprivate == true) {
      locations[counter].marginoferror = define_margin_of_error(locations[counter]);
    }

    locations[counter].marker = new GMarker(locations[counter].coordinates,{ icon: new GIcon(G_DEFAULT_ICON,'/resources/journal/destination.png'), title: locations[counter].hierarchy });
    add_click_event_to_marker(locations[counter]);
  }
}

function define_margin_of_error(location) {
  var center = location.coordinates;
  var radius = 1.609344;
  var numberofvertices = 20;
  var latConv = center.distanceFrom(new GLatLng(center.lat()+0.1, center.lng()))/100;
  var lngConv = center.distanceFrom(new GLatLng(center.lat(), center.lng()+0.1))/100;
  var step = parseInt(360/numberofvertices);
  var vertices = [];
  for(var i=0; i<=360; i+=step) {
    var vertice = new GLatLng(center.lat() + (radius/latConv * Math.cos(i * Math.PI/180)), center.lng() + (radius/lngConv * Math.sin(i * Math.PI/180)));
    vertices.push(vertice);
    location.bounds.extend(vertice);
  }
  return new GPolygon(vertices, '#000000', 0, 1, '#F8F8FF', 0.50);
}

function add_click_event_to_marker(location) {
  GEvent.addListener(location.marker, 'click', function() {map.setCenter(location.bounds.getCenter(), map.getBoundsZoomLevel(location.bounds));});
}

function format_tracks(tracks) {
  for(countera=0;countera<tracks.length;countera++) {
    tracks[countera].coordinatelist = [];
    tracks[countera].bounds = new GLatLngBounds();

    for (counterb=0;counterb<tracks[countera].points.length;counterb++) {
      var point = new GLatLng(tracks[countera].points[counterb].latitude, tracks[countera].points[counterb].longitude);
      tracks[countera].coordinatelist.push(point);
      tracks[countera].bounds.extend(point);
    }

    tracks[countera].polyline = new GPolyline(tracks[countera].coordinatelist, '#FF0000',1,.75);
    add_click_event_to_polyline(tracks[countera]);
  }
}

function add_click_event_to_polyline(track) {
  GEvent.addListener(track.polyline, 'click', function() {map.setCenter(track.bounds.getCenter(), map.getBoundsZoomLevel(track.bounds));});
}

function populate_totalbounds(locs_or_trks) {
  for(counter=0;counter<locs_or_trks.length;counter++) {
    totalbounds.extend(locs_or_trks[counter].bounds.getNorthEast());
    totalbounds.extend(locs_or_trks[counter].bounds.getSouthWest());
  }
}

function initialize_map() {
  map.setCenter(totalbounds.getCenter(), map.getBoundsZoomLevel(totalbounds));
}

function populate_map_with_locations(locations) {
  for(counter=0;counter<locations.length;counter++) {
    map.addOverlay(locations[counter].marker);
    if (locations[counter].isprivate == true) {map.addOverlay(locations[counter].marginoferror);}
  }
}

function populate_map_with_tracks(tracks) {
  for(counter=0;counter<tracks.length;counter++) {
    map.addOverlay(tracks[counter].polyline);
  }
}
