/**
 * @author http://kirill-novitchenko.com
 */

var TB_version = '2.1.1',	// Plugin version 
TB_minTweetID,				// ID of the oldest tweet shown
TB_maxTweetID,				// ID of the newest tweet shown
TB_tweetsShown = 0,			// number of tweets shown
TB_rateLimitData,
TB_mode = 'widget',			// widget or archive
TB_tmp,
TB_started = false,
TB_monthNumber = {'Jan':1,'Feb':2,'Mar':3,'Apr':4,'May':5,'Jun':6,'Jul':7,'Aug':8,'Sep':9,'Oct':10,'Nov':11,'Dec':12},
TB_timePeriods = new Array("second", "minute", "hour", "day", "week", "month", "year", "decade"),
TB_timePeriodLengths = new Array("60","60","24","7","4.35","12","10");

function TB_init() {

	// prevent initializing twice
	if (TB_started) {
		return;
	}
	else {
		TB_started = true;
	}
	
	// check mode
	if(jQuery('#tweetblender').hasClass('archive')) {
		TB_mode = 'archive';
	}
	
	// get config options and blend
	if (typeof(TB_config) != 'undefined') {
		if (typeof(TB_config.general_source_ids) == 'undefined' || TB_config.general_source_ids == '') {
			TB_showMessage('Twitter sources to blend are not defined', true);
			
			// disable refresh
			jQuery('#refreshlink').remove();
		}
		else {
			TB_initInfoBox();
			TB_makeAjaxURLs(TB_config.general_source_ids);

			// show loading indicator
			TB_showLoader();
	
			TB_blend();
		}
	}
	else {
		TB_showMessage('Cannot retrieve Tweet Blender configuration options',true);
	
		// disable refresh
		jQuery('#refreshlink').remove();
	}
}

// form Twitter API queries - group all keywords and hashtags into one search query url, build individual URLs for screen names
function TB_makeAjaxURLs(sources) {
	TB_config['ajaxURLs'] = new Array();
	var TB_searchTerms = new Array();
	jQuery.each(sources.split(','),function(i,src) {
		// if it's a screen name
		if (src.charAt(0) == '@') {
			TB_config['ajaxURLs'].push('http://twitter.com/statuses/user_timeline.json?screen_name='+src.substr(1)+'&count='+TB_config[TB_mode+'_tweets_num']); 
		}
		// else it's a hash or keyword will be grouped with the rest
		else {
			TB_searchTerms.push(src); 
		}
	});
	if (TB_searchTerms.length > 0) {
		TB_config['ajaxURLs'].push('http://search.twitter.com/search.json?q=&ors=' + escape(TB_searchTerms.join(' ')) + '&rpp=' + TB_config[TB_mode+'_tweets_num'] + '&page=1');
	}
}

function TB_initInfoBox() {
	// create HTML for sources
	TB_config.sourcesHTML = '';
	TB_config.sourcesCount = 0;
	jQuery.each(TB_config.general_source_ids.split(','),function(i,src) {
		TB_config.sourcesHTML += '<a target="_blank" href="';
		if (src.charAt(0) == '@') {
		 	TB_config.sourcesHTML += 'http://twitter.com/' + src.substr(1);
		}
		else {
		 	TB_config.sourcesHTML += 'http://search.twitter.com/search?q=' + escape(src);
		}
		TB_config.sourcesHTML += '">' + src + '</a> ';
		TB_config.sourcesCount++;
	});		
	
	// add action to twitter logo
	jQuery('#twitterlogo').click(function(){
		TB_showMessage('Powered by Tweet Blender plugin v' + TB_version + ' blending ' + TB_config.sourcesHTML,false);
	});
	
	// add automatic refresh
	if (parseInt(TB_config.widget_refresh_rate) > 0) {
		setInterval('TB_showLoader();TB_blend();',parseInt(TB_config.widget_refresh_rate) * 1000);
	}
}

function TB_blend() {
	// switch message from Initializing to Loading
	jQuery('#tb_loading').html('Loading...');
	
	// check limit for user viwing the page
	jQuery.ajax({
		url: 'http://twitter.com/account/rate_limit_status.json',
		dataType: 'jsonp',
		success: function(json){
			if (json.remaining_hits < TB_config.ajaxURLs.length) {
				TB_showMessage('You reached your twitter connection limit. Next reset ' + TB_verbalTime(TB_str2date(json.reset_time)), false);
			}
			// else, get new feeds
			else {
				TB_getTweets();
			}
		},
		error: function(){
			TB_getTweets();
		}
	});
}

function TB_checkComplete() {
	if (TB_config.urlsDone == TB_config.ajaxURLs.length) {
		// if nothing added after we are through all sources let user know
		if(jQuery('#tweetlist').children('li').size() == 0) {
			TB_showMessage('No tweets found for ' + TB_config.sourcesHTML, true);
		}
	}
}
	
function TB_getTweets() {
	// iterate over AJAX URLs
	TB_config['urlsDone'] = 0;
	
	// switch message from Initializing to Loading
	jQuery('#tb_loading').html('Loading...');
	
	jQuery.each(TB_config.ajaxURLs,function(i,url) {
		TB_getFreshTweets(url);
	});
}

function TB_getFreshTweets(url) {
	jQuery.ajax({
		dataType: 'jsonp',
		url: url,
		success: function (json) {
			TB_addTweets(json);
		},
		error: function() {
			TB_config.urlsDone++;
			TB_checkComplete();
		}
	});
}
	
function TB_addTweets(jsonData) {

	// hide loader and show tweet list
	TB_showTweetList();

	var tweets = jsonData;
	if (typeof(jsonData.results) != 'undefined') {
		tweets = jsonData.results;
	}
	
	jQuery.each(tweets,function(i,tweet) {
		// if this tweet already in the set, skip it
		if (jQuery('#' + tweet.id).length > 0) {
			return true;
		}
		// if this is the first tweet, just add it and set it to be both min and max
		else if (TB_tweetsShown == 0) {
			TB_tweetsShown++;
			TB_minTweetID = tweet.id;
			TB_maxTweetID = tweet.id;			

			// add at the end
			jQuery('#tweetlist').append(TB_makeHTML(tweet));
		}
		// if tweet older than the oldest
		else if (TB_minTweetID > 0 && tweet.id < TB_minTweetID) {
			// if we are at max already, no need to work through the rest of this set as the rest will be older
			if (TB_tweetsShown >= TB_config[TB_mode+'_tweets_num']) {
				return false;
			}
			else {

				// add at the end
				jQuery('#tweetlist').append(TB_makeHTML(tweet));
				TB_tweetsShown++;

				// make it the oldest
				TB_minTweetID = tweet.id;
			}
		}
		// if tweet is newer than the newest
		else if (TB_maxTweetID > 0 && tweet.id > TB_maxTweetID) {
			// if we are at max already, remove bottom tweet
			TB_enforceLimit();
			
			// add in the beginning
			jQuery('#tweetlist').prepend(TB_makeHTML(tweet));
			TB_tweetsShown++;

			// make it the newest
			TB_maxTweetID = tweet.id;
		}
		// if tweet is in the middle
		else {
			// if we are at max already, remove bottom tweet
			TB_enforceLimit();

			// traverse currently shown tweets and insert in the appropriate spot
			var prevTweetID = TB_maxTweetID;
			jQuery('#tweetlist li').each(function(i,nextTweet){
				if (tweet.id < prevTweetID && tweet.id > nextTweet.id) {
					jQuery('#'+prevTweetID).after(TB_makeHTML(tweet));
					TB_tweetsShown++;
					return false;
				}
				prevTweetID = nextTweet.id;
			});
			
			// if got to here and tweet still not there, make it the last
			if (jQuery('#'+tweet.id).length <= 0) {
					jQuery('#'+TB_minTweetID).after(TB_makeHTML(tweet));
					TB_minTweetID = tweet.id;
					TB_tweetsShown++;
			}
			TB_enforceLimit();
		}
		TB_enforceLimit();
		
		// wire mouseover action items
		jQuery('#'+tweet.id).hover(
		      function () {
				jQuery(this).find("div:last").slideDown()
		      }, 
		      function () {
		        jQuery(this).find("div:last").slideUp();
		      }
		);
		
	});

	if (tweets.length > 0 && TB_mode != 'archive' && TB_config.archive_is_disabled == '') {
		jQuery('#archivelink').show();
	}
	
	TB_config.urlsDone++;
	TB_checkComplete();
}

function TB_enforceLimit() {
	//alert("Max Tweets: " + TB_config[TB_mode+'_tweets_num'] + ", Actual Tweets: " + TB_tweetsShown);
	if (TB_tweetsShown > TB_config[TB_mode+'_tweets_num']) {
		var lastTweet = jQuery('#' + TB_minTweetID),
		nextToLastTweet = lastTweet.prev('li');
		
		// remove last tweet
		lastTweet.remove();
		TB_tweetsShown--;
		
		// make next to last to be last now
		TB_minTweetID = parseInt(nextToLastTweet.attr('id'));
	}
}

function TB_makeHTML(tweet) {
		
	var tweetHTML = '',
	tweetDate;
	
	// add screen name if from_user is given
	if (typeof(tweet.user) == 'undefined' && tweet.from_user) {
		tweet.user = {
			screen_name: tweet.from_user
		};
	}
	
	tweetHTML += '<li id="' + tweet.id + '">';
	
	// show photo if requested
	if (TB_config[TB_mode+'_show_photos']) {

		// add image url
		if (!tweet.user.profile_image_url && tweet.profile_image_url) {
			tweet.user.profile_image_url = tweet.profile_image_url;
		}

		tweetHTML += '<a class="tb_photo" href="http://twitter.com/' + tweet.user.screen_name + '" target="_blank">';
		tweetHTML += '<img src="' + tweet.user.profile_image_url + '" alt="' + tweet.user.screen_name + '"/>';
		tweetHTML += '</a>';
	}

	// show author
	tweetHTML += '<span class="tb_author"><a href="http://twitter.com/' + tweet.user.screen_name + '" target="_blank">' + tweet.user.screen_name + '</a> says: </span> ';

	// show text
	if (TB_config.general_link_urls) {
		tweet.text = tweet.text.replace(/(https?:\/\/\S+)/gi,'<a href="$1" target="_blank">$1</a>'); 
	}
	if (TB_config.general_link_screen_names) {
		tweet.text = tweet.text.replace(/\@([^\s\.\:]+)/gi,'<a href="http://twitter.com/$1" target="_blank">@$1</a>'); 
	}
	if (TB_config.general_link_hash_tags) {
		tweet.text = tweet.text.replace(/\#([^\s\,]+)/gi,'<a href="http://search.twitter.com/search?q=%23$1" target="_blank">#$1</a>'); 
	}
	tweetHTML += '<span class="tb_msg">' + tweet.text + '</span><br/>';

	// start tweet footer with info
	tweetHTML += ' <span class="tb_tweetinfo">';
	
	// show timestamp
	/*tweetHTML += '<a href="http://twitter.com/' + tweet.user.screen_name + '/statuses/' + tweet.id + '">';
	tweetDate = TB_str2date(tweet.created_at);
	if (TB_config.general_timestamp_format) {
		tweetHTML += jQuery.PHPDate(TB_config.general_timestamp_format,tweetDate);
	}
	else {
		tweetHTML += TB_verbalTime(tweetDate);		//jQuery.timeago(tweetDate);
	} 
	tweetHTML += '</a>';*/
	
	// show source if requested
	if (TB_config[TB_mode+'_show_source'] && tweet.source) {
		tweetHTML += ' from ';
		// if source is url encoded -> decode
		if (tweet.source.indexOf('&lt;') >= 0) {
			tweetHTML += jQuery('<textarea/>').html(tweet.source).val();
		}
		// else use as is
		else {
			tweetHTML += tweet.source;
		}
	}
	
	// end tweet footer
	tweetHTML += '</span>';
	
	// add tweet tools
	/*tweetHTML += '<div class="tweet-tools" style="display:none;">' +
				'<a href="http://twitter.com/home?status=@' + tweet.user.screen_name + '%20&in_reply_to_status_id=' + tweet.id + '&in_reply_to=' + tweet.user.screen_name + '" target="_blank">reply<a/>' + 
				' | <a href="http://twitter.com/' + tweet.user.screen_name + '" target="_blank">follow ' + tweet.user.screen_name + '</a>' +
				'</div>'; */
		
	// end tweet	
	tweetHTML += "</li>\n";

	return tweetHTML;
}


function TB_showLoader() {
	jQuery('#refreshlink img').attr('src',TB_pluginPath + '/img/ajax-refresh.gif');
	jQuery('#refreshlink').addClass('loading');
}

function TB_hideLoader() {
	jQuery('#tb_loading').hide();
	jQuery('#refreshlink img').attr('src',TB_pluginPath + '/img/ajax-refresh-icon.gif');
	jQuery('#refreshlink').removeClass('loading');
}

function TB_showTweetList() {
	TB_hideLoader();
	jQuery('#tweetlist').show();
}

function TB_showMessage(msg,keepOnScreen) {
	TB_hideLoader();
	jQuery('#tweetlist').before('<div class="tb_msg" style="display:none;">' + msg + '</div>');
	jQuery('div.tb_msg').slideDown();
	if (!keepOnScreen) {
		setTimeout('TB_hideMessages()',8000);
	}
}

function TB_hideMessages() {
	jQuery('div.tb_msg').slideUp(1000,function(){jQuery('div.tb_msg').remove()});
}

// search: Wed, 27 May 2009 15:52:40 +0000
// user feed: Thu May 21 00:09:16 +0000 2009
function TB_str2date(dateString) {
	
	var dateObj = new Date(),
	dateData = dateString.split(/[\s\:]/);
	
	// if it's a search format
	if (dateString.indexOf(',') >= 0) {
		// $wday,$mday, $mon, $year, $hour,$min,$sec,$offset
		dateObj.setUTCFullYear(dateData[3],TB_monthNumber[""+dateData[2]]-1,dateData[1]);
		dateObj.setUTCHours(dateData[4],dateData[5],dateData[6]);
	}
	// if it's a user feed format
	else {
		// $wday,$mon,$mday,$hour,$min,$sec,$offset,$year
		dateObj.setUTCFullYear(dateData[7],TB_monthNumber[""+dateData[1]]-1,dateData[2]);
		dateObj.setUTCHours(dateData[3],dateData[4],dateData[5]);
	}

	return dateObj;
}

function TB_verbalTime(dateObj) {
   
    var j,
	now = new Date(),
	difference,
	verbalTime,
	prefix = '',
	postfix = '';
	
	if (now.getTime() > dateObj.getTime()) {
		difference = Math.round((now.getTime() - dateObj.getTime()) / 1000);
		postfix = ' ago';
	}
	else {
		difference = Math.round((dateObj.getTime() - now.getTime()) / 1000);
		prefix = 'in ';
	}
		
   
    for(j = 0; difference >= TB_timePeriodLengths[j] && j < TB_timePeriodLengths.length; j++) {
        difference = difference / TB_timePeriodLengths[j];
    }
    difference = Math.round(difference);
   
    verbalTime = TB_timePeriods[j];
    if (difference != 1) {
        verbalTime += 's';
    }
   
    return prefix + difference + ' ' + verbalTime + postfix;
}

jQuery(document).ready(function() {
	TB_init();
});

// backup firing of init in 4 seconds
TB_tmp = setTimeout('TB_init()',4000);
