/**
 * stew.js
 *
 * A pure javascript implementation of the idea employed by soup.io, which
 * is to aggreate all of your social media traffic into one timeline.
 *
 * This was written simply to test the idea of a soup.io style client, but
 * not meant to be used in a serious nature.  This script queries the feeds
 * from the various sites on each pageload, and as such generates an undue
 * ammount of traffic on the services that host the feeds.  If you are
 * interested in this type of aggregation, I suggest you check out
 * http://soup.io ... They do a better job than me, anyway.
 *
 *
 * Current services working:
 *  - Twitter
 *  - Digg
 *  - Custom RSS Feed
 *
 * Services to be added:
 *  - Last.fm
 *  - del.icio.us
 *  - flickr
 *  - ?????
 *
 * Useage:
 *
 * In the <head> element of your html file, you must first:
 *
 * <script src="/path/to/stew.js"></script>
 *
 * Secondly, you must configure stew, and write it's script tags,
 * you still should be in the <head> element of your file:
 *
 * <script>
 *	stew.twitter_username = 'your_twitter_username';
 *	stew.digg_username = 'your_digg_username';
 *	stew.rss_feed = 'url_to_your_rss_feed';
 *
 *	stew.write_script_tags();
 * </script>
 *
 * That's it!
 *
 * Now, when all of the scripts are loaded,  stew will display
 * all of the content for the world to see.
 *
 *
 * @author Warren Krewenki <http://warren.mesozen.com>
 * @created May 30, 2008
 **/


var stew = {

	items : new Array(),		// The array that holds all posts

	// accounts
	twitter_username : '',
	digg_username : '',
	flickr_username : '',
	lastfm_username : '',
	rss_feed : '',


	// config
	month_names : new Array("January", "February", "March", "April",
		"May", "June", "July", "August", "September", 
		"October", "November", "December"),
	rss_custom_badge : '',

	// update status
	finished_tweets : false,
	finished_diggs : false,
	finished_rss : false,
	finished_flickr : false,


	// retrival functions
	/**
	 * getRSS()
	 *
	 * Takes an RSS feed's url and passes it through jsonme.com's converter
	 * This gives us a JSON array with a custom callback function.
	 *
	 * Note: Was originally from John Resig's RSS to JSON (http://ejohn.org/projects/rss2json/)
	 * but it appears John's service no longer works.
	 *
	 **/
	getRSS : function(url, callback) {
		var script = document.createElement('script');
		script.type = 'text/javascript';
		script.src = 'http://www.jsonme.com/json.php?url='+url+'&jsoncallback='+callback;
		document.getElementsByTagName("head")[0].appendChild(script);
	},

	/**
	 * write_script_tags()
	 *
	 * For each service (twitter, digg, rss, etc.), if we have the necessary
	 * information, create a script element with SRC pointing to whatever
	 * url provides a JSON object wrapped in a callback function. A little
	 * hacky, but it serves it's purpose
	 *
	 **/
	write_script_tags : function(){
		if(stew.twitter_username != ''){
			var script = document.createElement('script');
			script.src = 'http://twitter.com/statuses/user_timeline/'+stew.twitter_username+'.json?callback=stew.process_tweets&count=20';
			document.getElementsByTagName("head")[0].appendChild(script);
		} else {
			stew.finished_tweets = true;
		}

		if(stew.digg_username != ''){
			var script = document.createElement('script');
			script.src = 'http://digg.com/tools/services?type=javascript&callback=diggwb&endPoint=/user/krewenki/dugg&count=20';
			document.getElementsByTagName("head")[0].appendChild(script);
		} else {
			stew.finished_diggs = true;
		}

		if(stew.rss_feed != ''){
			stew.getRSS(stew.rss_feed,'stew.process_rss');
		} else {
			stew.finished_rss = true;
		}

		if(stew.flickr_username != ''){
			stew.getRSS('http://api.flickr.com/services/feeds/photos_public.gne?id='+stew.flickr_username+'&lang=en-us&format=rss','stew.process_flickr');
		} else {
			stew.finished_flickr = true;
		}
	},

	/**
	 * process_diggs()
	 *
	 * This function loops through the json object returned from
	 * diggs's "show diggs on your website" script and pushes
	 * the diggs onto the stew.items array
	 *
	 **/
	process_diggs : function(obj){
		var diggs = obj.stories;
		var statusHTML = "";
		var username = "";
		for (var i=0; i<diggs.length; i++){
			digg = diggs[i];
			topush = {
				timestamp : digg.submit_date * 1000,
				title : digg.title,
				url : digg.link,
				badge_url : 'http://digg.com/favicon.ico',
				text : digg.description,
				ingredient : 'digg'
			};
			stew.items.push(topush);
		}
		stew.finished_diggs = true;
		stew.display();
	},


	/**
	 * process_tweets()
	 *
	 * This function loops through the json object returned from
	 * twitter's "show tweets on your website" script and pushes
	 * the tweets onto the stew.items array
	 **/
	process_tweets : function(obj){
		var twitters = obj;
		var statusHTML = "";
		var username = "";
		for (var i=0; i<twitters.length; i++){
			var values = twitters[i].created_at.split(" ");
			time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
			var parsed_date = Date.parse(time_value);
		  
			topush = {
				timestamp : parsed_date,
				title : '',
				url : 'http://twitter.com/'+username+'/statuses/'+twitters[i].id,
				badge_url : 'http://twitter.com/favicon.ico',
				text : twitters[i].text,
				ingredient : 'twitter'
			};
			stew.items.push(topush);
		}
		stew.finished_tweets = true;
		stew.display();
	},

	/**
	 * process_rss()
	 *
	 * This function decides which favicon to use, and then loops
	 * through all RSS items passed from getRSS(), pushing them onto
	 * the stew.items array.
	 *
	 **/
	process_rss : function(obj){
		var items = obj.items;
		
		// Here, we get the domain, for favicon.ico
		if(stew.rss_custom_badge == ''){
			url = stew.rss_feed;
			url_parts = url.split('/');
			favicon_url = url_parts[0] + '//' + url_parts[2] + '/favicon.ico';
		} else {
			favicon_url = stew.rss_custom_badge;
		}

		
		for(i=0; i<items.length; i++){
			topush = {
				timestamp : new Date(items[i].pubdate),
				title : items[i].title,
				url : items[i].link,
				badge_url : favicon_url,
				text : items[i].description,
				ingredient : 'blog'
			};
			stew.items.push(topush);
		}
		stew.finished_rss = true;
		stew.display();
	},

	/**
	 * process_flickr()
	 *
	 * I had trouble with flickr, so they're being left out for now
	 *
	 */
	process_flickr : function(obj){
		
	},

	// output functions
	/**
	 * display
	 *
	 * display really just ensures that all scripts have been parsed before
	 * calling write_output(),  It sorts the array of events by date,
	 * newst to oldest, and then calls write_output()
	 *
	 **/
	display : function(){
		if(stew.finished_tweets && stew.finished_diggs && stew.finished_rss && stew.finished_flickr){
			// sort the items by timestamp
			stew.items.sort(stew.sort_by_timestamp);
			stew.write_output();
		} else {
			setTimeout("stew.display();",500);
		}

	},
	
	/**
	 * sort_by_timestamp
	 *
	 * a simple function to pass to sort() so we can sort our
	 * big array of json objects
	 *
	 **/
	sort_by_timestamp : function(a,b){
		var x = a.timestamp;
		var y = b.timestamp;
		return ((x < y) ? 1 : ((x > y) ? -1: 0));
	},
	
	/**
	 * write_output()
	 *
	 * This function loops through stew.items and writes all the HTML required
	 * to display them.  It groups the events by day of occurrence
	 *
	 **/
	write_output : function(){
		old_date = '';
		html = '';
		for(i=0;i<stew.items.length;i++){
			
			// For each item, compare the day it occurred with the last event
			date = new Date(stew.items[i].timestamp);
			comparedate = date.getDate().toString() + '_' + date.getMonth().toString() + '_' +date.getFullYear().toString();
			if(comparedate != old_date){ // if events are not the same day
				old_date = comparedate;
				// create a new h1 tag containing this events day of occurrence
				var header = document.createElement('h1');
				header.innerHTML = stew.month_names[date.getMonth()] + ' ' + date.getDate() + ', ' + date.getFullYear();
				document.getElementsByTagName("body")[0].appendChild(header);
			}
			
			// create the container for this event
			container = document.createElement('div');
			container.className = 'post '+stew.items[i].ingredient;
			
			// create and append the favicon badge to container
			badge = document.createElement('img');
			badge.className = 'badge';
			badge.src = stew.items[i].badge_url;
			
			container.appendChild(badge);
			
			// create and append the speech bubble img to container
			bubble = document.createElement('img');
			bubble.className = 'bubble';
			bubble.src = 'bubble.gif';
			
			container.appendChild(bubble);
			
			// create the div where our event text will go
			content = document.createElement('div');
			content.className = 'content';

			// If there's a title (blog/digg)
			if(stew.items[i].title != ''){
				// create a h2 element linked to item.url
				// and append it to our content element
				post_title = document.createElement('h2');
				post_link = document.createElement('a');
				post_link.href = stew.items[i].url;
				post_link.innerHTML = stew.items[i].title;
				
				post_title.appendChild(post_link);
				content.appendChild(post_title);
			}
			
			// This is ugly, but, it appends the text to our content element
			content.innerHTML += stew.items[i].text;
			
			// I am not proud of the next few elements, they
			// *need* to be cleaned up.
			// This is for the CSS I was using, allowing consistent
			// spacing between elements. Ideally, we'd just close content,
			// instead of using a clear div, and a spacer div.  Fix Me :)
			clear = document.createElement('div');
			clear.className = 'clear';
			content.appendChild(clear);
			
			container.appendChild(content);
			
			document.getElementsByTagName('body')[0].appendChild(container);
			
			// See? An entirely separate spacer div. Disgusting.
			spacer = document.createElement('div');
			spacer.className = 'spacer';
			document.getElementsByTagName('body')[0].appendChild(spacer);

		}
	}
};

/**
 * diggwb
 *
 * This function is just a wrapper for stew.process_diggs because
 * when I tried to switch diggwb to stew.process_diggs as the callback
 * argument in the digg feed, they throw an alert complaining about an
 * invalid callback function.  I wish they'd:
 *
 * A) Allow whatever you'd like for the argument, to avoid this type of mess
 *
 * B) Remove the argument from the url.  Pointless if it doesn't change
 *
 */
function diggwb(obj){
	stew.process_diggs(obj);
}
