$('#activity').append('<ul id=entries><li>Loading...</ul>');

var activity_events = [];

function ins_dl(data) {
  ins(data.map(function (item) {
    var x = [item.dt];
    x.body = '<p><a href="' + item.u + '">' + item.d + '</a></p>';
    x.feed_url = 'http://del.icio.us/krarick';
    x.sprite = 1;
    if (item.n) x.body += '<p class=note>&#8220;' + item.n +
                          '&#8221; &mdash;Keith</p>';
    return x;
  }));
}

function ins_gr(data) {
  const google_id = '00989336373167826616';
  ins(data.items.map(function (item) {
    var x = [date2iso(item.updated)];
    x.body = '<p><a href="' + item.alternate.href + '">' + item.title +
             '</a></p>';
    x.body += item.annotations.map(function (ann) {
      var author = ann.author, i = author.indexOf(' ');
      if (i > 0) author = author.substr(0, i);
      return '<p class=note>&#8220;' + ann.content +
             '&#8221; &mdash;' + author + '</p>';
    }).join('');
    var summary = item.summary || item.content;
    summary = summary.substr(summary.lastIndexOf('\n\n') + 2);
    x.body += '<p>' + summary + '</p>';
    x.feed_url = 'http://google.com/reader/shared/00989336373167826616';
    x.sprite = 5;
    return x;
  }));
}

function ins_gh_beanstalkd(data) {
  ins_gh('beanstalkd', data);
}

function ins_gh_cubby(data) {
  ins_gh('cubby', data);
}

function ins_gh(repo, data) {
  function day(x) { return x.committed_date.substr(0, 10); }
  ins(group_by(day, data.commits).map(function (items) {
    var x = cluster(items, 1,
    function (x) { return x.committed_date.substr(0, 19) + 'Z' },
    function (x) {
      return '<p>' + repo + ' commit <a href="' + x.url + '">' +
             x.id.substr(0, 6) + '</a></p><p class=note>' + x.message + '</p>';
    });

    if (x.extra.length > 0) {
      x.body += '<p><a href=http://github.com/kr/beanstalkd/commits/master>And ' +
                x.extra.length + ' more...</a></p>';
    }
    x.feed_url = 'http://github.com/kr';
    x.sprite = 4;
    return x;
  }));
}

function ins_fl(data) {
  function day(photo) { return date2iso(photo.dateupload).substr(0, 10); }
  const flickr_base = 'http://flickr.com/photos/keithrarick/';

  if (data.stat != 'ok') return;
  ins(group_by(day, data.photos.photo).map(function (items) {
    var x = cluster(items, 5, function(x) { return date2iso(x.dateupload); },
    function (x) {
      return '<li><a href="' + flickr_base + x.id +
             '"><img src="http://farm' + x.farm +
             '.static.flickr.com/' + x.server +
             '/' + x.id + '_' + x.secret + '_s.jpg"></a>';
    });
    x.body = '<ul class=flickr>' + x.body + '</ul>';

    if (x.extra.length > 0) {
      x.body += '<p class=more><a href="' + flickr_base +
                'archives/date-posted/' + iso2slashes(x[0]) +
                '/">And ' + x.extra.length + ' more...</a></p>';
    }
    x.feed_url = flickr_base;
    x.sprite = 2;
    return x;
  }));
}

function ins_as(data) {
  function day(track) { return date2iso(track.date.uts).substr(0, 10); }

  if (data.error) return;
  ins(group_by(day, data.recenttracks.track).map(function (items) {

    var seen = {};
    var x = cluster(items, 8, function (t) {return date2iso(t.date.uts)},
    function (x) {
      var img = x.image[0]['#text'];
      if (img == '') return false;
      if (seen[img]) return false;
      seen[img] = true;
      return '<li><a href="' + x.url + '" title="' + x.name +
             ' &ndash; ' + x.artist['#text'] + '"><img alt="' + x.name +
             '" src="' + img + '"></a>';
    });
    if (x.body != '') x.body = '<ul class="lastfm icons">' + x.body + '</ul>';
    x.feed_url = 'http://last.fm/user/krarick';
    x.sprite = 7;
    return x;
  }));
}

function pad(i) {
  if (i < 10) return '0' + i;
  return '' + i;
}

function date2iso(stamp) {
  var time = new Date(parseInt(stamp) * 1000);
  return time.getUTCFullYear() + '-' +
         pad(time.getUTCMonth() + 1) + '-' +
         pad(time.getUTCDate()) + 'T' +
         pad(time.getUTCHours()) + ':' +
         pad(time.getUTCMinutes()) + ':' +
         pad(time.getUTCSeconds()) + 'Z';
}

function iso2h(ds) {
  var parsed = ds.match(/^(\d{4})-(\d{2})-(\d{2})/);
  if (!parsed) return '';
  return parsed[3] + ' ' + [
    null, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
    'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
  ][parseInt(parsed[2], 10)] + ' ' + parsed[1];
}

function iso2slashes(ds) {
  var parsed = ds.match(/^(\d{4})-(\d{2})-(\d{2})/);
  if (!parsed) return '';
  return parsed[1] + '/' + parsed[2] + '/' + parsed[3];
}

function ins(events) {
  function has_content(x) { return (x.body != ''); }

  activity_events = activity_events.concat(events).filter(has_content);
  activity_events.sort().reverse().splice(10);

  var last_date = '';
  activity_events.forEach(function (event) {
    var dt = iso2h(event[0]);
    event.show_date = '';
    if (dt != last_date) last_date = event.show_date = dt;
  });

  $('#entries').html(activity_events.map(format).join(''));
}

function format(event) {
  var show_date = '';
  if (event.show_date) {
    show_date = '<div class=date>' + event.show_date + '</div>';
  }

  var icon = '<a href="' + event.feed_url + '"' +
             ' sprite=' + event.sprite + '>' +
             '</a>';

  return '<li>' + show_date + icon + '<div class=body>' + event.body + '</div>';
}

function cluster(items, n, date_f, body_f) {
  function I(x) { return x }
  function xlate(pair) { return body_f(pair[1]) }
  var sorted = items.map(function (item) {return [date_f(item), item]})
               .sort().reverse();
  var x = [sorted.length > 0 ? sorted[0][0] : ''];
  x.extra = sorted.map(xlate).filter(I);
  x.body = x.extra.splice(0, n).join('');
  return x;
}

function group_by(f, list) {
  var groups = {}, keys = [];
  list.forEach(function (item) {
    var key = f(item);
    if (!groups.hasOwnProperty(key)) {
      groups[key] = [];
      keys.push(key);
    }
    groups[key].push(item);
  });
  return keys.map(function (key) { return groups[key] });
}

