
/**
 * Object to handle twitter searching.
 */
var twitterSearcher = {
	newestPID : 0,
	outstanding : 0,
	servertime: -1,
	proxyURL : '',
	cid : '',
	maxLoad : 6,
	q: '',
	
	rateContainers: [],
	
	contentContainer: null,
	
	
	buildQueryUrl: function() {	
		var url = "http://search.twitter.com/search.json?q=" + this.q +
					"&lang=en&rpp=" + this.maxLoad; 
		
		url += "&rand=" + Math.random() + 
			   "&callback=?";

		return url;												
	},

	/**
	 * Static function to template dates.
	 */
	printDate: function(date) {
		var hours = date.getHours();
		hours = hours > 12 ? hours - 12 : hours;
		hours = hours == 0 ? "12" : hours;
		var mins = date.getMinutes();
		mins = mins < 10 ? '0' + mins : mins;
		var hh = (date.getHours() > 11 ? " PM" : " AM");
		var day = date.getDate();
		var month = date.getMonth() + 1;
		var year = date.getFullYear();	
		
		return  "<b>" + hours + ":" + mins + hh + "</b> (" + day + "/" + month + "/" + year + ")";
	},
	
	/**
	 * Static function to template links in tweet.
	 */
	createLinks: function(str) {
		var linkedAlready = str.indexOf("</a>");

		if(linkedAlready == -1) {
			var start = str.indexOf("http://");
			var end = 0;
			if(start >= 0) {
				end = str.indexOf(' ', start);
				end = end == -1 ? str.length : end;	
				var url = str.substring(start, end);
				str = str.replace(url, "<a class='tweet-inline-url' href='" + url + "'>" + url + "</a>");
			}
		}
		return str;
	},
		
	doSearch: function(callback) {
		var url = this.buildQueryUrl();
		
		$.getJSON(url, function(data) {
			callback(data.results);
		});
	},
	
	
	getSpeed: function() {
		// currently not supported.
		return 0;
	}
};

/**
 * Object associated with the control of a story search
 */
var searchStory = {
		/** Private control class of a search story */
		control_obj: {
			button: null,
			content: null,
			parent: null,
			
			init: function(parent, button, content) {
				this.button = button;
				this.content = content;
				this.parent = parent;
				
				var self = this;
				this.button.bind('click', function() {
					// If navigation is enabled.
					if(self.parent.control_lock == 0) {
						this.style.color = '#3366AA';
						self.parent.control_lock = 1;
						self.parent.moveArrow($(this).position().top);
						self.parent.updateContent(self);
					}
				});
			}
		},
		
		blogs: null,
		news: null,
		twitter: null,
		
		contentCon:null,
		arrowCon:null,
		
		control_lock : 0,
		twitter_obj : null,
		
		visible:null,
		
		init: function(blogsButton, blogsContent,
						newsButton, newsContent,
						twitterButton, twitterContent,
						arrowCon, contentCon, twitter_query) {
			
			this.blogs = Object.create(this.control_obj);
			this.news = Object.create(this.control_obj);
			this.twitter = Object.create(this.control_obj);
			this.arrowCon = arrowCon;
			
			this.contentCon = contentCon;
			
			// visible selected based on page content.
			this.visible = newsContent.html().trim().length != 0 ?
											this.news : this.blogs;
			
			this.twitter_obj = Object.create(twitterSearcher);
			
			this.twitter_obj.q = twitter_query;
			
			this.blogs.init(this, blogsButton, blogsContent);
			this.news.init(this, newsButton, newsContent);
			this.twitter.init(this, twitterButton, twitterContent);
		},
		
		/** 
		 * Given a top position, move the arrow to this position.
		 */
		moveArrow: function(buttonTop) {
			this.arrowCon.animate({
				top: buttonTop + 4
			}, 150);
		},
		
		/**
		 * Update content in the dom based on control being clicked.
		 */
		updateContent: function(control) {
			
			// Same control.
			if(control == this.visible) {
				//Release lock and return.
				this.control_lock = 0;
				return;
			}
			
			// Change old visible button back to grey.
			this.visible.button.css('color','#AAAAAA');
			
			// Handle updating on content based on control.
			if(control === this.blogs) {
				this.visible.content.hide();
				this.twitter.content.hide();
				this.blogs.content.fadeIn('fast');
			} else if(control === this.news) {
				this.visible.content.hide();
				this.twitter.content.hide();
				this.news.content.fadeIn('fast');	
			} else if(control == this.twitter) {
				this.contentCon.fadeTo(100, 0.5);
				
				// Grab the loading gif.
				_loading = jQuery(this.twitter.button.children()[0]);
				_loading.css('display', 'inline');
				
				_self = this;
				// Perform the twitter search.
				this.twitter_obj.doSearch(function(posts) {
					
					if(posts && posts.length > 0) {	
						// Draw the twitter posts in the hidden container.
						_self.drawTwitter(posts);
					
						_self.contentCon.css('opacity', 0);
						
						// Hide old content.
						_self.news.content.hide();
						_self.blogs.content.hide();
						
						// Update content to twitter.
						_self.contentCon.animate({
						height: Math.max(100,_self.twitter.content.height() + 10)
						}, 500, function() { 
									_self.twitter.content.fadeIn('fast');
									_self.contentCon.fadeTo(100, 1);
									_self.visible = _self.twitter;
									_self.control_lock = 0;
									_loading.css('display', 'none');
								});
						
					} else {
						// No tweets display error.
						_self.visible = _self.twitter;
						_self.twitter.content.html("<div class='twitter-none'>No related tweets found</div>");
						
						_self.news.content.hide();
						_self.blogs.content.hide();
						
						_self.twitter.content.fadeIn('fast');
						_self.contentCon.fadeTo(100, 1);
						_loading.css('display', 'none');
						_self.control_lock = 0;
					}
				});
				// all code below handled in concurrent callback.
				return;
			}
			
			if(this.visible == this.twitter) {
				this.contentCon.fadeTo(100, 1);
				var self = this;
				this.contentCon.animate({
					height: '70'
				}, 500);
				
			}
			// set the new visible control
			this.visible = control;
			// release controlling lock.
			this.control_lock = 0;
		},
		
		drawTwitter: function(posts) {
			_self.twitter.content.html(tmpl("twitter_search_template", {posts:posts}));
		}
};