// 
//  jQuery Social
//  A jQuery plugin for asynchronous requests of social network data.
//  Supported streams of data:
//  - Twitter
//  - Flickr
//  - Last.fm
//  - Delicious
//  - Youtube
// 
//  Future updates will include:
//	----------------
//  - Filtering out replies from Twitter
//  - Vimeo
//  
//  @author: Justin Jones (justin@jstnjns.com) http://www.jstnjns.com/
//  @version: 1.0
//  @copyright: 2010 Justin Jones. All rights reserved.
//  @requires: jQuery v1.4.x
// 

(function($){
	$.fn.social = function(options, callback) {
		
		return $(this).each(function() {
			// ----------------------------------------------------------------|| Setting Vars ||
			var $this = $(this),
				settings = {},		
			
				_init = function() {
				
					$.extend(true, settings, $.fn.social.defaults, options);
				
					$this.html(settings.loadingText);
				
					switch(settings.network) {
						case 'twitter':
							_twitter();
							break;
						case 'flickr':
							_flickr();
							break;
						case 'lastfm':
							_lastfm();
							break;
						case 'youtube':
							_youtube();
							break;
						case 'delicious':
							_delicious();
							break;
					}
				},
			
				// ----------------------------------------------------------------|| TWITTER ||
				_twitter = function() {
								
					var requestURL = 'http://search.twitter.com/search.json?q=',
						user,
					
						_format = function(text) {
							text = text.replace(/(\b(https?|ftp):\/\/[A-Z0-9+&@#\/%?=~_|!:,.;]*[A-Z0-9+&@#\/%=~_|])/gim, '<a href="$1" target="_blank">$1</a>');
							text = text.replace(/(^|[^\/])(www\.[\S]+(\b|$))/gim, '$1<a href="http://$2" target="_blank">$2</a>');
							text = text.replace(/(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim, '<a href="mailto:$1">$1</a>');
							text = text.replace(/(^|\s)@(\w+)/g, '<span class="mention"><a href="http://www.twitter.com/$2" target="_blank">$1@$2</a></span>');
							text = text.replace(/(^|\s)#(\w+)/g, '<span class="hash">$1#<a href="http://search.twitter.com/search?q=%23$2" target="_blank">$2</a></span>');
							return text;
						},
						
						_ago = function(time) {
							var t			= time.split(' ');
							var parsed_date	= Date.parse(t[2]+" "+t[1]+", "+t[3]+" "+t[4]+" "+t[5]);
							// var parsed_date = Date.parse(time.split(' '));
							var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
							var delta = parseInt((relative_to.getTime() - parsed_date) / 1000, 10);
							if(delta < 60) {
								return 'less than a minute ago';
							} else if(delta < 120) {
								return 'about a minute ago';
							} else if(delta < (45*60)) {
								return (parseInt(delta / 60, 10)).toString() + ' minutes ago';
							} else if(delta < (90*60)) {
								return 'about an hour ago';
							} else if(delta < (24*60*60)) {
								return 'about ' + (parseInt(delta / 3600, 10)).toString() + ' hours ago';
							} else if(delta < (48*60*60)) {
								return '1 day ago';
							} else {
								return (parseInt(delta / 86400, 10)).toString() + ' days ago';
							}
						};
						
					// User
					if($.isArray(settings.user) && settings.user.length) {
						requestURL += escape('from:' + settings.user.join(' OR from:'));
					} else if(settings.user.length) {
						requestURL += escape('from:' + settings.user);
					}
					
					if(settings.user.length && (settings.twitter.mention.length || settings.twitter.hash.length)) {
						requestURL += escape(' OR ');
					}
					
					// Mention
					if($.isArray(settings.twitter.mention) & settings.twitter.mention.length) {
						requestURL += escape('@' + settings.twitter.mention.join(' OR @'));
					} else if(settings.twitter.mention.length) {
						requestURL += escape('@' + settings.twitter.mention);
					}
					
					if(settings.twitter.mention.length && settings.twitter.hash.length) requestURL += escape(' OR ');
					
					// Hash
					if($.isArray(settings.twitter.hash) && settings.twitter.hash.length) {
						requestURL += escape('#' + settings.twitter.hash.join(' OR #'));
					} else if(settings.twitter.hash.length) {
						requestURL += escape('#' + settings.twitter.hash);
					}
					
					requestURL += '&rpp=' + settings.count;
				
					$.ajax({
						type		: 'GET',
						dataType	: 'jsonp',
						url			: requestURL,
						success		: function(data) {
							// Prepare space in which  is replacing
							$this.empty();
						
							var list = (data.results) ? data.results.slice(0, settings.count) : data;
						
							if(list.length < 1) {
								$this.html('<span class="error">Sorry, could not load tweets.</span>');
							} else {
							
								for(var item = 0; item < list.length; item++) {

									var output		= settings.twitter.output;

									var user		= (list[item].from_user) ? list[item].from_user : list[item].user.screen_name;

									var user_url	= 'http://www.twitter.com/' + user;
									var tweet_url	= 'http://www.twitter.com/' + user + '/status/' + list[item].id;						
									var retweet_url	= 'http://twitter.com/home?status=RT @' + list[item].from_user + ' ' + escape(list[item].text);

									var text		= _format(list[item].text);
									var time		= _ago(list[item].created_at);
									var avatar		= (list[item].profile_image_url) ? list[item].profile_image_url : list[item].user.profile_image_url;

									var replace		= ['{user_url}','{tweet_url}','{retweet_url}','{text}','{time}','{user}','{avatar}'];
									var by			= [user_url,tweet_url,retweet_url,text,time,user,avatar];

									for(var i = 0; i < replace.length; i++) {
										output = output.replace(replace[i],by[i]);
										output = output.replace(replace[i],by[i]);
									}

									if(settings.wrapItemIn !== '') {
										$(settings.wrapItemIn).append(output).appendTo($this);
									} else {
										$(output).appendTo($this);
									}
								}
							
								$this.wrapInner(settings.wrapListIn);
							}
						
							if($.isFunction(callback)) {
								callback.call(this,list);
							}
						}
					});
				
				},
			
				_flickr = function() {
					
					var requestURL = 'http://api.flickr.com/services/feeds/photos_public.gne?format=json',
						user = (settings.user) ? '&id=' + settings.user : '',
						tags = (settings.flickr.tags) ? '&tags=' + settings.flickr.tags : '';

						$.ajax({
						type	: 'GET',
						dataType: 'json',
						url		: requestURL + user + tags + '&limit=5&jsoncallback=?',
						success	: function(data) {
						
							$this.empty();
						
							var list = data.items.slice(0, settings.count);
						
							for(var item = 0; item < list.length; item++) {
							
								var output		= settings.flickr.output;
						
								var url			= list[item].link;
								var title		= list[item].title;
								var description	= list[item].description;
								var author		= list[item].author;
								var tags		= list[item].tags;
								
								var taken		= list[item].date_taken;
								var published	= list[item].published;
						
								var size		= (settings.flickr.size !== '' && settings.flickr.size !== 'n') ? '_' + settings.flickr.size : '';
								var image		= list[item].media.m.replace('_m', size);
								var images		= {
													s	: list[item].media.m.replace('_m', '_s'),
													m	: list[item].media.m,
													l	: list[item].media.m.replace('_m', '_b')
													};
						
								var replace		= ['{url}','{image}','{small}','{medium}','{large}','{title}','{description}','{author}','{tags}','{taken}','{published}'];
								var by			= [url,image,images.s,images.m,images.l,title,description,author,tags,taken,published];
						
								for(var i = 0; i < replace.length; i++) {
									output = output.replace(replace[i],by[i]);
								}
						
								if(settings.wrapItemIn) {
									$(settings.wrapItemIn).append(output).appendTo($this);
								} else {
									$(output).appendTo($this);
								}
							}
						
							if(settings.wrapListIn) {
								$this.wrapInner(settings.wrapListIn);
							}
						
							if($.isFunction(callback)) { callback.call(); }
						}
					});
				},
			
				_lastfm = function() {
					$.ajax({
						type	: 'GET',
						dataType: 'json',
						url		: 'http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=' + settings.user + '&api_key=2d39f166ead04801f3b9376b1e8ba17d&limit=' + settings.count + '&format=json&callback=?',
						success	: function(data) {
							$this.empty();
						
							var list = data.recenttracks.track.slice(0, settings.count);
						
							for(var item = 0; item < list.length; item++) {
							
								var output		= settings.lastfm.output;
						
								var url			= list[item].url;
								var image		= list[item].image[3]['#text'];
								var track		= list[item].name;
								var album		= list[item].album['#text'];
								var artist		= list[item].artist['#text'];
						
								var replace		= ['{url}','{image}','{track}','{album}','{artist}'];
								var by			= [url,image,track,album,artist];
						
								for(var i = 0; i < replace.length; i++) {
									output = output.replace(replace[i],by[i]);
								}
						
								$(settings.wrapItemIn).append(output).appendTo($this);
							}
						
							$this.wrapInner(settings.wrapListIn);
						
							if($.isFunction(callback)) { callback.call(); }
						}
					});
				},
			
				_delicious = function() {
					$.ajax({
						type	: 'GET',
						dataType: 'jsonp',
						url		: 'http://feeds.delicious.com/v2/json/' + settings.user + '?count=' + settings.count,
						success	: function(data) {
							$this.empty();
						
							var list = data.slice(0, settings.count);
						
							for(var item = 0; item < list.length; item++) {
							
								var output		= settings.delicious.output;
						
								var linkStart	= '<a href="' + list[item].u + '" target="_blank">';
								var linkEnd		= '</a>';
								var name		= list[item].d;
						
								var replace		= ['{linkStart}','{linkEnd}','{name}'];
								var by			= [linkStart,linkEnd,name];
						
								for(var i = 0; i < replace.length; i++) {
									output = output.replace(replace[i],by[i]);
								}
						
								$(settings.wrapItemIn).append(output).appendTo($this);
							}
						
							$this.wrapInner(settings.wrapListIn);
						
							if($.isFunction(callback)) { callback.call(); }
						}
					});
				},
			
				_youtube = function() {
					$.ajax({
						type	: 'GET',
						dataType: 'json',
						url		: 'http://gdata.youtube.com/feeds/users/' + settings.user + '/uploads?alt=json&max-results=' + settings.count,
						success	: function(data) {
						
							$this.empty();
						
							var list = data.feed.entry.slice(0, settings.count);
						
							var vars		= {};
							var params		= {};
							var attributes	= {};
						
							for(var item = 0; item < list.length; item++) {
							
								var output		= (settings.youtube.embed) ? settings.youtube.embedOutput : settings.youtube.output;
						
								var name		= list[item].title.$t;
								var url			= list[item].link[0].href;
								var thumb		= list[item].media$group.media$thumbnail[3].url;
								var views		= list[item].yt$statistics.viewCount;
								var video		= '<div id="youtube_player-' + item + '"></div>';
						
								if(typeof(swfobject) !== 'undefined') {
									vars[item]						= {};
									params[item]					= {};
									attributes[item]				= {};
							
									vars[item].file					= list[item].link[0].href;
									vars[item].skin					= settings.youtube.video.skin;
									vars[item].controlbar			= 'over';
									vars[item].stretching			= 'fill';
									vars[item].abouttext			= settings.youtube.video.about_text;
									vars[item].aboutlink			= settings.youtube.video.about_link;
									vars[item].fullscreen			= true;
									vars[item].autostart			= false;
							
									params[item].allowfullscreen	= true;
									params[item].allowscriptaccess	= 'always';
									params[item].allownetworking	= 'all';
									params[item].wmode				= 'transparent';
								} else {
									video		= 'You need \'swfobject\' to run this script';
								}
						
								var replace		= ['{name}','{url}','{thumb}','{views}','{video}'];
								var by			= [name,url,thumb,views,video];
						
								for(var i = 0; i < replace.length; i++) {
									output = output.replace(replace[i],by[i]);
								}
						
								$(settings.wrapItemIn).append(output).appendTo($this);

							}
						
							$this.wrapInner(settings.wrapListIn);
						
							for(item=0; item<list.length; item++) {
								swfobject.embedSWF('/engine/swf/jw/player.swf', 'youtube_player-' + item,settings.youtube.video.width,settings.youtube.video.height,'9.0.0','/engine/swf/expressinstall.swf',vars[item],params[item],attributes[item]);
							}
							
							if($.isFunction(callback)) { callback.call(); }
						}
					});
				};
			
			_init();
			
		});
		
	};
	
	$.fn.social.defaults = {
		network			: 'twitter',
		user			: 'groundctrl',
		count			: 5,
		wrapItemIn		: '<li class="item" />',
		wrapListIn		: '<ul class="listing" />',
		loadingText		: '<div class="loading">Loading..</div>',
	
		twitter			: {
			output			: '<span class="tweet"><span class="user"><a href="{user_url}">{user}</a></span> <span class="text">{text}</span> <span class="time"><a href="{tweet_url}">Posted {time}</a></span>',
			search			: [],
			type			: 'recent',
			hash			: [],
			mention			: [],
			list			: []
		},
		flickr			: {
			output			: '<span class="image"><a href="{url}"><img src="{image}"</a></span>',
			size			: 's',
			tags			: false
		},
		lastfm			: {
			output			: '<span class="track"><a href="{url}"><span class="image"><img src="{image}" /></span> <span class="name">{track}</span> <span class="album">{album}</span> <span class="artist">{artist}</span>{linkEnd}</span></a>',
			defaultImage	: ''
		},
		delicious		: {
			output			: '<span class="bookmark"><a href="{url}">{name}</a></span>'
		},
		youtube			: {
			output			: '<span class="video"><a href="{url}" title="{name} - {views} views"><img src="{thumb}" /></a></span>',
			embed			: false,
			embedOutput		: '<span class="video">{video}</span>',
			playlist		: false,
			video			: {
				width			: 400,
				height			: 300,
				about_text		: 'Ground(ctrl)',
				about_link		: 'http://www.groundctrl.com',
				player			: '/engine/swf/jw/player.swf',
				skin			: '/engine/swf/jw/skins/modieus/video_player.xml',
				express_install	: '/engine/swf/expressinstall.swf'
			}
		}
	};
})(jQuery);
