/*
	Twitter Slurp - JavaScript component
	Author: John Bafford - http://bafford.com
	Copyright 2009 The Bivings Group
	http://www.bivings.com
		
	Requires json2.js and jQuery
*/

function NewAJAXRequest(requestHandler, method, url)
{
	var xmlhttp;
	
	if(window.ActiveXObject)
		xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
	else if(window.XMLHttpRequest)
		xmlhttp = new XMLHttpRequest();
	
	if(xmlhttp)
	{
		xmlhttp.open(method, url, true);
		
		if(method == 'POST')
			xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;');
		
		xmlhttp.onreadystatechange = function() { requestHandler(xmlhttp); }
	}
	
	return xmlhttp;
}

function NewStandardAJAXRequest(okHandler, method, url)
{
	var handler = function(xmlhttp)
	{
		if(xmlhttp.readyState == 4)
			if(xmlhttp.status == 200)
				okHandler(xmlhttp.responseText);
	}
	
	return NewAJAXRequest(handler, method, url);
}

//---------------------------------------------------------------------

TwitterSlurp = function(init)
{
	this.self = this;
	this.applicationURL = '';
	this.refreshTimeNoUpdates = 60000;
	this.refreshTimeUpdates = 30000;
	
	//-----------------------------------------------------------------
	//These functions are standard implementations of the display maintenance functions
	//You can override these as necessary.
	
	this.MakeNewTweet = function(tweet)
	{
		var url = 'http://twitter.com/' + tweet.fromUser;
		
		var out = '<div class="tweet" id="tweet_' + tweet.tweetID + '"><span><span class="avatar"><a href="' + url + '"><img src="' + tweet.profileImage + '" height="48" width="48" /></a></span>';
		
		out += '<span><b><a href="' + url + '">' + tweet.fromUser + '</a></b></span> <span class="tweetmsg">' + tweet.tweet + '</span> <span>(at ' + tweet.tweetDate + ')</span></span></div>';
		
		return out;
	}
	
	this.MakeNewLeaderboardEntry = function(leader)
	{
		return '<div><img src="' + leader.profileImage + '" height="48" width="48"><b>' + leader.fromUser + '</b>: ' + leader.count + '</div>';
	}
	
	this.MakeNewLeaderboardTotalsEntry = function(total)
	{
		return '';
	}
	
	this.RemoveTweet = function(jqueryElts)
	{
		jqueryElts.remove();
	}
	
	//-----------------------------------------------------------------
	
	this.removeOldTweets = function(elt, numToDisplay)
	{
		this.RemoveTweet($(elt).children('.tweet').slice(numToDisplay));
	}
	
	this.setSearchContent = function(searchID, results)
	{
		var out = '';
		var cnt = 0;
		
		if(typeof results.tweets != 'undefined')
			for(var tweetID in results.tweets)
			{
				var tweet = results.tweets[tweetID];
				
				out += this.MakeNewTweet(tweet);
				
				cnt++;
			}
		
		if(cnt > 0)
		{
			var elt = $('#' + searchID);
			
			elt.prepend(out);
			
			var maxDisp = elt[0].attributes.getNamedItem('maxDisp');
			if(maxDisp)
				maxDisp = maxDisp.value;
			
			if(!maxDisp)
				maxDisp = 20;
			
			this.removeOldTweets(elt[0], maxDisp);
		}
		
		return cnt;
	}
	
	this.MakeNewStatsTableEntry = function(item)
	{
		return '<li class="leader"><span><b>' + item.name + '</b>: ' + item.count + '</span></li>';
	}
	
	this.graphShowTooltip = function(statID, stat, x, y, contents)
	{
		$('<div id="tooltip">' + contents + '</div>').css( {
			'position': 'absolute',
			'display': 'none',
			'top': y + 5,
			'left': x + 5,
			'border': '1px solid #fdd',
			'padding': '2px',
			'background-color': '#fee',
			'opacity': 0.80
		}).appendTo('body').fadeIn(200);
	}
	
	this.setStats = function(stats, newID)
	{
		if(typeof newID.stats == 'undefined')
			newID.stats = {};
		
		var previousPoint = null;
		
		for(var statID in stats)
		{
			newID.stats[statID] = statID;
			
			if(typeof stats[statID] == 'object')
			{
				var stat = stats[statID];
				
				if(stat.type == 'table')
				{
					var out = '';
					for(var name in stat.data)
						out += this.MakeNewStatsTableEntry(stat.data[name]);
					
					$('#' + statID).html(out);
				}
				else if(stat.type == 'graph')
				{
					var dataItem = stat.dataConfig;
					dataItem.data = stat.data;
					
					var graphConfig = stat.graphConfig;
					if(graphConfig.xaxis.mode == 'time')
					{
						for(var i = 0; i < dataItem.data.length; i++)
							dataItem.data[i][0] *= 1000;
						
						graphConfig.xaxis.min *= 1000;
						graphConfig.xaxis.max *= 1000;
					}
					
					var tooltipFn = this.graphShowTooltip;
					$.plot($('#' + statID), [ dataItem ], graphConfig);
					$('#' + statID).bind('plothover', function(event, pos, item) {
						if(item)
						{
							if(previousPoint != item.datapoint)
							{
								previousPoint = item.datapoint;
								
								$('#tooltip').remove();
								
								tooltipFn(statID, stat, item.pageX, item.pageY, item.datapoint[1]);
							}
						}
						else
						{
							$('#tooltip').remove();
							previousPoint = null;
						}
					});
				}
			}
		}
	}

	this.setLeaderboard = function(leaderboard, newID)
	{
		for(var lbID in leaderboard)
		{
			newID.leaderboard[lbID] = {};
			
			if(typeof leaderboard[lbID] == 'object')
			{
				var lb = leaderboard[lbID];
				if(typeof lb.maxDisp != 'undefined')
					newID.leaderboard[lbID].maxDisp = lb.maxDisp;
				
				var out = '';
				for(var name in lb.users)
					out += this.MakeNewLeaderboardEntry(lb.users[name]);
				
				out += this.MakeNewLeaderboardTotalsEntry(lb.total);
				
				$('#' + lbID).html(out);
				
				this.setStats(lb.stats, newID);
			}
		}
	}
	
	this.setSearches = function(searches, newID)
	{
		var gotNew = 0;
		
		for(var searchID in searches)
		{
			var results = searches[searchID];
			
			gotNew += this.setSearchContent(searchID, results);
			
			newID.search[searchID] = results.maxID;
		}
		
		return gotNew;
	}
	
	this.RefreshHandler = function(self, responseText)
	{
		var refreshTime;
		var gotNew = 0;
		var response = JSON.parse(responseText);
		var newID = {
			'search': {},
			'leaderboard': {}
		};
		
		self.setSearches(response.searches, newID);
		self.setLeaderboard(response.leaderboard, newID);
		
		if(typeof response.refreshTime != 'undefined')
			refreshTime = response.refreshTime;
		else if(gotNew == 0)
			refreshTime = this.refreshTimeNoUpdates;
		else
			refreshTime = this.refreshTimeUpdates;
		
		setTimeout( function() { self.refresh(newID); }, refreshTime);
	};
	
	this.refresh = function(newID)
	{
		if(!this.applicationURL)
		{
			alert('twitterslurp: you must specify the application url');
			return;
		}
		
		url = this.applicationURL;
		
		var self = this;
		var rh = function(responseText) { self.RefreshHandler(self, responseText); };
		ajax = NewStandardAJAXRequest(rh, 'POST', url);
		ajax.send('newID=' + encodeURIComponent(JSON.stringify(newID)));
	};
	
	this.bootstrapContent = function()
	{
		var newID = {
			'search': {},
			'leaderboard': {}
		};
		
		$('.twitterSearchResults').each(function(index) {
			newID.search[this.id] = 0;
		});
		
		$('.twitterLeaderboard').each(function(index) {
			newID.leaderboard[this.id] = 0;
		});
		
		return newID;
	};
	
	this.start = function()
	{
		this.refresh(this.bootstrapContent())
	};
	
	if(typeof init == 'function')
		init(this);
}
