var basedir = '/'; // change into '/' before live!

// Expand/collapse for navigation sidebar
function chapter_toggle(e) {
  var div = Event.element(e).parentNode.parentNode;
  $(div).toggleClassName('expanded');
  $(div).toggleClassName('collapsed');
}

// Show footnote
function footnote_show(e) {
  var sup = Event.element(e);
  Event.observe(sup,'mouseout',footnote_hide);
  var re = new RegExp(/\d+/);
  var id = re.exec(sup.innerHTML) - 1;
  footnote_timeout = setTimeout("footnote_show2("+id+")",250);
  if($('footnotes').immediateDescendants()[id]) {
    if($('footnote')) $('footnote').remove();
    var pos = Position.cumulativeOffset($(sup));
    var dim = $(sup).getDimensions();
    var box = document.createElement('div');
    box['id']='footnote';
    box['innerHTML'] = $('footnotes').immediateDescendants()[id].innerHTML;
    box['style']['top'] = (pos[1] + dim.height + 10) + 'px';
    box['style']['display'] = 'none';
    if(Position.within($(document.body), pos[0] + dim.width + 400, pos[1]) ==  false)
      box['style']['right'] = '10px';
    else
      box['style']['left'] = (pos[0] + dim.width) + 'px';
    document.body.appendChild(box);
    // Start timeout
    setTimeout("footnote_show2()",250);
  }
}

function footnote_show2() {
  if($('footnote')) $('footnote').show();
}

// Hide footnote
function footnote_hide() {
  if($('footnote')) $('footnote').remove();
}

// Create onload event listeners
Event.observe(window, 'load', function() {
  // Expand/collapse for navigation sidebar
  if($('sidebar')) {
    $('sidebar').select('div.chapter').each(function(i){
      var s = $(i).select('span');
      var span = s[0];
      if(span){
        Event.observe(span, 'click', chapter_toggle.bindAsEventListener(span));
      }
    });
  
    // Footnotes
    $('main').select('sup.footnote').each(function(i) {
      Event.observe(i,'mouseover',footnote_show.bindAsEventListener(i));
    });
  }
  
  // VOC abbr
  // set_abbr();
});

function show_all_footnotes() {
  if($('all_footnotes')) {
    $('all_footnotes').toggle();
  } else {
    var ol = document.createElement('ol');
    ol['id'] = 'all_footnotes';
    $('footnotes').immediateDescendants().each(function(i) {
      var li = document.createElement('li');
      li['innerHTML'] = i.innerHTML;
      ol.appendChild(li);
    });
    $('main').insertBefore(ol, $('main').select('.prevnextup').last());
  }
}

/*
function set_abbr(){
  var searches = new Array('VOC');
  var befores = new Array('<abbr title="Verenigde Oost-Indische Compagnie (Dutch East India Company)">');
  var afters = new Array('</abbr>');
  for(var c=0; c<searches.length; c++) {
    var newText = '';
    var i = -1;
    var searchTerm = searches[c];
    var bodyText = $('main').innerHTML;
    var highlightStartTag = befores[c];
    var highlightEndTag = afters[c];
    while (bodyText.length > 0) {
      i = bodyText.indexOf(searchTerm, i+1);
      if (i < 0) {
        newText += bodyText;
        bodyText = '';
      } else {
        if (bodyText.lastIndexOf(">", i) >= bodyText.lastIndexOf("<", i)) {
          if (bodyText.lastIndexOf("/script>", i) >= bodyText.lastIndexOf("<script", i)) {
            newText += bodyText.substring(0, i) + highlightStartTag + bodyText.substr(i, searchTerm.length) + highlightEndTag;
            bodyText = bodyText.substr(i + searchTerm.length);
            i = -1;
          }
        }
      }
    }
    $('main').update(newText);
  }
}
*/

// Global map vars
var map;
var tooltip;
var loadedxml;
var zoomlevel;
var icon_region;
var icon_overview;
var icon_standard;
var gmarkers = [];

function init_map() {
  if (GBrowserIsCompatible()) {
    
    /*
    // Scroll to map (#m) if no hash in url
    if(!location.hash) window.location = window.location + '#m';
    */
    
    // Set up map
    map = new GMap2(document.getElementById("map"));
    map.setCenter(new GLatLng(26.4312,4.2188),2);
    map.setMapType(G_SATELLITE_MAP);
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.addControl(new GScaleControl());
    map.enableDoubleClickZoom();
    map.enableContinuousZoom();
    
    // Set up tooltip
    tooltip = document.createElement('div');
    tooltip['className'] = 'tooltip';
    tooltip['style']['display']='none';
    map.getPane(G_MAP_FLOAT_PANE).appendChild(tooltip);
    
    // Set up various types of icons
    icon_region = new GIcon();
    icon_region.image = basedir+'img/map/green-dot.png';
    icon_region.shadow = basedir+'img/map/shadow50.png';
    icon_region.iconSize=new GSize(32,32);
    icon_region.shadowSize=new GSize(56,32);
    icon_region.iconAnchor=new GPoint(16,32);
    icon_region.infoWindowAnchor=new GPoint(16,0);
    
    icon_overview = new GIcon();
    icon_overview.image = basedir+'img/map/overview.png';
    icon_overview.shadow = basedir+'img/map/overviews.png';
    icon_overview.iconSize=new GSize(32,32);
    icon_overview.shadowSize=new GSize(56,32);
    icon_overview.iconAnchor=new GPoint(16,32);
    icon_overview.infoWindowAnchor=new GPoint(16,0);
    
    icon_standard = new GIcon();
    icon_standard.image = basedir+'img/map/mm_20_red.png';
    icon_standard.shadow = basedir+'img/map/mm_20_shadow.png';
    icon_standard.iconSize = new GSize(12, 20);
    icon_standard.shadowSize = new GSize(22, 20);
    icon_standard.iconAnchor = new GPoint(6, 20);
    icon_standard.infoWindowAnchor = new GPoint(5,1);
    
    // Load initial data, based on hash
    var hash = self.document.location.hash.substring(1);
    if(hash && hash!='legend' && hash!='instructions') {
      // Insert 'back' link right above map
      $('map').insert({'before': '<a href="#" onclick="history.back();return false;">Back to previous page</a>'});
      if(hash.include(':')) {
        var xml = hash.substring(0, hash.indexOf(':')) + '.xml';
        var loc = hash.substring(hash.indexOf(':')+1);
      } else {
        var xml = hash + '.xml';
      }
      load_xml('index.xml', false, xml);
      load_xml(xml, loc);
      window.location.hash = '#m';
      window.location.hash = '#'+ hash;
    } else {
      load_xml('index.xml');
    }

  } else alert('Your browser is not compatible with Google Maps.');
}

function load_xml(xmlfile, opentitle, nodisplay) {
  
  // Clear map & sidebar if (re)loading index.xml
  if(xmlfile == 'index.xml') {
    map.clearOverlays();
    $$('#sidebar .chapter ul').each(function(ul) {
      ul.update('');
    });
  }

  // Hide tooltip
  tooltip['style']['display']='none';
  
  // Remove map zoom listener
  map_remove_zoom_listener();
  
  // Open XML file
  GDownloadUrl(basedir + "xml/"+xmlfile, function(data, responseCode) {
    var bounds = new GLatLngBounds();
    var xml = GXml.parse(data);
    // Set the title of this map in the DOM
    var maptitle = xml.documentElement.getElementsByTagName("title");
    if(maptitle[0]) {
      var newmaptitle = ': ' + maptitle[0].getAttribute("value");
    } else {
      var newmaptitle = ': Overview';
    }
    $('maptitle').update(newmaptitle);
    
    var markers = xml.documentElement.getElementsByTagName("marker");
    // Loop through markers and add to map
    for (var i = 0; i < markers.length; i++) {
      var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                              parseFloat(markers[i].getAttribute("lon")));
      var title = markers[i].getAttribute("title");
      var html = markers[i].getAttribute("content");
      var onclick = markers[i].getAttribute("onclick");
      var type = markers[i].getAttribute('type');
      // Check if we should open this marker
      if(opentitle) {
        var re = new RegExp("^"+ opentitle +"$","i");
        if(title.match(re)) var trigger = true;
        else var trigger = false;
      }
      // Check if we should hide this marker (for first load of index.xml and preloaded is e.g. africa.xml)
      if(nodisplay && onclick && nodisplay == onclick) var hide = true;
      else var hide = false;
      
      // Make key for gmarkers[]
      if(onclick) var key = onclick.substring(0, onclick.indexOf('.')); // e.g. 'africa'
      else var key = xmlfile.substring(0, xmlfile.indexOf('.')) + i; // e.g. 'africa1'
      
      // Add marker to map and to gmarker
      gmarkers[key] = addmarker(point, title, html, onclick, trigger, hide, type);
      bounds.extend(point);
      
      // Add sidebar handle
      if(onclick) {
        if(!$('xml_'+ onclick.substring(0, onclick.indexOf('.')))) {
          $('sidebar').update($('sidebar').innerHTML + '<div class="chapter" id="xml_'+ onclick.substring(0, onclick.indexOf('.')) +'"><div class="title"><a href="#'+ onclick.substring(0, onclick.indexOf('.')) +'" onclick="sidebar_click(\''+ key +'\');">'+ title +'</a></div><ul></ul></div>');
        }
      } else {
        if(!$('xml_'+ xmlfile.substring(0, xmlfile.indexOf('.')) +'_'+ i)) {
          var ul = $$('#xml_'+ xmlfile.substring(0, xmlfile.indexOf('.')) +' ul')[0];
          ul.update(ul.innerHTML + '<li id="xml_'+ xmlfile.substring(0, xmlfile.indexOf('.')) +'_'+ i +'"><a href="#'+ xmlfile.substring(0, xmlfile.indexOf('.')) + ':' + encodeURI(title.toLowerCase()) +'" onclick="sidebar_click(\''+ key +'\');">'+ title +'</a></li>');
        }
      }
    }
    
    // Autocenter/zoom
    var b = bounds;
    var t = b.toSpan();
    if (!b.isEmpty() && (t.lat() != 0 || t.lng() != 0)) {
      map.setZoom(map.getBoundsZoomLevel(b)-1);
      map.setCenter(b.getCenter());
    }
    
    // Remember map status
    loadedxml = xmlfile;
    zoomlevel = map.getZoom();
    
    // Add map zoom listener
    map_add_zoom_listener();
  });
}

function addmarker(point,title,html,onclick, trigger, hide, type) {
  // Define type of icon based on type
  var icon = icon_standard;
  if(type) {
    if(type == 'region') var icon = icon_region;
    if(type == 'overview') var icon = icon_overview;
  }
  var m = new GMarker(point, icon);
  m.tooltip = '<strong>' + title + '</strong><br/>' + (onclick ? html : 'Click for details');
  
  // Click listener
  GEvent.addListener(m, "click", function() {
    if(onclick){
      load_xml(onclick);
      m.hide();
    } else {
      m.openInfoWindowHtml('<div class="balloon" style="max-height:375px;overflow:auto;"><strong>' + title + '</strong> <small>(<a href="#" onclick="map.setCenter(new GLatLng('+ point.lat() +','+ point.lng() +'), map.getZoom() + 3);return false;">zoom</a>)</small><br/><br/>' + html+'</div>', {maxWidth:500});
    }
  });
  
  // Mouseover => show tooltip
  GEvent.addListener(m, 'mouseover', function() {
    tooltip.innerHTML = m.tooltip;
    var p=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
    var o=map.getCurrentMapType().getProjection().fromLatLngToPixel(m.getPoint(),map.getZoom());
    var a=m.getIcon().iconAnchor;
    var w=m.getIcon().iconSize.width;
    var h=tooltip.clientHeight;
    var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(o.x - p.x - a.x + w, o.y - p.y -a.y -h)); 
    pos.apply(tooltip);
    tooltip['style']['display']='block';
  });
  
  // Mouseout => hide tooltip
  GEvent.addListener(m, 'mouseout', function() {
    tooltip['style']['display']='none';
  });
  
  // Add marker to map
  map.addOverlay(m);
  
  // Zoomed in to a city via URL? Open it, and zoom in.
  if(trigger) {
    GEvent.trigger(m,'click');
  }
  
  // Do not display this marker?
  if(hide) {
    m.hide();
  }
  
  return m;
  
}

// Listens to zoom actions. Loads index.xml data if zoom level is smaller than previous data zoom level.
function map_add_zoom_listener() {
  GEvent.addListener(map, "zoomend", function(oldlevel,newlevel) {
    if(newlevel<oldlevel && newlevel<3 && loadedxml!='index.xml') {
      load_xml('index.xml');
    }
  });
}

function map_remove_zoom_listener() {
  GEvent.clearListeners(map, "zoomend");
}

function sidebar_click(key) {
  GEvent.trigger(gmarkers[key], "click");
}
