if (typeof W4 == 'undefined' || !W4) {
    var W4 = {};
}

W4.ui = W4.ui || {};

(function() {

  var Event = YAHOO.util.Event;
  var Dom = YAHOO.util.Dom;
  var TextNode = YAHOO.widget.TextNode;
  var JSON = YAHOO.lang.JSON;

  var sites = {
    'Ask about Ireland': 'http://www.askaboutireland.ie/search.xml?query=%22{q}%22',
    'Irish Resources in the Humanities': 'http://irith.org/irith.service?request=search&query={q}',
    'CELT (Corpus of Electronic Texts)': 'http://www.google.com/cse?cx=015080749438202091167:j3njhim80qu&q={q}&filter=0',
    'COPAC': 'http://copac.ac.uk/wzgw?form=qs&fs=Search&any={q}',
    'Google Books': 'http://books.google.com/books?q={q}',
    'Google Scholar': 'http://scholar.google.com/scholar?q={q}',
    'Wikipedia': 'http://en.wikipedia.org/wiki/Special:Search?search={q}'
  };

  W4.ui.EntityMenu = function(id) {
    if (arguments.length) {
      this.init(id);
    }
  };

  W4.ui.EntityMenu.prototype = {
    
    init: function(id) {
      _initEntityMenu.apply(this, arguments);
    },

    /**
     * Adds an array of entity detections to the menu (but does not refresh
     * the view).
     *
     * @method update
     * @param {Array} detections  an array of entity detections
     */
    update: function(detections) {
      for (var i = 0; i < detections.length; i++) {
        var detection = detections[i];
        var dict = this._entities[HEADINGS[detection.type]];
        if (! YAHOO.lang.hasOwnProperty(dict, detection.name)) {
          dict[detection.name] = {};
        }
        var key = detection.resource + JSON.stringify(detection.locator);
        dict[detection.name][key] = [detection.resource, detection.locator];
      }
    },

    /**
     * Refreshes the menu view. Call this after updating the menu to show the
     * updated information.
     *
     * @method refresh
     */
    refresh: function() {
      for (var w in this._entities) {
        var list = document.getElementById(w);
        var count = 0;
        for (var name in this._entities[w]) {
          var id = name.replace(/[^\w]/g, '');
          var item = document.getElementById(id);
          if (item == null) {
            item = document.createElement('li');
            item.id = id;
            item.name = name;
            item.className = 'entity';
            var html = '<div>';
            html += '<div class="entity-name"><span>' + name + '</span></div>';
            html += '<div class="entity-links" id="' + id + '-links"></div>';
            item.innerHTML = html;
            list.appendChild(item);
            var tree = new YAHOO.widget.TreeView(id + '-links');
            var root = new TextNode('Links to more info', tree.getRoot());
            var values = { q: encodeURIComponent(name) };
            for (var site in sites) {
              var node = new TextNode(site, root);
              node.href = YAHOO.lang.substitute(sites[site], values);
              node.target = '_blank';
            }
            tree.draw();
          }
          count++;
        }
        if (count > 0) {
          var none = document.getElementById(w + '-none');
          if (none) {
            none.parentNode.removeChild(none);
          }
        }
      }
    },

    /**
     * Returns the text locations where the currently selected entity has been
     * detected.
     *
     * @method getSelectedEntityLocations
     * @return {Array} an array of page ID + locator object pairs
     */
    getSelectedEntityLocations: function() {
      var locators = [];
      var name = this._selected.name;
      for (var w in this._entities) {
        if (! YAHOO.lang.hasOwnProperty(this._entities[w], name)) {
          continue;
        }
        for (var key in this._entities[w][name]) {
          var resource = this._entities[w][name][key][0];
          var locator = this._entities[w][name][key][1];
          var page_id = resource.split('#')[1];
          locators.push([page_id, locator]);
        }
      }
      return locators;
    }

  };

  YAHOO.lang.augment(W4.ui.EntityMenu, YAHOO.util.EventProvider); 

  // Map entity types to W4 menu headings.
  var HEADINGS = {
    'person': 'who',
    'city': 'where',
    'country': 'where'
  };

  var _initEntityMenu = function(id) {
    this.id = id;
    this._entities = { what: {}, where: {}, when: {}, who: {} };
    this._selected = null;
    Event.on(id, 'mouseover', _onMouseover, this, true);
    this.createEvent('select');
  };

  var _clearSelection = function(e) {
    if (Dom.isAncestor(this.id, Event.getTarget(e))) { return; }
    Event.removeListener(document, 'mousedown', _clearSelection);
    if (this._selected) {
      Dom.removeClass(this._selected, 'selected');
    }
    this._selected = null;
  };

  var _onMouseover = function(e) {
    var target = Event.getTarget(e);
    while (target.id != this.id) {
      if (target.nodeName.toUpperCase() == 'LI' && 
          target.className == 'entity') {
        if (this._selected) {
          if (target.id == this._selected.id) { break; }
          Dom.removeClass(this._selected, 'selected');
        }
        Dom.addClass(target, 'selected');
        this._selected = target;
        Event.addListener(document, 'mousedown', _clearSelection, this, true);
        this.fireEvent('select', { target: target });
        break;
      }
      target = target.parentNode;
    }
  };


})();
