/**
 * Creates the UI that shows a timeline.
 * Events are displayed on the timeline, and are clickable.
 * The timeline is also zoomable.
 *
 * Creates:
 * </>
 *
 * Depends on: TimelineJS timeline.js
 *    <http://timeline.verite.co/> <https://github.com/VeriteCo/TimelineJS>
 *
 * @param container {jquery DOM Element}   <div> where to add the UI
 * @param events {Array of Event}   The events to display
 * @param navFunc {Function}   Called when the user
 *     clicks on an event.
 * * @param errorCallback {Function}
 */
function uiTimeline(p) {
  assert(p.container, "div: need element");
  assert(p.events.length > 0, "events: needed");
  assert(p.events[0] instanceof Event, "events: wrong type");
  assert(typeof(p.navFunc) == "function", "navFunc: need function");
  assert(typeof(p.errorCallback) == "function", "errorCallback: need function");

  runAsync(function() {
    ddebug("timeline for " + p.events.map(function(e) { return e.name; }).join(", ") + "-");
    var data = p.events
        .filter(function(event) { return event.time; }) // only if has .time
        .map(function(event) {
          return { // map to what the widget expects
            start : event.time,
            content : event.name,
            className : event.timePlusMinus ? "estimate" : "exact",
            event : event,
          };
        });
    ddebug("left with " + data.map(function(e) { return e.content; }).join(", ") + "-");
    if (data.length == 0) {
      return;
    }

    var divE = $("<div class='timeline'/>").appendTo(p.container).get(0);
    var timeline = new links.Timeline(divE);
    timeline.options.showNavigation = true;
    //timeline.options.cluster = true;
    timeline.draw(data, options = {
        width :  "100%",
        height : "150px",
        style : "box",
    });
    links.events.addListener(timeline, "select", function(ev) {
      try {
        var sel = timeline.getSelection();
        if (sel.length == 0) {
          return;
        }
        var index = sel[0].row;
        var event = data[index].event;
        assert(event instanceof Event);

        p.navFunc(event);
      } catch (e) { p.errorCallback(e); }
    });
  }, p.errorCallback);
}
