var CspanTwitter = function(name, container) {
	//Object declaration
	this.Name = name == undefined ? 'twitter' : name;
	this.Container = container == undefined ? 'twitter_box' : container;
	//Public properties
	this.SearchTag = '';
	this.Blacklist = 'shit|piss|fuck|cunt|cocksucker|motherfucker|tits';
	this.TweetsPerPage = 5;
	this.TimerSecs = 20;
	this.SearchLinkText = 'View results on Twitter';
	this.CounterText = '%d more results - <a href="%c">Refresh</a><br/>';
	this.ShowProfilePics = true;
	this.AutoRefresh = false;

	//Private properties
	this.Twits = Array();
	this.FirstCallBackRun = true;
	this.ShowNoResultsFoundMessage = false;
	this.FilterLinks = false;
	this.LastTweetID = '';
	this.CounterNewTweets = 0;
	this.TwitterTimer = '';
	this.CallbackFunctionName = this.Name + '.CallBack';
	this.PaginatorId = 'twitter_pagination';
	this.SearchLinkId = 'twitter_search';
}

CspanTwitter.prototype.TwitterCall = function(search_tag, last_tweet_id, callback_function_name) {
	if (this.TwitterTimer != '') {
		clearTimeout(this.TwitterTimer);
	}

	this.SearchTag = search_tag == undefined ? this.SearchTag : search_tag;

	if (this.FilterLinks) {
		this.SearchTag += '+-filter%3Alinks';
	}

	var maxResultsNumber = this.TweetsPerPage * 5;
	this.LastTweetID = last_tweet_id == undefined ? this.LastTweetID : last_tweet_id;
	this.CallbackFunctionName = callback_function_name == undefined ? this.CallbackFunctionName : callback_function_name;

	var query = 'http://search.twitter.com/search.json?q=' + this.SearchTag + '&callback=' + this.CallbackFunctionName + '&lang=en&rpp=' + maxResultsNumber.toString();

//	this.SearchTag = 'kmac23va/lists/us-senators';
//	var query = 'http://api.twitter.com/1/' + this.SearchTag + '/statuses.json?per_page=' + maxResultsNumber.toString();

	if (this.LastTweetID != '') {
		query += '&since_id=' + this.LastTweetID;
	}

	var script = document.createElement('script');
	script.setAttribute('src', query);
	script.setAttribute('type', 'text/javascript');
	document.getElementsByTagName('head')[0].appendChild(script);
}

CspanTwitter.prototype.CallBack = function(twitter_object) {
	var got_error = false;

	if (!twitter_object) {
		got_error = true;
	}

	if (!got_error) {
		if (twitter_object.results && twitter_object.results.length) {
			var results = twitter_object.results;
			this.LastTweetID = results[0].id;

			for (i = results.length - 1; i >= 0; i--) {
				this.Twits.unshift(results[i]);
			}

			if (this.FirstCallBackRun) {
				this.FirstCallBackRun = false;
				this.RenderTweetsPage(1, true);
			} else {
				this.CounterNewTweets = this.CounterNewTweets + results.length;

				if (this.CounterNewTweets > 0) {
					if (this.AutoRefresh) {
						this.RenderTweetsPage(1, true);
					} else {
						update_fade_inout('twitter_counter', this.CounterText.replace('%d', this.CounterNewTweets).replace('%c', 'javascript:' + this.Name + '.RenderTweetsPage(1, true)'));
					}
				}
			}
		} else {
			if ('' == this.LastTweetID) {
				update_fade_inout('twitter_entries', 'There is no information on Twitter for this search at this time.');

				if (this.PaginatorId) {
					update_fade_inout(this.PaginatorId, 'Pages: 1');
				}
			}

			if (this.FirstCallBackRun && this.ShowNoResultsFoundMessage) {
				document.getElementById(this.Container).innerHTML = 'There is no information on Twitter for this search at this time.';
			}
		}
	}

	if (!got_error && !this.FirstCallBackRun && twitter_object.results && twitter_object.results.length != 0) {
		this.TwitterTimer = this.setTwitterTimeout(this.TimerSecs * 1000, 'TwitterCall', this.SearchTag, this.LastTweetID);
	}
}

CspanTwitter.prototype.setTwitterTimeout = function(msec, method) {
	var that = this;
	var args = Array.prototype.slice.apply(arguments, [2]);
	if (typeof method === 'string') {
		method = that[method];
	}

	return setTimeout(function() {
		method.apply(that, args);
	}, msec);
}

CspanTwitter.prototype.RenderTweetsPage = function(page, refresh) {
	if (refresh) {
		update_fade_inout('twitter_counter', '');
		this.LastLen = this.Twits.length;
		this.CounterNewTweets = 0;
	}

	var tweets = '';
	var current_date = new Date();
	var curr_len = this.Twits.length;
	twarr = this.Twits.slice(curr_len - this.LastLen);
	var ftw = (page - 1) * this.TweetsPerPage;
	var ltw = ftw + this.TweetsPerPage - 1;

	if (ltw >= this.LastLen) {
		ltw = this.LastLen - 1;
	}

	for (var c = ftw; c <= ltw; c++) {
		var tweet = twarr[c];
		var user = tweet['user'];
		var fromUser = '';
		var profileImg = '';

		if (YAHOO.lang.isUndefined(user)) {
			fromUser = tweet['from_user'];
			profileImg = tweet['profile_image_url'];
		} else {
			fromUser = user['screen_name'];
			profileImg = user['profile_image_url'];
		}

		var tweetId = tweet['id'];
		var text = tweet['text'];
		var source = tweet['source'].replace(/&lt;/gi, '<').replace(/&gt;/gi, '>').replace(/&quot;/gi, '"').replace(/&amp;/gi, '&');
		var time_passed = elapsedTime(current_date, new Date(tweet['created_at']));

		var checkTweet = fromUser.toLowerCase() + ' ' + text.toLowerCase();
		checkTweet = checkTweet.replace(eval("/(" + this.Blacklist.toLowerCase() + ")/gi"), 'BLACKLIST');
		var passBlacklist = checkTweet.indexOf('BLACKLIST') == -1 ? true : false;

		if (passBlacklist) {
			tweets += '<div class="single_twitt">';

			if (this.ShowProfilePics) {
				tweets += '    <div class="twitter_img">';
				tweets += '        <a rel="nofollow" href="http://twitter.com/' + fromUser + '" target="_blank"><img src="' + profileImg + '"><br/>Read<br/>More<br/>Tweets</a>';
				tweets += '    </div>';
			}

			if (!this.FilterLinks) {
				text = linkify.clean(text);
			}

			tweets += '    <div class="twitter_content">';
			//tweets += '        <a rel="nofollow" href="http://twitter.com/' + fromUser + '" target="_blank">' + fromUser + '</a>: ' + text;
			tweets += text;
			tweets += '        <div class="twitt_status">';
			tweets += '            <a rel="nofollow" href="http://twitter.com/' + fromUser + '/status/' + tweetId + '" target="_blank">' + time_passed + '</a> from ' + source;
			tweets += '        </div>'
			tweets += '    </div>'
			tweets += '</div>';
			tweets += '<div style="clearFloat"></div>';
			tweets += c != ltw ? '<hr class="twitter_seperator"/>' : '';
		}
	}

	//var pagination = this.PaginationTweets(page, this.LastLen);
	//document.getElementById(this.PaginatorId).innerHTML = pagination;
	//document.getElementById(this.SearchLinkId).innerHTML = '<a href="http://search.twitter.com/search?q=' + this.SearchTag + '" target="_blank">' + this.SearchLinkText + '</a>';
	update_fade_inout('twitter_entries', tweets);
}

CspanTwitter.prototype.PaginationTweets = function(page, total) {
	var pagination = 'Pages: ';
	var epsilon = 4;
	var per_page = this.TweetsPerPage;

	if (1 < (page - epsilon)) {
		pagination += '<a href="javascript:' + this.Name + '.RenderTweetsPage(1);">1</a> ';

		if (1 < (page - epsilon - 1)) {
			pagination += '... ';
		}
	}

	var pages = Math.ceil(total / per_page);
	var first = page - epsilon;
	var last = page + epsilon;

	if (first < 1) {
		first = 1;
	}

	if (last > pages) {
		last = pages;
	}

	for (var i = first; i <= last; i++) {
		var p = (i - 1) * 4;

		if (i == page) {
			pagination += '<strong>' + i + '</strong> ';
		} else {
			pagination += '<a href="javascript:' + this.Name + '.RenderTweetsPage(' + i + ');">' + i + '</a> ';
		}
	}

	if ((page + epsilon) < pages) {
		if ((page + epsilon + 1) < pages) {
			pagination += '... ';
		}

		pagination += '<a href="javascript:' + this.Name + '.RenderTweetsPage(' + pages + ');">' + pages + '</a> ';
	}

	return pagination;
}

window.linkify = function() {
	var entities = { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };
	return { "at": function(t) {
		return t.replace(/(^|[^\w]+)\@([a-zA-Z0-9_]{1,15})/g, function(m, m1, m2) {
			return m1 + '@<a href="http://twitter.com/' + m2 + '" target="_blank">' + m2 + '</a>';
		});
	}, "hash": function(t) {
		return t.replace(/(^|[^\w'"]+)\#([a-zA-Z0-9_]+)/g, function(m, m1, m2) {
			return m1 + '#<a href="http://search.twitter.com/search?q=%23' + m2 + '" target="_blank">' + m2 + '</a>';
		});
	}, "clean": function(tweet) {
		return this.hash(this.at(autolink(tweet)));
	} 
	};
} ();

function autolink(string) {
	var regex = /((http\:\/\/|https\:\/\/|ftp\:\/\/)|(www\.))+(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi;

	string = string.replace(regex, function(value) {
		var m = value.match(/^([a-z]+:\/\/)/);
		var url;

		if (m) {
			url = value;
		} else {
			url = 'http://' + value;
		}

		return '<a href="' + url + '" target="_blank">' + url + '</a>';
	});

	return string;
};

function update_fade_inout(id, msg) {
	var fadeOut = new YAHOO.util.Anim(id, { opacity: { to: 0} }, 0.5);
	var fadeIn = function(type, args) {
		document.getElementById(id).innerHTML = msg;

		if (!(id == 'twitter_counter' && msg == '')) {
			var fadeIn = new YAHOO.util.Anim(id, { opacity: { to: 1} }, 0.5);
			fadeIn.animate();
		}
	};

	fadeOut.onComplete.subscribe(fadeIn);
	fadeOut.animate();
}

function elapsedTime(currentDate, createdAt) {
	var ageInSeconds = Math.floor((currentDate - createdAt) / 1000);

	var s = function(n) {
		return n == 1 ? '' : 's'
	};

	if (ageInSeconds < 30) {
		return 'less than a minute ago';
	}

	if (ageInSeconds < 60) {
		return 'half a minute ago';
	}

	if (ageInSeconds < 60 * 60) {
		var n = Math.floor(ageInSeconds / 60);
		return n + ' minute' + s(n) + ' ago';
	}

	if (ageInSeconds < 60 * 60 * 24) {
		var n = Math.floor(ageInSeconds / 60 / 60);
		return n + ' hour' + s(n) + ' ago';
	}

	if (ageInSeconds < 60 * 60 * 24 * 7) {
		var n = Math.floor(ageInSeconds / 60 / 60 / 24);
		return n + ' day' + s(n) + ' ago';
	}

	if (ageInSeconds < 60 * 60 * 24 * 31) {
		var n = Math.floor(ageInSeconds / 60 / 60 / 24 / 7);
		return n + ' week' + s(n) + ' ago';
	}

	if (ageInSeconds < 60 * 60 * 24 * 365) {
		var n = Math.floor(ageInSeconds / 60 / 60 / 24 / 31);
		return n + ' month' + s(n) + ' ago';
	}

	var n = Math.floor(ageInSeconds / 60 / 60 / 24 / 365);
	return n + ' year' + s(n) + ' ago';
}

