/**
 * @param type {Subtype of Detail}
 *      E.g. Person, Event, Place
 * @param navFunc {Function}
 * @param errorCallback {Function(e)}
 */
function listAll(p) {
  try {
    assert(typeof(p.type) == "function", "type parameter missing");
    assert(typeof(p.navFunc) == "function", "need navFunc");
    assert(typeof(p.errorCallback) == "function", "need errorCallback");
    var typename = p.type.prototype.typename;
    changePage("main-sub-page", null);
    var $container = $("#main-sub-page");
    $container.empty();
    var navFunc = p.navFunc;
    p.navFunc = function() {
      $container.empty();
      navFunc.apply(null, arguments);
    };
    uiSectionTitle({
      container: $container,
      text : tr("mainpage.listall." + typename + ".title"),
    });
    gStorage.getAll(p.type, function(objs) {
      objs.sort(function(a, b) { return a.compare(b); });
      p.container = $container;
      p.objs = objs;
      if (p.type == Person) {
        listAllPersons(p);
      } else if (p.type == Event) {
        listAllEvents(p);
      } else if (p.type == Place) {
        listAllPlaces(p);
      }
    }, p.errorCallback);
  } catch (e) { p.errorCallback(e); }
}

/**
 * @param container {JQuery element}
 * @param objs {Array of Person}
 * @param navFunc {Function}
 */
function listAllPersons(p) {
  assert(typeof(p.type) == "function", "type parameter missing");
  assert(typeof(p.objs.length) == "number");
  assert( !p.objs[0] || p.objs[0] instanceof Person);
  assert(typeof(p.navFunc) == "function");
  listAllFound(p);
  uiList({
    container : p.container,
    columns : [
      { label : tr("mainpage.listall.person.name.th"), displayFunc : function(obj) { return obj.name; } },
      { label : tr("mainpage.listall.person.role.th"), displayFunc : function(obj) { return obj.role || ""; } },
      //{ label : tr("mainpage.listall.person.father.th"), displayFunc : function(obj) { return obj.father ? obj.father.name : ""; } },
      { label : "Wikipedia ID", displayFunc : function(obj) { return obj.dbpediaID || ""; } },
      { label : "IT book selected", displayFunc : function(obj) { return !obj.idExt || obj.idExt.indexOf("-A") > 5 ? "No" : ""; } },
    ],
    data : p.objs,
    clickFunc : p.navFunc,
  });
}


/**
 * @param container {JQuery element}
 * @param objs {Array of Event}
 * @param navFunc {Function}
 */
function listAllEvents(p) {
  assert(typeof(p.type) == "function", "type parameter missing");
  assert(typeof(p.objs.length) == "number");
  assert( !p.objs[0] || p.objs[0] instanceof Event);
  assert(typeof(p.navFunc) == "function");
  uiTimeline({
    container : $("<div/>").appendTo(p.container),
    events : p.objs,
    navFunc : p.navFunc,
    errorCallback : p.errorCallback,
  });
  listAllFound(p);
  uiList({
    container : p.container,
    columns : [
      { label : tr("mainpage.listall.event.name.th"), displayFunc : function(obj) { return obj.name; } },
    ],
    data : p.objs,
    clickFunc : p.navFunc,
  });
}


/**
 * @param container {JQuery element}
 * @param objs {Array of Place}
 * @param navFunc {Function}
 */
function listAllPlaces(p) {
  assert(typeof(p.type) == "function", "type parameter missing");
  assert(typeof(p.objs.length) == "number");
  assert( !p.objs[0] || p.objs[0] instanceof Place);
  assert(typeof(p.navFunc) == "function");
  /* TODO Destroy map. Bug: Go here, then to Jesus, map won't appear on latter
  uiMap({
    container : p.container,
    places : p.objs,
    navFunc : p.navFunc,
    errorCallback : p.errorCallback,
  });
  */
  listAllFound(p);
  uiList({
    container : p.container,
    columns : [
      { label : tr("mainpage.listall.place.name.th"), displayFunc : function(obj) { return obj.name; } },
      { label : tr("mainpage.listall.place.role.th"), displayFunc : function(obj) { return obj.role || ""; } },
      { label : "Wikipedia ID", displayFunc : function(obj) { return obj.dbpediaID || ""; } },
      { label : "Location known", displayFunc : function(obj) { return obj.point ? "Yes" : ""; } },
      { label : "IT book selected", displayFunc : function(obj) { return !obj.idExt || obj.idExt.indexOf("-A") > 5 ? "No" : ""; } },
    ],
    data : p.objs,
    clickFunc : p.navFunc,
  });
}

function listAllFound(p) {
  var $total = $("<div class='count'/>").appendTo(p.container);
  $total.text(tr("mainpage.listall.resultCount", [ p.objs.length ]));
}
