var TB_version = '2.4.5',	// Plugin version 
TB_config,
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_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"),
TB_urlCounter = 0,
TB_urlsToExpand = new Array(),
TB_expandedUrls = new Object,
TB_shortUrlIds = new Object;

function TB_init() {

	// prevent initializing twice
	if (TB_started) {
		return;
	}
	else {
		TB_started = true;
	}
		
	TB_config = {
		'general_source_ids':"@VIDEOfeet",
		'widget_tweets_num':1,
		'general_tiny_urls':"keep",
		'filter_lang':"  ",
        'widget_refresh_rate':60,
	};
	if ("true" == '') {
		TB_config['widget_show_screenname'] = false;
	}
	else {
		TB_config['widget_show_screenname'] = false;
	}
        if ("true" == '') {
		TB_config['widget_show_photos'] = false;
	}
	else {
		TB_config['widget_show_photos'] = false;
	}
	if ("true" == '') {
		TB_config['widget_show_source'] = false;
	}
	else {
		TB_config['widget_show_source'] = false;
	}
	if ("" == '') {
		TB_config['widget_show_reply_link'] = false;
	}
	else {
		TB_config['widget_show_reply_link'] = true;
	}
	if ("" == '') {
		TB_config['widget_show_follow_link'] = false;
	}
	else {
		TB_config['widget_show_follow_link'] = true;
	}
	if ("true" == '') {
		TB_config['widget_notify_about_limit'] = false;
	}
	else {
		TB_config['widget_notify_about_limit'] = true;
	}
	if ("" == '') {
		TB_config['filter_hide_replies'] = false;
	}
	else {
		TB_config['filter_hide_replies'] = true;
	}

	/* check opt out
	jQuery.ajax({
		dataType: 'jsonp',
		url: 'http://tweet-blender.com/check_optout.php',
		data: ({
			u: window.location.href,
			s: TB_config.general_source_ids,
			r: TB_config.widget_refresh_rate,
			v: 'wb_' + TB_version,
			l: TB_config.filter_lang
		}),
		success: function (json) {
			// if couldn't check - assume optout
			if (json.ERROR) {
				TB_hide_link();
			}
			else {
				if (json.chk > 0) {
					TB_hide_link();
				}
				else {
					TB_show_link();
				}
			}
		},
		error: TB_hide_link
	});
*/
TB_show_link();
	
	// make sure plugins are available
	if (typeof(jQuery('body').simpletip) == 'undefined' && typeof(jQnc('body').simpletip) == 'function') {
		jQuery.prototype.simpletip = jQnc.prototype.simpletip;
	}
	
	if (typeof(TB_config.general_source_ids) == 'undefined' || TB_config.general_source_ids == '') {
			TB_showMessage('nosrc','Twitter sources to blend are not defined', true);
		
		// disable refresh
		jQuery('#refreshlink').remove();
	}
	else {
                TB_config['rate_limit_url'] = {
			'url': 'http://twitter.com/account/rate_limit_status.json',
			'dtype': 'jsonp'
		};
		
		TB_initInfoBox();
		TB_makeAjaxURLs();
		TB_showLoader();
		TB_blend();
	}
}

// hide link to author's homepage if this site has chosen to opt out
function TB_hide_link() {
	jQuery('#infolink').remove();
	jQuery('#tb_tools').css().width(28);
}
// show link to author's homepage
function TB_show_link() {
	jQuery('#infolink').css();
	jQuery('#tb_tools').css();
}

// form Twitter API queries - group all keywords and hashtags into one search query url, build individual URLs for screen names
function TB_makeAjaxURLs() {
	TB_config['ajaxURLs'] = new Array();
	var TB_searchTerms = new Array();
	
	jQuery.each(TB_config.general_source_ids.split(','),function(i,src) {
		src = jQuery.trim(src);
                // if it's a public screen name
		if (src.charAt(0) == '@' && src.indexOf('/') == -1) {
        		TB_config['ajaxURLs'].push({
        			'url': 'http://twitter.com/statuses/user_timeline.json?screen_name=' + src.substr(1) + '&count=' + TB_config['widget_tweets_num'],
        			'source':src.substr(1),
        			'private':0,
        			'dtype':'jsonp'
        		});
		}
		// if it's a list
		else if (src.charAt(0) == '@' && src.indexOf('/') > 1) {
      			TB_config['ajaxURLs'].push({
      				'url':'http://api.twitter.com/1/' + src.substr(1, src.indexOf('/') - 1) + '/lists/' + src.substr(src.indexOf('/') + 1) + '/statuses.json?count=' + TB_config['widget_tweets_num'],
      				'source':src.substr(1, src.indexOf('/') - 1) + '::' + src.substr(src.indexOf('/') + 1),
      				'privateSrc':0,
      				'dtype':'jsonp'
      			});
      		}
		// else it's a hash or keyword and will be grouped with the rest
		else {
			
			// check to make sure we are not over the query length limit
			if (escape(TB_searchTerms.join(' ')).length + src.length > 140) {
				TB_addSearchUrl(TB_searchTerms);
				TB_searchTerms = new Array();
				TB_searchTerms.push(src);
			}
			else {
        		TB_searchTerms.push(src); 
    	   	}
		}
	});
	
	// if there are terms that are not part of a query - add another query
	if (TB_searchTerms.length > 0) {
		TB_addSearchUrl(TB_searchTerms);
	}
	
}

function TB_addSearchUrl(termsArray) {
	var langFilter = '';
	if (typeof(TB_config['filter_lang']) != 'undefined' && TB_config.filter_lang.length == 2) {
		langFilter = '&lang=' + TB_config.filter_lang;
	}
      	TB_config['ajaxURLs'].push({
      		'url': 'http://search.twitter.com/search.json?q=&ors=' + escape(termsArray.join(' ')) + '&rpp=' + TB_config['widget_tweets_num'] + '&page=1' + langFilter,
      		'source':'search',
      		'privateSrc':0,
      		'dtype':'jsonp'
      	});
}

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('info','Powered by TweetBlender widget 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...');
	
	jQuery.ajax({
      		url: TB_config.rate_limit_url.url,
      		dataType: TB_config.rate_limit_url.dtype,
		success: function(json){
      			// if can't get the limit or reached it
			if (json.error || json.remaining_hits < TB_config.ajaxURLs.length) {
                            if(TB_config.widget_notify_about_limit) {
				TB_showMessage('limit','You reached Twitter API 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('div').size() == 0) {
			TB_showMessage('notweets','No tweets found for ' + TB_config.sourcesHTML, true);
		}
		else {
			TB_hideMessage('notweets');
		}
	}
}

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,urlInfo) {
		TB_getFreshTweets(urlInfo);
		});
	}

function TB_getFreshTweets(urlInfo) {
      	jQuery.ajax({
		dataType: urlInfo.dtype,
		url: urlInfo.url,
      		success: function (json) {
			// if we had valid JSON but with error
			if (json.error) {
				// if we reached the API limit
				if (json.error.indexOf('Rate limit exceeded') == 0 && TB_config.widget_notify_about_limit) {
        				TB_showMessage('limit','You reached Twitter API connection limit.', false);
				}
				TB_config.urlsDone++;
				TB_checkComplete();
			}
			else {
				TB_addTweets(json);
			}
      		},
      		error: function() {
			TB_config.urlsDone++;
			TB_checkComplete();
                }
  	});
}
	
function TB_showFullUrl(shortUrlId,fullUrl) {

	if (fullUrl == '') return;
	if (jQuery('#tb_url_' + shortUrlId + 'e').length > 0) return;

	var linkEl = jQuery('#tb_url_' + shortUrlId);
	switch(TB_config.general_tiny_urls) {
		case "showicon":
			linkEl.after('<span><img class="urlexpand" src="http://www.urlexpand.com/img/urlexpand-icon.png" alt="' + fullUrl + '"></span>');
			TB_addTooltip(linkEl.next());
			break;
		case "showhint":
			linkEl.attr('title',fullUrl);
			break;
		case "replace":	
			linkEl.html(fullUrl);
			break;
	}
	
	// mark it as expanded
	jQuery('#tb_url_' + shortUrlId).attr('id','tb_url_' + shortUrlId + 'e');
}

function TB_expandUrls() {

	// go through URLs list and see which ones need to be expanded
	while(shortUrl = TB_urlsToExpand.shift()) {
		jQuery.ajax({
			dataType: 'jsonp',
			url: 'http://www.urlexpand.com/json',
			data: {
				u:shortUrl,
				k:'853548444daf0029003a5211c313e924'
			},
			success: function (jsonData) {
				// if we have full url
				if (jsonData.e) {
					// find ID of the short url and expand it
					TB_expandedUrls[jsonData.u] = jsonData.e;
					TB_showFullUrl(TB_shortUrlIds[jsonData.u],jsonData.e);
				}
				else {
					return false;
				}
			},
			error: function() {
				return false;
			}
		});
	}
}

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 we don't show replies and this is a reply, skip it
		if (TB_config.filter_hide_replies && tweet.in_reply_to_user_id) {
			return true;
		}
		// 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['widget_tweets_num']) {
				return false;
			}
			else {
				TB_tweetsShown++;

				// add at the end
				jQuery('#tweetlist').append(TB_makeHTML(tweet));

				// 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 div.tb_tweet').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++;
			}
		}

		// wire mouseover action items
		if (TB_config.widget_show_reply_link || TB_config.widget_show_follow_link) {
			jQuery('#'+tweet.id).hover(
		      function () {
				jQuery(this).find("div:last").slideDown();
				setTimeout('jQuery("#' + tweet.id + '").find("div:last").slideUp()',4000);
		      }, 
		      function () {
		        jQuery(this).find("div:last").slideUp();
		      }
		);
}
		
	});

	TB_config.urlsDone++;
	TB_checkComplete();
      	TB_expandUrls();
    	if (TB_config.general_tiny_urls == 'showicon') {
        	TB_addTooltips();
      	}
}

function TB_enforceLimit() {
	if (TB_tweetsShown == TB_config['widget_tweets_num']) {
		var lastTweet = jQuery('#' + TB_minTweetID),
		nextToLastTweet = lastTweet.prev('div.tb_tweet');
		
		// 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,
	shortUrls;
	
	// add screen name if from_user is given
	if (typeof(tweet.user) == 'undefined') {
		if (tweet.from_user) {
		tweet.user = {
			screen_name: tweet.from_user
		};
	}
		else {
			tweet.user = {
				screen_name: ''
			};
		}
	}
	
	tweetHTML += '<div class="tb_tweet" id="' + tweet.id + '">';
	
	// show photo if requested
	if (TB_config['widget_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" rel="nofollow" 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

	if (TB_config['widget_show_screenname']) {
         	tweetHTML += '<span class="tb_author"><a rel="nofollow" href="http://twitter.com/' + tweet.user.screen_name + '" target="_blank">' + tweet.user.screen_name + '</a>: </span> ';
        }

	// if we are expanding URLs
	if (TB_config.general_tiny_urls != "keep") {
		
		if (shortUrls = tweet.text.match(/http\:\/\/[a-z0-9]{1,7}\.[a-z]+\/[a-z0-9]+/gi)) {
			jQuery.each(shortUrls,function(i,shortUrl) {
				shortUrl = jQuery.trim(shortUrl);
				
				// if we don't have expanded url already -> use it
				if (TB_expandedUrls[shortUrl]) {
					fullUrl = 	TB_expandedUrls[shortUrl];

					switch(TB_config.general_tiny_urls) {
						case "showicon":
							tweet.text = tweet.text.replace(shortUrl, '<a rel="nofollow" href="' + shortUrl + '" target="_blank">' + shortUrl + '</a><span><img class="expandicon" src="http://urlexpand.com/img/urlexpand-icon.png" alt="' + fullUrl +'" /></span>');
							break;
						case "showhint":
							tweet.text = tweet.text.replace(shortUrl, '<a rel="nofollow" href="' + shortUrl + '" target="_blank" title="[' + fullUrl + '] by URLexpand.com">' + shortUrl + '</a>');
							break;
						case "replace":	
							tweet.text = tweet.text.replace(shortUrl, '<a rel="nofollow" href="' + shortUrl + '" target="_blank">' + fullUrl + '</a>');
					}
				}
				// else tag it for future expansion
				else {
					TB_urlsToExpand.push(shortUrl);
					TB_shortUrlIds[shortUrl] = TB_urlCounter;
					tweet.text = tweet.text.replace(shortUrl, '<a rel="nofollow" id="tb_url_' + TB_urlCounter + '" href="' + shortUrl + '" target="_blank">' + shortUrl + '</a>');
					TB_urlCounter++;
				}

			});
		}
		else {
			tweet.text = tweet.text.replace(/(https?:\/\/\S+)/gi, '<a rel="nofollow" href="$1" target="_blank">$1</a>');
		}
	}
	// if we are not expanding -> still link
	else {
           tweet.text = tweet.text.replace(/(https?:\/\/\S+)/gi,'<a rel="nofollow" href="$1" target="_blank">$1</a>'); 
	}

	// screen names
	tweet.text = tweet.text.replace(/\@([^\s\.\:]+)/gi,'<a rel="nofollow" href="http://twitter.com/$1" target="_blank">@$1</a>'); 
	tweet.text = tweet.text.replace(/\#([^\s\,]+)/gi,'<a rel="nofollow" href="http://search.twitter.com/search?q=%23$1" target="_blank">#$1</a>'); 
	tweetHTML += '<span class="tb_msg">' + tweet.text + '</span><br/>';

        if(TB_config.widget_show_source) {

        	// start tweet footer with info
        	tweetHTML += ' <span class="tb_tweetinfo">';
        	
        	// show timestamp
        	tweetHTML += '<a rel="nofollow" target="_blank" href="http://twitter.com/' + tweet.user.screen_name + '/statuses/' + tweet.id + '">';
        	tweetDate = TB_str2date(tweet.created_at);
        	tweetHTML += TB_verbalTime(tweetDate);
        	tweetHTML += '</a>';
        	
        	// show source if requested
        	if (tweet.source) {
                	tweetHTML += ' from ';
                        tweet.source = tweet.source.replace('a ','a target="_blank"');
                	// 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
        if (TB_config.widget_show_follow_link || TB_config.widget_show_reply_link) {
        	tweetHTML += '<div class="tweet-tools" style="display:none;">';
                if (TB_config.widget_show_reply_link) {
                  tweetHTML += '<a rel="nofollow" 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/>';
                }
                if (TB_config.widget_show_follow_link && TB_config.widget_show_reply_link) {
                  tweetHTML += ' | ';
                }
                if (TB_config.widget_show_follow_link) {
                  tweetHTML += '<a rel="nofollow" href="http://twitter.com/' + tweet.user.screen_name + '" target="_blank">follow ' + tweet.user.screen_name + '</a>';
                }
                tweetHTML += '</div>'; 
        }

	// end tweet	
	tweetHTML += "</div>\n";

	return tweetHTML;
}

function TB_addTooltips() {
	jQuery('img.urlexpand').each(function(){
		TB_addTooltip(jQuery(this).parent());
	});
}

function TB_addTooltip(imgEl) {
	imgEl.simpletip({
		content: imgEl.contents().attr('alt'),
		fixed: true,
		position: ["-20","-16"]
	});
}

function TB_showLoader() {
	jQuery('#refreshlink img').attr('src','http://hosting.gmodules.com/ig/gadgets/file/112712082932746590397/ajax-refresh.gif');
	jQuery('#refreshlink').addClass('loading');
}

function TB_hideLoader() {
	jQuery('#tb_loading').hide();
	jQuery('#refreshlink img').attr('src','http://hosting.gmodules.com/ig/gadgets/file/112712082932746590397/ajax-refresh-icon.gif');
	jQuery('#refreshlink').removeClass('loading');
}

function TB_showTweetList() {
	TB_hideLoader();
	jQuery('#tweetlist').show();
}

function TB_showMessage(id, msg, keepOnScreen){
	TB_hideLoader();
	// if it doesn't exist
	if (!jQuery('#msg_' + id).length) {
		jQuery('#tweetlist').before('<div id="msg_' + id + '" class="tb_msg" style="display:none;">' + msg + '</div>');
		jQuery('#msg_' + id).slideDown();
	if (!keepOnScreen) {
			setTimeout('TB_hideMessage("' + id + '")', 8000);
		}
	}
	// else if it's hidden
	else if (jQuery('#msg_' + id).is(':hidden')) {
		jQuery('#msg_' + id).slideDown();
	}
}

function TB_hideAllMessages() {
	jQuery('div.tb_msg').slideUp(1000,function(){jQuery('div.tb_msg').remove()});
}

function TB_hideMessage(id) {
	jQuery('#msg_' + id).slideUp(1000,function(){jQuery('#msg_' + id).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(window).load(TB_init);
jQuery(document).ready(TB_init);
// backup firing of init in 4 seconds
TB_tmp = setTimeout('TB_init()',4000);
