﻿jQuery.fn.showTweets = function (users, numTweetsFetch, numTweetsShow, showRetweets) {

  var url = "http://search.twitter.com/search.json";
  var div = $(this[0]);

  // Show the waiting message
  div.showWaiting(true);

  // Build the list of user feeds
  url += '?q=from%3a' + users.join('+OR+from%3a');

  // Limit the number of tweets returned
  url += '&rpp=' + numTweetsFetch;

  // Call Twitter
  jQuery.getJSON(url + "&callback=?", function (data) {
    div.buildResults(data, numTweetsShow, showRetweets);
    div.showWaiting(false);
  });
}

jQuery.fn.showWaiting = function (state) {
  var div = $(this[0]);
  if (state) {
    div.find('div.loading').css('display', 'block');
    div.find('div.results').css('display', 'none');
  } else {
    div.find('div.loading').css('display', 'none');
    div.find('div.results').css('display', 'block');
  }
}

jQuery.fn.buildResults = function (data, numTweetsShow, showRetweets) {
  var div = $(this[0]);
  var i;
  var displayed = 0;
  for (i = 0; i < data.results.length; ++i) {
    if (displayed >= numTweetsShow)
      break;
    if ((!showRetweets) && (data.results[i].text.substr(0, 2) == "RT"))
      continue;
    div.find('div.results').buildResultsRow(data.results[i]);
    ++displayed;
  }
}

jQuery.fn.buildResultsRow = function (datarow) {
  var div = $(this[0]);
  var name = '<a href="http://twitter.com/' + datarow.from_user + '">' + datarow.from_user + '</a>';
  var time = new Date(datarow.created_at).timeSince();
  var text = datarow.text.formatTwitter();
  div.append('<div class="tweet"></div>');
  div.find('div.tweet:last').append('<div class="name">' + name + '</div>');
  div.find('div.tweet:last').append('<div class="time">' + time + '</div>');
  div.find('div.tweet:last').append('<div style="clear:both;"></div>');
  div.find('div.tweet:last').append('<div class="text">' + text + '</div>');
}

String.prototype.formatTwitter = function () {
  // See http://dev.twitter.com/pages/display_guidelines
  var text = this;
  var str = null;
  while (str = text.nextString(str)) {
    var newstr = null;
    if (str.string[0] == '@')
      newstr = '<a href="http://twitter.com/' + str.string.substr(1) + '">' + str.string + '</a>';
    else if (str.string.isHashTag())
      newstr = '<a href="http://twitter.com/#search?q=%23' + str.string.substr(1) + '">' + str.string + '</a>';
    else if ((str.string.substr(0, 7) == 'http://') || (str.string.substr(0, 8) == 'https://'))
      newstr = '<a href="' + str.string + '">' + str.string + '</a>';
    if (newstr != null) {
      text = text.replaceAt(newstr, str.start, str.length);
      str.string = newstr;
      str.length = newstr.length;
    }
  }
  return text;
}

String.prototype.isHashTag = function () {
  var str = this;
  if (str.length < 2)
    return false;
  if (str[0] != '#')
    return false;
  if ((str[1] >= '0') && (str[1] <= '9'))
    return false;
  return true;
}

String.prototype._findWhiteSpace = function (mode, start) {

  if (start == null)
    start = 0;

  var length = this.length;

  for (; start < length; ++start) {
    switch (this[start]) {
      case ' ':
      case '\t':
        if (mode == true)
          return start;
        break;
      default:
        if (mode == false)
          return start;
    }
  }

  return -1;
}

String.prototype.findWhitespace = function (start) {
  return this._findWhiteSpace(true, start);
}

String.prototype.findNonWhitespace = function (start) {
  return this._findWhiteSpace(false, start);
}

String.prototype.nextString = function (str) {
  if (str == null)
    str = { "string": "", "start": 0, "length": 0 };
  str.start = this.findNonWhitespace(str.start + str.length);
  if (str.start == -1)
    return null;
  var end = this.findWhitespace(str.start);
  if (end == -1)
    end = this.length;
  str.length = end - str.start;
  str.string = this.substr(str.start, str.length);
  return str;
}

String.prototype.replaceAt = function (newstring, start, length) {
  var result = "";
  if (start > 0)
    result += this.substr(0, start);
  result += newstring;
  result += this.substr(start + length);
  return result;
}

Date.prototype.timeSince = function () {
  var now = new Date();
  var seconds = (now - this) / 1000;
  if (seconds < 60)
    return 'less than a minute ago';
  else if (seconds < 120)
    return 'about a minute ago';
  else if (seconds < 3600)
    return 'about ' + Math.floor(seconds / 60) + ' minutes ago';
  else if (seconds < 7200)
    return 'about an hour ago';
  else if (seconds < 24 * 3600)
    return 'about ' + Math.floor(seconds / 3600) + ' hours ago';
  else if (seconds < 2 * 24 * 3600)
    return 'about a day ago';
  else
    return 'about ' + Math.floor(seconds / 24 / 3600) + ' days ago';
}

