/* 
watercooler.js

experimental code to include Twitter messages on a web page,
e.g. for blog comments. requires jQuery.

this is unfinished---please get in touch if you have suggestions
(I intend to properly open up the source next week sometime)

by Daniel Sandler <dsandler#dsandler.org>

version: 1e-5
*/

// I realize this is an incomplete list of TLDs. Why bother, you say?
// It makes the RE simpler (otherwise I'd need a separate RE for
// http:// urls that may have any TLD, and unadorned URLs that must be
// inferred by their TLD).
var RE_LINK = new RegExp("(http://)?([A-Za-z0-9-.]+[.](?:com|net|org|us|edu|info|ly|uk|es|de|ws|tv))(/[_.%A-Za-z0-9#/]*[_A-Za-z0-9#])?", "g");
var TWITTER_XREF = new RegExp("@([A-Za-z0-9-_]*)", "g");
var MAX_LINK_LENGTH = 25;
var LINK_SUFFIX = "/&hellip;";

// quick and dirty (emphasis on dirty) htmlizer
function autolink(s) {
	return s
	.replace(RE_LINK, function(str, scheme, host, path, offset, s) {
		var text = str;
		if (text.length > MAX_LINK_LENGTH) {
			text = host + LINK_SUFFIX; // "/&#x22EF;";
		}
		if (scheme == '') scheme = 'http://';
		return "<a href=\"" + scheme + host + path + "\">" 
			+ text + "</a>";
	})
	.replace(TWITTER_XREF, "@<a href=\"http://twitter.com/$1\">$1</a>")
	;
}

// copied from a previous project; fuzzy date display
function relative_time(time_value, short) {
	//var values = time_value.split(" ");
	//time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
	var parsed_date = new Date(time_value).getTime();
	if (!parsed_date)
		return time_value;

	var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
	var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
	// delta = delta + (relative_to.getTimezoneOffset() * 60);

	if (delta < 60) {
		return short ? 'now' : 'a moment ago';
	} else if(delta < 120) {
		return short ? '~1m' : 'about a minute ago';
	} else if(delta < (60*60)) {
		return (parseInt(delta / 60)).toString() + 
			(short ? 'm' : ' minutes ago');
	} else if(delta < (120*60)) {
		return short ? '~1h' : 'about an hour ago';
	} else if(delta < (24*60*60)) {
		return (short ? '~' : 'about ') 
			+ (parseInt(delta / 3600)).toString() 
			+ (short?'h':' hours ago');
	} else if(delta < (48*60*60)) {
		return short ? '1d' : 'yesterday';
	} else {
		return (parseInt(delta / 86400)).toString() 
			+ (short ? 'd' : ' days ago');
	}
}

// this is where the magic happens
// query: keywords (e.g. a permalink) to query search.twitter.com for
// result: HTML element elt will be emptied and replaced with <li> for
// each matching tweet, up to 100 (the max unpaged response from
// search.twitter.com)



function watercooler(elt, query, reltime) {
	var count = 100; // the max

	var currentPage = 1;

	function process_page(data) {
		var results = data.results;
		var n = results.length;
		if (n > 0) {
			/*$("<p>" 
				+ ((n == count)
					?"At least "
					:"")
				+ n
				+ " Twitter message"
				+ (count==1?"":"s")
				+ " reference this page:</p>").appendTo(elt);*/
			for (var i=0; i<n; i++) {
				var item = results[i];
				$('<li><span class="comment_author"><img src="'
					+ item.profile_image_url
					+ '" class="avatar" style="height: 32px;" /> '
					+ '<a href="http://twitter.com/' + item.from_user 
					+ '">' + item.from_user + '</a>'
					+ '</span> '
					+ '<span class="comment_text">'
					+ autolink(item.text)
					+ '</span>'
					+ '<p class="comment_date">'
					+ 'twitter message posted <a href="http://twitter.com/' 
					+ item.from_user + '/status/' + item.id + '">' 
					+ (reltime ? relative_time(item.created_at) : item.created_at)
					+ '</a>'
					+ '</p>'
					+ '</li>').prependTo(elt);
			}

			// continue computation
			currentPage += 1;
			$.getJSON(
				"http://search.twitter.com/search.json?rpp=" + count
					+ "&page=" + currentPage
					+ "&q=" + escape(query)
					+ '&callback=?' ,  // JSONP
				process_page);

		} else {
			if (currentPage == 1) $("<em>(None)</em>").appendTo(elt);
		}
	}

	$.getJSON(
		"http://search.twitter.com/search.json?rpp=" + count + "&q=" + escape(query)
			+ '&callback=?' ,  // JSONP
			function (data) {
				// initial callback function
				$(elt).empty(); // clean out spinners, etc

				process_page(data);
			}
		);
}
