function twitter(selector, url, limit) {
  var removeUsernamePrefix = function(d) {return d.replace(/^[a-zA-Z0-9_]+: /, '');};
  var linkifyURLs = function(d) {return d.replace(/(https?:\/\/([-\w\.]+)+(:\d+)?(\/([-\w/_\.]*(\?\S+)?)?)?)/g, '<a href="$1">$1</a>');}
  var linkifyUsernames = function(d) {return d.replace(/(^|\s)@([a-zA-Z0-9_]+)/g,'$1@<a href="http://twitter.com/$2">$2</a>');}
  var linkifyHashtags = function(d) {return d.replace(/(^|\s)#([a-zA-Z0-9_]+)/g,'$1@<a href="http://twitter.com/#!/search/%23$2">$2</a>');}
  var mapItemDesc = function(d) {return linkifyHashtags(linkifyUsernames(linkifyURLs(removeUsernamePrefix(d))));}
  feed(selector, url, limit, false, mapItemDesc);
}

function feed(selector, url, limit, showItemTitles, mapItemDesc) {
  jQuery.getFeed({
    url: url,
    success: function(feed) {
      var result = jQuery(selector);

      var ul = jQuery('<ul>').addClass('feed-items');
      ul.hide();
      for(var i = 0; i < feed.items.length && i < limit; i++) {
        var item = feed.items[i];

        var li = jQuery('<li>').addClass('feed-item');

        if (showItemTitles) {
          var titleDiv = jQuery('<div>').addClass('feed-item-title');
          var titleLink = jQuery('<a>').attr('href', item.link).html(item.title);
          titleLink.appendTo(titleDiv.appendTo(li));
        }

        var updatedDiv = jQuery('<div>').addClass('feed-item-updated');
        if (showItemTitles) {
          updatedDiv.html(item.updated);
        }
        else {
          var updatedLink = jQuery('<a>').attr('href', item.link).html(item.updated);
          updatedDiv.append(updatedLink);
        }
        updatedDiv.appendTo(li);

        var description = (mapItemDesc != null) ? mapItemDesc(item.description) : item.description;
        var descriptionDiv = jQuery('<div>').addClass('feed-item-description').html(description);
        descriptionDiv.appendTo(li);

        li.appendTo(ul);
      }
      ul.appendTo(result);
      ul.fadeIn(1000);
    }  
  });
};


