(function() {

  var Dom = YAHOO.util.Dom;
  var Event = YAHOO.util.Event;
  var TextNode = YAHOO.widget.TextNode;
  var DataSource = YAHOO.util.DataSource;
  var has = YAHOO.lang.hasOwnProperty;

  var DC_POINT_RE = /east=(.+); north=(.+)/;
  var OMEKA_URI = 'http://gray.ischool.berkeley.edu/omeka/items';
  var ICONS_URI = 'http://www.google.com/intl/en_us/mapfiles/ms/micons/'; 
  var NORMAL_IMG = ICONS_URI + 'blue-dot.png';
  var FEATUR_IMG = ICONS_URI + 'red-dot.png';
  var HILITE_IMG = ICONS_URI + 'yellow-dot.png';
  var SHADOW_IMG = ICONS_URI + 'msmarker.shadow.png';

  YAHOO.widget.Logger.enableBrowserConsole();
  google.load('maps', '2');

  var map;
  var selectedMarker = null;
  var omeka = new DataSource(OMEKA_URI + '?');
  omeka.responseType = DataSource.TYPE_JSON;
  omeka.responseSchema = {
    fields: [ { key: 'id', parser: DataSource.parseNumber },
              { key: 'type_id', parser: DataSource.parseNumber },
	      { key: 'temporal_coverage_start', parser: DataSource.parseDate },
              { key: 'temporal_coverage_end', parser: DataSource.parseDate },
              'title', 'spatial_coverage', 'description' ]
  };
    
  function initLayout() {
    var layout = new YAHOO.widget.Layout({
      units: [
        {
          position: 'top',
          body: 'header',
          height: 70,
          resize: false
        },
        {
          position: 'center',
          body: 'map'
        },
        {
          position: 'right',
          body: 'chronology',
          width: 400,
          scroll: true
        }
      ]
    });
    layout.render();
  }

  function initMap() {
    map = new google.maps.Map2(document.getElementById('map'));
    map.addControl(new google.maps.LargeMapControl());
    map.setCenter(new google.maps.LatLng(39.0, -95.0), 4);
    addMarkers();
  }

  function dcPointToLatLng(dcpoint) {
    var match = DC_POINT_RE.exec(dcpoint);
    if (match) {
      return new google.maps.LatLng(match[2], match[1]);
    }
    return null;
  }

  function loadEventLinks(node, callback) {
    node.tree.setDynamicLoad(null);
    omeka.sendRequest('tags=' + node.data.tag + '&output=json&per_page=50', {
      success: function(req, res) { 
        var count = 0;
        for (var i = 0; i < res.results.length; i++) {
          if (res.results[i].type_id != 8) {
            new TextNode({ 
              label: res.results[i].title, target: '_blank',
              href: OMEKA_URI + '/show/' + res.results[i].id }, node);
            count++;
          }
        }
        if (count == 0) {
          new TextNode({ 
            label: 'No related materials found.', style: 'inactive' }, node);
        }
        callback();
      },
      failure: function(req, res) { 
        YAHOO.log('Request failed.');
          new TextNode({ 
            label: 'No related materials found.', style: 'inactive' }, node);
        callback();
      }
    });
  }

  function addMarkers() {
    var chronology = document.getElementById('chronology');
    var events_by_location = Dom.getChildren(chronology);
    var icon = new google.maps.Icon(G_DEFAULT_ICON);
    icon.iconSize = new google.maps.Size(32, 32);
    icon.iconAnchor = new google.maps.Point(16, 32);
    icon.shadow = SHADOW_IMG;
    icon.shadowSize = new google.maps.Size(59, 32);
    for (var i = 0; i < events_by_location.length; i++) {
      var spatial_coverage = events_by_location[i].id.slice(7);
      var featured = Dom.hasClass(events_by_location[i], 'featured');
      if (featured) { icon.image = FEATUR_IMG; } 
      else { icon.image = NORMAL_IMG; }
      var latlng = dcPointToLatLng(spatial_coverage);
      if (latlng) {
        var m = new google.maps.Marker(latlng, { icon: icon });
        m.event_info = events_by_location[i];
        m.featured = featured;
        google.maps.Event.addListener(m, 'click', function() {
          if (selectedMarker) { 
            selectedMarker.event_info.className = 'hide';
            if (selectedMarker.featured) {
              selectedMarker.setImage(FEATUR_IMG); 
            } else {
              selectedMarker.setImage(NORMAL_IMG); 
            }
          } else {
            document.getElementById('introduction').className = 'hide';
          }
          selectedMarker = this;
          if (! this.initialized) {
            var events = Dom.getChildren(this.event_info);
            for (var i = 0; i < events.length; i++) {
              var links = Dom.get(events[i].id + '-links');
              if (! links) { continue; }
              var tree = new YAHOO.widget.TreeView(links);
              tree.setDynamicLoad(loadEventLinks);
              var t = events[i].getAttribute('title').split(', ');
              var node = new TextNode({ 
                label: 'Related materials', 
                tag: t[1] + '/' + t[0].toLowerCase().replace(' ', '_') }, 
                                      tree.getRoot());
              events[i].removeAttribute('title');
              tree.draw();
            }
            this.initialized = true;
          }
          this.setImage(HILITE_IMG);
          this.event_info.className = 'show';
        });
        map.addOverlay(m);
      }
    }
  }

  Event.onDOMReady(function() {
    initLayout();
    initMap();
  });

})();
