/* $Header: e:\CVSROOT/zlibmap/scripts/zlibmap.js,v 1.3 2006/08/14 05:11:45 MMcM Exp $ */

var g_map = null;

REGION = 1;
COUNTRY = 2;
AREA = 3;
LOCALITY = 4;
STREET = 5;

var g_level = LOCALITY;
var g_localNames = true;

var g_timeline = null;

function MapLoad() {
  var mapdiv = document.getElementById("map");
  if (mapdiv == null) return;

  if (!GBrowserIsCompatible()) {
    mapdiv.innerHTML = "This browser is not compatible with Google Maps.";
    return;
  }

  if (typeof(GMap2) == "undefined") {
    mapdiv.innerHTML = "Your browser has only partially loaded Google Maps.  If you are displaying the .XML file directly, you may need to transform it into HTML before display.";
    return;
  }

  g_map = new GMap2(mapdiv);
  g_map.addControl(new GLargeMapControl());
  g_map.addControl(new GMapTypeControl());

  g_map.setCenter(new GLatLng(0,0),0);

  var byid = {};
  var bounds = new GLatLngBounds();
  var levelsUsed = 0;
  var localNames = false;
  for (i in g_places) {
    var place = g_places[i];
    byid[place.id] = place;
    if (place.parentId == null) {
      if (place.level == null)
        place.level = 1;
    }
    else {
      place.parentPlace = byid[place.parentId];
      if ((place.level == null) || (place.level <= place.parentPlace.level))
        place.level = place.parentPlace.level + 1;
      if ((place.parentPlace.coarsestChildLevel == null) ||
          (place.parentPlace.coarsestChildLevel > place.level))
        place.parentPlace.coarsestChildLevel = place.level;
    }
    levelsUsed |= (1 << place.level);
    if (place.localName != null)
      localNames = true;
    if (place.coords != null)
      bounds.extend(place.coords);
  }
  g_map.setZoom(g_map.getBoundsZoomLevel(bounds));
  g_map.setCenter(bounds.getCenter());

  var lcount = 0;
  for (i = REGION; i <= STREET; i++) {
    if ((levelsUsed & (1<<i)) != 0)
      lcount++;
    else {
      var elem = document.getElementById("level_" + i);
      if (elem != null)
        elem.parentNode.removeChild(elem);
    }
  }
  if (lcount == 0) {
    var elem = document.getElementById("levelMenu");
    if (elem != null)
      elem.parentNode.removeChild(elem);
  }

  if (!localNames) {
    var elem = document.getElementById("namesMenu");
    if (elem != null)
      elem.parentNode.removeChild(elem);
  }

  var tldiv = document.getElementById("timeline");
  if (tldiv != null) {
    if (typeof(Timeline) == "undefined") {
      tldiv.innerHTML = "Timeline did not load properly.";
    }
    else {
      g_timeline = createTimeline(tldiv);
    }
  }

  showLocalNames(g_localNames);
}

function getInfoWindowHtml(place) {
  var html = "<table style='width:200px'>";
  html += "<tr class='infoNames'><td";
  if (place.localName == null)
    html += " colspan='2'";
  html += ">";
  html += place.name;
  html += "</td>";
  if (place.localName != null) {
    html += "<td align='right'>";
    html += place.localName;
    html += "</td>";
  }
  html += "</tr>";
  if (place.value != null) {
    html += "<tr class='infoValue'><td align='center' colspan='2'>";
    html += place.value.toString();
    html += "</td></tr>";
  }
  if (place.sourceURL != null) {
    var links = place.sourceURL.split(",");
    html += "<tr class='infoLink'><td align='left' colspan='2'>";
    if (links.length == 1)
      html += "<a href='" + place.sourceURL + "' target='_blank'>link</a> to this book.";
    else {
      html += "Links to these books: ";
      for (i = 1; i <= links.length; i++) {
        if (i > 1) html += "&nbsp;";
        html += "<a href='" + links[i-1] + "' target='_blank'>" + i + "</a>";
      }
    }
    html += "</td></tr>";
  }
  html += "<table>";
  return html;
}

function showLocalNames(localNames) {
  for (i = 0; i <= 1; i++) {
    var div = document.getElementById("localNames_" + i);
    if (div == null) continue;
    var a = div.getElementsByTagName("A")[0];
    if (!!i == !!localNames)
      a.removeAttribute("href");
    else
      a.setAttribute("href", "javascript:showLocalNames(" + i + ")");
  }

  g_localNames = localNames;

  showLevelOfDetail(g_level);
}

var g_icons = [];
for (i = 0; i < 10; i++)
  g_icons[i] = new GIcon(G_DEFAULT_ICON, "../images/marker" + i + ".png");

function showLevelOfDetail(level) {
  for (i = REGION; i <= STREET; i++) {
    var div = document.getElementById("level_" + i);
    if (div == null) continue;
    var a = div.getElementsByTagName("A")[0];
    if (i == level)
      a.removeAttribute("href");
    else
      a.setAttribute("href", "javascript:showLevelOfDetail(" + i + ")");
  }

  g_level = level;

  g_map.clearOverlays();
  g_markerOpts = new Array();

  function createPlaceMarker(place) {
    /**
    if (place.level != g_level)
      alert(place.name + ":" + place.level);
    **/
    var marker = new GMarker(place.coords, place);
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowHtml(getInfoWindowHtml(place));
    });
    return marker;
  }

  var values = new Array();
  for (i in g_places) {
    var place = g_places[i];
    place.visible = false;
    if (place.level > level)
      // Showing coarser; skip this one.
      continue;
    if ((place.level == level) ||
        // When there is a hole, we display the outer as if its level
        // were chosen, not just its own.
        (place.coarsestChildLevel > level)) {
      // Showing exactly this level.
      if (place.aggregateValue != null) {
        place.value = place.aggregateValue;
        place.coords = place.aggregateCenter;
        place.sourceURL = place.aggregateSourceURL;
      }
      else if (place.ownValue != null) {
        place.value = place.ownValue;
        place.coords = place.ownCenter;
        place.sourceURL = place.ownSourceURL;
      }
    }
    else {
      // Showing finer; skip unless has own.
      if (place.ownValue != null) {
        place.value = place.ownValue;
        place.coords = place.ownCenter;
        place.sourceURL = place.ownSourceURL;
      }
      else
        continue;
    }
    if (place.coords != null) {
      place.visible = true;
      if (place.value != null) {
        values.push(place.value);
      }
    }
  }
  // Something like deciles.
  values.sort(function(v1, v2) { 
                return (v1 - v2);
              });
  var thresh = [];
  for (i = 0; i < 9; i++)
    thresh[i] = values[Math.round(values.length * i / 10)];

  for (i in g_places) {
    var place = g_places[i];
    if (!place.visible) continue;

    var title = null;
    if (g_localNames)
      title = place.localName;
    if (title == null)
      title = place.name;
    if (place.value != null) {
      if (title == null)
        title = place.value;
      else
        title += ": " + place.value;
    }
    place.title = title;

    if (place.value == null)
      place.icon = G_DEFAULT_ICON;
    else {
      i = 9;
      while (i > 0) {
        if (place.value >= thresh[i-1])
          break;
        i--;
      }
      place.icon = g_icons[i];
    }

    place.marker = createPlaceMarker(place);
    g_map.addOverlay(place.marker);
  }

  if (g_timeline != null) {
    showTimelineEvents();
  }
}

function MapUnload() {
  GUnload();
  g_map = null;
}

function createTimeline(tldiv) {
  var eventSource = new Timeline.DefaultEventSource();
  var bandInfo = Timeline.createHotZoneBandInfo({
    // TODO: Need some heuristics for the center & hotzone.
    date: Timeline.DateTime.parseGregorianDateTime("1900"),
    zones: [
        { start: "1900",
          end: "2100",
          magnify: 4,
          unit: Timeline.DateTime.DECADE
        }
      ],
    eventSource: eventSource,
    width: "100%",
    intervalUnit: Timeline.DateTime.CENTURY,
    intervalPixels: 200
  });
  bandInfo.eventPainter._onClickInstantEvent = function(icon, domEvt, evt) {
    var place = evt.place;
    place.marker.openInfoWindowHtml(getInfoWindowHtml(place));
  };
  var tl = Timeline.create(tldiv, [ bandInfo ]);
  // Looks like a bug in clear().
  if (eventSource._listeners[0].onClear == null)
    eventSource._listeners[0].onClear = function() {};
  return tl;
}

function showTimelineEvents() {
  var eventSource = g_timeline.getBand(0).getEventSource();
  eventSource.clear();

  for (i in g_places) {
    var place = g_places[i];
    if (!place.visible) continue;

    var year = new Date();
    year.setUTCFullYear(place.value);
    var title = null;
    if (g_localNames)
      title = place.localName;
    if (title == null)
      title = place.name;
    var event = new Timeline.DefaultEventSource
      .Event(year, null, null, null, true,
             title, null, null, place.sourceURL);
    event.place = place;
    place.tlevent = event;
    if (false)
      eventSource.add(event);
    else {
      eventSource._events.add(event);
    }
  }
  for (var i = 0; i < eventSource._listeners.length; i++) {
    eventSource._listeners[i].onAddMany();
  }
}
