/**
	Twitter addon by Huge Solutions.
	
	@licence Huge Solutions, all rights reserved!
	@author Antti Hukkanen, Huge Solutions
	@version 1.0
*/
(function() {

var Twitter = {

	APIAddress: 'api.twitter.com',
	APIVersion: 1,
	
	userData: null,
	tweetData: null,
	elementSettings: {},
	
	containerElement: null,

	/**
	 * Forms the Twitter API url for different API actions/requests.
	 */
	getUrl: function(action, data) {
		var proto = ('https:' == document.location.protocol ? 'https:' : 'http:');
		var url = proto+'//'+this.APIAddress+'/'+this.APIVersion+'/';
		if (action == 'tweetlist') {
			return url + 'statuses/user_timeline.json?screen_name='+data.username+'&count='+data.tweetCount+'&callback=?';
		} else if (action == 'user') {
			return url + 'users/show.json?screen_name='+data.username+'&callback=?';
		}
		return null;
	},
	
	/**
	 * Parses the time into right format.
	 */
    parseTime: function(time_value) {
		var parsed_date = Date.parse(time_value.replace(/^([a-z]{3})( [a-z]{3} \d\d?)(.*)( \d{4})$/i, '$1,$2$4$3'));
		var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
		var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
		var r = '';
		if (delta < 60) {
			r = delta + ' seconds ago';
		} else if (delta < 120) {
			r = 'a minute ago';
		} else if (delta < (45*60)) {
			r = (parseInt(delta / 60, 10)).toString() + ' minutes ago';
		} else if (delta < (2*60*60)) {
			r = 'an hour ago';
		} else if (delta < (24*60*60)) {
			r = '' + (parseInt(delta / 3600, 10)).toString() + ' hours ago';
		} else if (delta < (48*60*60)) {
			r = 'yesterday';
		} else {
			r = (parseInt(delta / 86400, 10)).toString() + ' days ago';
		}
		return r;
    },
	
	updateUserData: function(requestData, callback) {
		$.getJSON(this.getUrl("user", requestData), function(data){
			Twitter.userData = (data.results || data);
			if (typeof callback == 'function') {
				callback("userdata");
			}
		});
	},
	
	updateTweetData: function(requestData, callback) {
		$.getJSON(this.getUrl("tweetlist", requestData), function(data) {
			Twitter.tweetData = (data.results || data);
			if (typeof callback == 'function') {
				callback("tweetdata");
			}
		});
	},
	
	updateData: function(message) {
		if (message == 'tweetdata') {
			// After Ajax
			Twitter.generateTwitterElement();
		} else if (message == 'userdata') {
			// Second Ajax call
			Twitter.updateTweetData(Twitter.elementSettings.tweetData, Twitter.updateData);
		} else {
			// First Ajax call
			Twitter.updateUserData(Twitter.elementSettings.tweetData, Twitter.updateData);
		}
	},
	
	/**
	 * Forms a jQuery element of the Twitter element head.
	 * The head element contains information about the user.
	 */
	getTweetHead: function() {
		var elem = $('<div class="tweetHead"></div>');
		
		var user = Twitter.userData;
		var avatar = $('<div class="avatar"><a href="http://twitter.com/'+user.screen_name+'" target="_blank"><img src="'+user.profile_image_url+'" alt="'+user.screen_name+'" title="'+user.screen_name+'" width="'+this.elementSettings.tweetData.pictureSize+'" height="'+this.elementSettings.tweetData.pictureSize+'" /></a></div>');
		elem.append(avatar);
		var name = $('<div class="name">'+user.name+'</div>');
		elem.append(name);
		var screenName = $('<div class="screenName"><a href="http://twitter.com/'+user.screen_name+'" target="_blank">'+user.screen_name+'</a></div>');
		elem.append(screenName);
		
		elem.css('min-height', this.elementSettings.tweetData.pictureSize);
		return elem;
	},
	
	/**
	 * Forms a jQuery element of the Twitter element tweet list.
	 */
	getTweetList: function() {
		var elem = $('<div class="tweetList"></div>');
		
		var tweets = Twitter.tweetData;
		$.each(tweets, function(i,item){
			var text = '<span class="text">' + $([item.text]).linkUrl().linkUser().linkHash()[0] + '</span>';
			var time = '<span class="time"><a target="_blank" href="http://twitter.com/' + item.user.screen_name + '/status/' + item.id + '">' + Twitter.parseTime(item.created_at) + '</a></span>';
			var reply = '<span class="reply"><a target="_blank" href="http://twitter.com/?status=@' + item.user.screen_name + '%20&amp;in_reply_to_status_id=' + item.id + '&amp;in_reply_to=' + item.user.screen_name + '">reply</a></span>';
		
			var tweet = $('<div class="tweet"></div>');
			tweet.append(text);
			var tweetBottom = $('<div class="bottom"></div>');
			tweetBottom.append(time);
			tweetBottom.append('<span class="itemSeparator">&nbsp;&bull;&nbsp;</span>');
			tweetBottom.append(reply);
			tweet.append(tweetBottom);
			
			elem.append(tweet);
		});
			
		return elem;
	},
	
	/**
	 * Forms a jQuery element of the Twitter element footer.
	 */
	getTweetFoot: function() {
		var user = Twitter.userData;
		var elem = $('<div class="tweetFoot"></div>');
		elem.append('<img alt="" src="http://widgets.twimg.com/i/widget-logo.png" />');
		elem.append('<span><a target="_blank" href="http://twitter.com/' + user.screen_name + '">Join the conversation</a></span>');
		return elem;
	},
	
	generateTwitterElement: function() {
		var container = this.containerElement;
		
		container.html("");
		if (this.elementSettings.showHead && this.userData !== null) {
			var tweetHead = this.getTweetHead();
			container.append(tweetHead);
		}
		if (this.tweetData !== null) {
			var tweetList = this.getTweetList();
			container.append(tweetList);
		}
		if (this.elementSettings.showFoot && this.userData !== null) {
			var tweetFoot = this.getTweetFoot();
			container.append(tweetFoot);
		}
	},
	
	/**
	 * Adds the twitter element to the specified container. 
	 */
	addTwitter: function(container, userSettings) {
		var settings = $.extend(true, {
			showHead: true,
			showFoot: true,
			tweetData: {
				username: '',
				tweetCount: 5,
				pictureSize: 35,
				showAvatar: false
			}
		}, userSettings);
		
		this.containerElement = container;
		this.elementSettings = settings;
		this.updateData('init');
	}
	
};

$.fn.twitter = function(settings) {
	// Extensions for parsing the tweet
    $.fn.extend({
		linkUrl: function() {
			var returning = [];
			var regexp = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi;
			this.each(function() {
				returning.push(this.replace(regexp,'<a href="$1" target="_blank">$1</a>'));
			});
			return $(returning);
		},
		linkUser: function() {
			var returning = [];
			var regexp = /[\@]+([A-Za-z0-9-_]+)/gi;
			this.each(function() {
			  returning.push(this.replace(regexp,'<a href="http://twitter.com/$1" target="_blank">@$1</a>'));
			});
			return $(returning);
		},
		linkHash: function() {
			var returning = [];
			var regexp = /(?:^| )[\#]+([A-Za-z0-9-_]+)/gi;
			this.each(function() {
			  returning.push(this.replace(regexp,'<a href="http://search.twitter.com/search?q=%23$1" target="_blank">#$1</a>'));
			});
			return $(returning);
		}
    });
	
	// Actual functionality to add the Twitter element
	Twitter.addTwitter($(this), settings);
}

})();
