(function($){

	$.fn.trickleIn = function(opts)
	{
	
		if( opts == 'stop' )
		{
			window.clearInterval(this.data('trickle-timer'));
		}
		else
		{
			if(!opts)opts={};
			
			var options = {
			limit:100,
			first:false,
			animation:function(el){el.show(400);}
			};
			
			$.extend(options,opts);

			var el = this;
			var timer = window.setInterval(function(){
				var trickle;
				var c = el.children(':hidden');
				
				if(options.first)trickle = c[0];
				else trickle = c[c.length-1];
				
				options.animation($(trickle));
				
				var d = el.children(':visible');
				if(d.length > options.limit)
				{	
					$(d.slice(options.limit)).fadeOut(200,function(){$(this).detach();});
				}
				
			},options.frequency*1000);
			
			this.data('trickle-timer',timer);
		}
		
		return this;
	}

	
	$.fn.parrotFeed = function(type,opts,renderer)
	{
	
		if(!opts)opts={};
		
		return this.each(function(){
			
			var renderers = {
				twitter:function(tweet,opts)
				{
					if(!opts.renderer)opts.renderer={};
					opts = $.extend({},{meta:true,photo:true,author:true,time:true},opts.renderer);
					
					if ( opts.no_replies && tweet.text[0] == '@')return false;
	
					var outer = $('<li>').addClass('tweet');
					var body = $('<div>').addClass('tweet-body');
					var content = $('<span>').addClass('tweet-content').html($.xssafe(tweet.text));
					var meta = $('<div>').addClass('tweet-meta');
					var photo = $('<a>').addClass('tweet-photo').attr('href','http://www.twitter.com/'+$.xssafe(tweet.from_user)).append($('<img>').attr('src',$.xssafe(tweet.profile_image_url)).attr('alt',$.xssafe(tweet.from_user)));
					var author = $('<a>').addClass('tweet-author').attr('href','http://www.twitter.com/'+$.xssafe(tweet.from_user)).html($.xssafe(tweet.from_user));
					var time = $('<a>').addClass('tweet-time').addClass('liveTime').attr('href','http://www.twitter.com/'+$.xssafe(tweet.from_user)+'/status/'+$.xssafe(tweet.id)).html($.prettyDate(tweet.parrotFeed.time*1000));
					time.data('time',tweet.parrotFeed.time);
					outer.data('time',tweet.parrotFeed.time);
					content.appendTo(body.appendTo(outer));
					
					if(opts.meta)
					{
						if(opts.photo)photo.appendTo(meta);
						if(opts.author)author.appendTo(meta);
						if(opts.time)time.appendTo(meta);
						meta.appendTo(outer);
					}
					var currentTime = Math.round((new Date()).getTime()/1000);
					
					if(currentTime-tweet.parrotFeed.time < opts.hide_threshold){ outer.css('display','none'); }
					
					return outer;
				}
			};
			
			var $this=$(this);	
			
			if(!renderer)
			{
				if(renderers[type]){renderer=renderers[type];}
				else{console.error('parrotFeed error: No renderer found for type "'+type+'" and no renderer provided.');}
			}
			

			var oldCallback = opts.callback;
			opts.callback = function(result){
				if(typeof oldCallback == 'function')oldCallback();
				
				if(result.text.split(' ')[0]=='RT') return false;
				
				var el = renderer(result,opts);
				
				if ( !el ) return false;
				
				// Find the right place to insert the element in the timeline
					var found=false;
			     		$this.children().each(function(index){
				     		if ( $(this).data('time') )
				     		{
				     			if ($(this).data('time') <= el.data('time'))
				     			{
				     				found=$(this);
				     				return false;
				     			}
				     		}
			     		});
			     		
			     		if(found) el.insertBefore(found);
			     		else el.appendTo($this);
			}
			
			$.parrotFeed(type,opts);
	
		});
	
	}
	

	$.extend({
	
		liveTime: function()
		{
			var liveTimer = window.setInterval(function(){
				
					$('body').find('.liveTime').each(function(){
						if($(this).data('time')) $(this).text($.prettyDate($(this).data('time')*1000));
					});
			},5000);
		},
	
		xssafe: function(theText)
		{
			theText+="";
			return theText.replace("/</g",'&lt;').replace("/>/g",'&gt;');
		},
	
		parrotFeed: function(type,opts)
		{
			var defaults = {
				twitter:{
					className:"tweet",
					query: { format:'json', q:'kitten', since_id:'0' },
					query_refresh:{'since_id':'max_id_str'},
					data_node:'results',
					id_field:'id_str',
					date_field:'created_at',
					limit_field:'rpp',
					url: 'http://search.twitter.com/search.json',
					limit:3,
					live:true,
					max_fetch_time:60000,
					min_fetch_time:5000,
					fetch_time:10000
				}
			}
			
			var options = $.extend(true,{},(defaults[type]?defaults[type]:{}),opts);

			var fetch = function() {
			
				if(!this.count)
				{

					// Initialise state
					this.count=1;
				}
				else
				{

					// Update state
					this.count++;
				}
				
				if(this.count==1)
				{
					
					// Only get a few to start with
					options.query[options.limit_field]=options.limit;
				}
				else
				{
					// Then get as many as possible that have occured since last update
					options.query[options.limit_field]=100;
				}
				
				
				// Request feed
				$.ajax({
					url:options.url,
					data:options.query,
					dataType:'jsonp',
					success:function(data,textStatus,jqXHR){
					var r = data[options.data_node];
					if(r && r.length > 0)
					{
						// We have data
						$.each(r,function(i,result){
						
							result.parrotFeed={};
							result.parrotFeed.time = Math.floor((new Date(result[options.date_field])).getTime()/1000);
							options.callback(result);
						});
						
						
						// Update settings object based on current state
						
						for(z in options.query_refresh)
						{
							options.query[z] = data[options.query_refresh[z]];
						}
						
						options.fetch_time = options.min_fetch_time;
					}
					else
					{
						// No data this time, poll longer
						options.fetch_time = Math.min(options.max_fetch_time,options.fetch_time*1.5);
					}
					
					if(options.live)
					{
						var timer = window.setTimeout(function(){fetch();},options.fetch_time);
					}
					
					
					
				}}).done(function(){
					//Hack to display the actual number of tweets we're after!
					$('#tweets > *').slice(4).remove();
				});
				
			
			}
			
			fetch();			
			
		}
	});
	
	/*
	 * JavaScript Pretty Date
	 * Copyright (c) 2008 John Resig (jquery.com)
	 * Licensed under the MIT license.
	 */
		 
	$.prettyDate = function(time){
		var date = new Date((time || "")),
			diff = (((new Date()).getTime() - date.getTime()) / 1000),
			day_diff = Math.floor(diff / 86400);
				
		if ( isNaN(day_diff)  )
			return;
				
		return day_diff < 1 && (
				diff < 60 && "just now" ||
				diff < 120 && "1 minute ago" ||
				diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
				diff < 7200 && "1 hour ago" ||
				diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
			day_diff == 1 && "Yesterday" ||
			day_diff < 7 && day_diff + " days ago" ||
			day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago"
			|| "ages ago";
	};


})(jQuery);
