
/**
 * @param string keyword
 * @param Element container
 * @param object parameters {
 * 		maxTwitts:10,
 * 		width:300px,
 * 		height:300px,
 * 		refreshPeriod:10000,
 * 		alias:['alias1','alias2'], // OR 'alias' - alias searches
 * 		titleLink:'http://www.google.com' // the widget title link
 * 		noHeader:false // hide the header
 * 		enableTweet:false // displays "post a tweet" button
 * 		postTweet_ButtonCaption:'post a tweet' // "post a tweet" button caption
 * 		postTweet_Text:'' // "post a tweet" default text
 * 		postTweet_currentPageLink:false // displays short url to current page
 * 		postTweet_currentPageLinkOptional:false // displays short url to current page
 * 		enableRetweet:false // displays retweet button
 * 		enablePagination:false // displays multiple twitt pages
 * 		adminMode:false // enables admin mode
 * }
 */

function WVliveTwitt(keyword, container, parameters){
	this.maxTwitts = 10;
	this.refreshPeriod = 10000; // miliseconds
	this.originalRefreshPeriod = 10000; // miliseconds
	this.keyword = keyword;
	this.serverUrl = "http://search.twitter.com";
	this.twitts = Array();
	this.max_id = 0;
	this.widgetWidth = '300px';
	this.displayedTwitts = Array();
	this.page = 1;
	
	var max_pages = 15;
	
	this.minRefreshPeriod = 6000;
	WVliveTwitt.months = Array('January','February','March','April','May','June','July','August','September','October','November','December');
	WVliveTwitt.monthsAbbr = Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	
	this.bannedUsers;
	
	var _self = this;
	var main_window = window;
	var widget_base_url = "http:\/\/www.socialpulse.com";
	var fan_base_url = "http:\/\/fan.yspan.com";
	var tweet_posting_required = false;
	
	//////////
	// init //
	//////////
	
	if(typeof(parameters)!='object'){
		parameters = {};
	}
	
	if(typeof(container)=='object' && container){
		this.container = container;
	}
	else{
		var container_id = 'WVliveTwitt-generate-container-'+Math.random();
		document.write("<div id=\""+container_id+"\"></div>");
		this.container = document.getElementById(container_id);
	}
	
	
	// load jquery
	this.load_jquery = function(){
		if(typeof($)!='function'){
			var jquery_script = document.createElement('script');
			jquery_script.type = 'text/javascript';
			jquery_script.src = widget_base_url+'/3rd_party/jquery.js';
			this.container.appendChild(jquery_script);
			return false;
		}
		else{
			return true;
		}
	}
	
	// load jquery ui
	this.load_jqueryui = function(){
		if(typeof($(this.container).show)!='function'){
			var jquery_ui_script = document.createElement('script');
			jquery_ui_script.type = 'text/javascript';
			jquery_ui_script.src = widget_base_url+'/3rd_party/jquery-ui.js';
			this.container.appendChild(jquery_ui_script);
			return false;
		}
		else{
			return true;
		}
	}
	
	// load css
	if(typeof(WVliveTwitt.css_loaded)!='boolean' || WVliveTwitt.css_loaded==false){
		var css_elem = document.createElement('link');
		css_elem.rel = 'stylesheet';
		css_elem.type = 'text/css';
		css_elem.href = widget_base_url+'/css/live_twitts.css';
		this.container.appendChild(css_elem);
		WVliveTwitt.css_loaded = true;
	}
	
	this.parameters = parameters;
	
	if(typeof(parameters.maxTwitts)=='number'){
		this.maxTwitts = parameters.maxTwitts;
	}
	
	// alias
	if(typeof(this.parameters.alias)=='string'){
		var temp = this.parameters.alias;
		this.parameters.alias = Array();
		this.parameters.alias.push(temp);
	}
	if(typeof(this.parameters.alias)=='object'){
		this.minRefreshPeriod = (this.parameters.alias.length + 1) * this.minRefreshPeriod;
	}
	
	if(typeof(parameters.refreshPeriod)=='number'){
		this.refreshPeriod = parameters.refreshPeriod;
		this.originalRefreshPeriod = parameters.refreshPeriod;
	}
	if(this.refreshPeriod<this.minRefreshPeriod){
		this.refreshPeriod = this.minRefreshPeriod;
		this.originalRefreshPeriod = this.minRefreshPeriod;
	}
	
	// width
	if(typeof(parameters.width)=='number'){
		parameters.width = parameters.width+'px';
	}
	if(typeof(parameters.width)=='string'){
		this.widgetWidth = parameters.width;
	}
	
	// tweet
	if(typeof(this.parameters.enableTweet)!='boolean'){
		this.parameters.enableTweet = false;
	}
	else if(this.parameters.enableTweet){
		tweet_posting_required = true;
	}
	if(typeof(this.parameters.tweetButtonCaption)!='string' || !this.parameters.tweetButtonCaption){
		this.parameters.tweetButtonCaption = 'post a tweet';
	}
	if(typeof(this.parameters.defaultTweetText)!='string'){
		this.parameters.defaultTweetText = '';
	}
	if(typeof(this.parameters.postTweet_currentPageLink)!='boolean'){
		this.parameters.postTweet_currentPageLink = false;
	}
	if(typeof(this.parameters.postTweet_currentPageLinkOptional)!='boolean'){
		this.parameters.postTweet_currentPageLinkOptional = false;
	}
	
	//admin mode
	if(typeof(this.parameters.adminMode)!='boolean'){
		this.parameters.adminMode = false;
	}
	
	// retweet
	if(typeof(this.parameters.enableRetweet)!='boolean'){
		this.parameters.enableRetweet = false;
	}
	else if(this.parameters.enableRetweet){
		tweet_posting_required = true;
	}
	
	if(tweet_posting_required){
		// load window ui
		if(typeof(fan_window)!='fonction'){
			var window_script = document.createElement('script');
			window_script.type = 'text/javascript';
			window_script.src = fan_base_url+'/js/window.js';
			this.container.appendChild(window_script);
		}
		// load share framework
		if(typeof(fan_share_post_on_twitter)!='fonction'){
			var share_script = document.createElement('script');
			share_script.type = 'text/javascript';
			share_script.src = fan_base_url+'/js/sharev2.js';
			this.container.appendChild(share_script);
		}
	}
	
	this.widgetBody = document.createElement('div');
	this.widgetBody.className = 'WVliveTwitt_WidgetBody';
	this.widgetBody.style.width = this.widgetWidth;
	this.container.appendChild(this.widgetBody);
	
	this.innerContainer = document.createElement('div');
	this.innerContainer.className = 'WVliveTwitt_innerContainer';
	this.widgetBody.appendChild(this.innerContainer);
	
	this.headerContainer = document.createElement('div');
	this.headerContainer.className = 'WVliveTwitt_headerContainer';
	this.innerContainer.appendChild(this.headerContainer);
	
	this.headerLayoutTable = document.createElement('table');
	this.headerLayoutTable.className = 'WVliveTwitt_headerLayoutTable'
	this.headerContainer.appendChild(this.headerLayoutTable);
	
	this.headerLayout = document.createElement('tbody');
	this.headerLayoutTable.appendChild(this.headerLayout);
	
	this.headerLayoutRow = document.createElement('tr');
	this.headerLayout.appendChild(this.headerLayoutRow);
	
	this.headerTitle = document.createElement('td');
	this.headerTitle.className = 'WVliveTwitt_headerTitle';
	if(typeof(this.parameters.noHeader)!='boolean' || !this.parameters.noHeader){
		this.headerLayoutRow.appendChild(this.headerTitle);
	}
	if(typeof(parameters.titleLink)=='string' && parameters.titleLink){
		var titleLink_elem = document.createElement('a');
		titleLink_elem.className = 'WVliveTwitt_headerLink';
		titleLink_elem.href = parameters.titleLink;
		titleLink_elem.innerHTML = keyword+' live tweets';
		
		this.headerTitle.appendChild(titleLink_elem);
	}
	else{
		this.headerTitle.innerHTML = keyword+' live tweets';
	}
	
	// tweet button
	if(this.parameters.enableTweet){
		var tweetBtnContainer = document.createElement('td');
		tweetBtnContainer.className = 'WVliveTwitt_tweetBtnContainer';
		
		var tweetBtn = document.createElement('a');
		tweetBtn.className = 'WVliveTwitt_tweetBtn'; 
		tweetBtn.innerHTML = this.parameters.tweetButtonCaption;
		tweetBtn.onclick = function(){
			_self.updateStatus(
				_self.parameters.defaultTweetText,
				_self.parameters.postTweet_currentPageLink?main_window.location.href:'',
				_self.parameters.postTweet_currentPageLinkOptional
			);
		}
		
		var tweetBtnImg = document.createElement('img');
		tweetBtnImg.src = widget_base_url+"/images/icon/16/twitter.png";
		tweetBtnImg.align = 'absmiddle';
		tweetBtn.appendChild(tweetBtnImg);
		
		this.headerLayoutRow.appendChild(tweetBtnContainer);
		tweetBtnContainer.appendChild(tweetBtn);
	}
	
	this.twittsContainer = document.createElement('div');
	this.twittsContainer.className = 'WVliveTwitt_twittsContainer';
	this.innerContainer.appendChild(this.twittsContainer);
	
	// height
	if(typeof(parameters.height)=='number'){
		parameters.height = (parameters.height-60)+'px';
	}
	if(typeof(parameters.height)=='string'){
		this.twittsContainer.style.height = parameters.height;
	}
	
	
	//footer
	this.footerContainer = document.createElement('div');
	this.innerContainer.appendChild(this.footerContainer);
	this.footerContainer.className = 'WVliveTwitt_footerContainer';
	
	if(parameters.enablePagination){
		var pagination_container = document.createElement('div');
		pagination_container.className = 'WVliveTwitt_pagination_container';
		this.footerContainer.appendChild(pagination_container);
	}
	
	var powered_by_container = document.createElement('div');
	powered_by_container.className = 'WVliveTwitt_powered_by_container';
	this.footerContainer.appendChild(powered_by_container);
	
	var footer_powered = document.createElement('span');
	footer_powered.innerHTML = 'Powered by ';
	powered_by_container.appendChild(footer_powered);
	
	var twitt_img = document.createElement('img');
	twitt_img.src = 'http://widgets.twimg.com/j/1/twitter_logo_s.png';
	twitt_img.align = 'absmiddle';
	twitt_img.height = 15;
	twitt_img.width = 64;
	
	var twitt_a = document.createElement('a');
	twitt_a.href = 'http://twitter.com';
	twitt_a.target = '_blank';
	twitt_a.appendChild(twitt_img);
	powered_by_container.appendChild(twitt_a);
	
	this.display_pages = function(container){
		container.innerHTML = '';
		
		var prev_page_link = document.createElement('a');
		prev_page_link.href = '#';
		prev_page_link.innerHTML = "&laquo;previous page";
		if(_self.has_previous_page){
			prev_page_link.className = 'WVliveTwitt_active_page';
			prev_page_link.onclick = function(){
				_self.set_page(_self.page-1);
				return false;
			}
		}
		else{
			prev_page_link.className = 'WVliveTwitt_inactive_page';
			prev_page_link.onclick = function(){return false;};
		}
		container.appendChild(prev_page_link);
		
		var next_page_link = document.createElement('a');
		next_page_link.href = '#';
		next_page_link.innerHTML = "next page&raquo;";
		next_page_link.style.marginLeft = '25px';
		if(_self.has_next_page){
			next_page_link.className = 'WVliveTwitt_active_page';
			next_page_link.onclick = function(){
				_self.set_page(_self.page+1);
				return false;
			}
		}
		else{
			next_page_link.className = 'WVliveTwitt_inactive_page';
			next_page_link.onclick = function(){return false;}
		}
		container.appendChild(next_page_link);
		
		_self.has_previous_page
	}
	
	this.set_page = function(page){
		_self.page = page;
		_self.max_id = 0;
		_self.twittsContainer.innerHTML = '';
		_self.displayedTwitts = Array();
		this.refreshTwitts();
	}
	
	
	this.refreshTwitts = function(){
		
		if(!_self.load_jquery()){
			setTimeout(_self.refreshTwitts, 100);
			return;
		}
		if(!_self.load_jqueryui()){
			setTimeout(_self.refreshTwitts, 100);
			return;
		}
		
		var request = _self.serverUrl+'/search.json?output=jquery&callback=?';
		var data = {
			rpp:_self.maxTwitts,
			q:$.trim(_self.keyword),
//			since_id:_self.max_id,
			page:_self.page
		}
		$(document.body).ready(function(){
			jQuery.ajax({
				type: "GET",
				url: request,
				data: data,
				success: _self.refreshTwittsCallback,
				dataType: 'json'
			});
			
			if(typeof(_self.parameters.alias)=='object' && _self.parameters.alias){
				for(var i in _self.parameters.alias){
					if(!_self.parameters.alias[i]){
						continue;
					}
					data.q = $.trim(_self.parameters.alias[i]);
					
					jQuery.ajax({
						type: "GET",
						url: request,
						data: data,
						success: _self.refreshTwittsCallback,
						dataType: 'json'
					});
				}
			}
		});
		
		clearTimeout(_self.refreshTimeout); // to avoid multiple refreshes
		_self.refreshTimeout = setTimeout(_self.refreshTwitts, _self.refreshPeriod);
	}
	
	/**
	 * displays a twitt
	 * 
	 * @param object twittDetails
	 * @param object after_this_elem after a twitt in the list, if not given then displayed first
	 * 
	 * @return object twittItemElem
	 */
	
	this.displayTwitt = function(twittDetails, after_this_elem){
		var twittItemElem = document.createElement('div');
		twittItemElem.className = 'WVliveTwitt_twittItem';
		twittItemElem.style.display = 'none';
		
		var layout_table = document.createElement('table');
		layout_table.width = '100%';
		twittItemElem.appendChild(layout_table);
		
		var tbody_elem = document.createElement('tbody');
		layout_table.appendChild(tbody_elem);
		
		var line1 = document.createElement('tr');
		tbody_elem.appendChild(line1);
		
		var img_td = document.createElement('td');
		img_td.className = 'WVliveTwitt_img_td';
		line1.appendChild(img_td);
		
		if(typeof(twittDetails.profile_image_url)=='string' && twittDetails.profile_image_url){
			var user_img_link = document.createElement('a');
			user_img_link.href = 'http://twitter.com/'+ twittDetails.from_user;
			user_img_link.target = '_blank';
			user_img_link.title = twittDetails.from_user;
			img_td.appendChild(user_img_link);
			
			var user_img = document.createElement('img');
			user_img.className = 'WVliveTwitt_user_img';
			user_img.src = twittDetails.profile_image_url;
			user_img.title = twittDetails.from_user;
			user_img.border = 0;
			user_img_link.appendChild(user_img);
		}
		
		var msg_td = document.createElement('td');
		line1.appendChild(msg_td);
		
		var twittText = document.createElement('div');
		twittText.innerHTML = _self.build_links(twittDetails.text);
		msg_td.appendChild(twittText);
		
		var date_match = twittDetails.created_at.match(/[a-z]{3}, ([0-9]{2}) ([a-z]{3}) ([0-9]{4}) ([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2}) \+0000/i);
		var post_month = $.inArray(date_match[2], WVliveTwitt.monthsAbbr);
		
		var post_date = new Date();
		
		post_date.setUTCDate(date_match[1]);
		post_date.setUTCMonth(post_month);
		post_date.setUTCFullYear(date_match[3]);
		post_date.setUTCHours(date_match[4]);
		post_date.setUTCMinutes(date_match[5]);
		post_date.setUTCSeconds(date_match[6]);
		
		var footer = document.createElement('div');
		footer.className = 'WVliveTwitt_item_footer';
		footer.innerHTML = 'by <a href="http://twitter.com/'+ twittDetails.from_user+'" target="_blank">'+ twittDetails.from_user+'</a> on ' + WVliveTwitt.monthsAbbr[post_date.getMonth()] + ' ' + post_date.getDate() + ', ' + post_date.getFullYear() + ' ' + post_date.getHours() + ':' + post_date.getMinutes() + ':' + post_date.getSeconds();
		msg_td.appendChild(footer);
		
		if(typeof(after_this_elem)=='object' && after_this_elem){
			$(after_this_elem).after(twittItemElem);
		}
		else{
			$(_self.twittsContainer).prepend(twittItemElem);
		}
		
		if(typeof(twittDetails.profile_image_url)=='string' && twittDetails.profile_image_url){
			_self.onLoadedImage(user_img, function (){
				twittItemElem.style.display = 'block';
			});
		}
		else{
			$(twittItemElem).show('blind');
		}
	
		var opt_container = document.createElement('div');
		opt_container.className = 'WVliveTwitt_item_opt_container';
		footer.appendChild(opt_container);
		
		if(_self.parameters.enableRetweet){
			var retweet_message = 'RT @'+ twittDetails.from_user+': '+twittDetails.text;
			
			var retweet_btn = document.createElement('a');
			retweet_btn.onclick = function(){_self.updateStatus(retweet_message)}
			retweet_btn.className = 'WVliveTwitt_retweet_btn';
			
			var retweet_img = document.createElement('img');
			retweet_img.src = widget_base_url+'/images/icon/16/retweet.png';
			retweet_img.alt = '';
			retweet_img.align = 'absmiddle';
			retweet_img.style.marginRight = '5px';
			retweet_btn.appendChild(retweet_img);
			
			var retweet_label = document.createElement('span');
			retweet_label.innerHTML = 'retweet';
			retweet_btn.appendChild(retweet_label);
			
			opt_container.appendChild(retweet_btn);
		}
		
		if(_self.parameters.adminMode){
			var ban_btn = document.createElement('a');
			ban_btn.onclick = function(){_self.banUser(twittDetails.from_user_id)}
			ban_btn.title = 'ban user';
			ban_btn.className = 'WVliveTwitt_ban_btn';
			
			var ban_img = document.createElement('img');
			ban_img.src = widget_base_url+'/images/icon/16/agt_action_fail.png';
			ban_img.alt = '';
			ban_img.align = 'absmiddle';
			ban_img.style.marginRight = '5px';
			ban_btn.appendChild(ban_img);
			
			var ban_label = document.createElement('span');
			ban_label.innerHTML = 'ban';
			ban_btn.appendChild(ban_label);
			
			opt_container.appendChild(ban_btn);
		}
		
		return twittItemElem;
	}
	
	this.banUser = function(user_id){
		if(confirm("Ban user and hide all his posts?")){
			var params = {mode:'tweets', act:'ban_user', user_id:user_id};
			_self.makeServiceCall(params, _self.banUserCallback);
		}
	}
	
	this.banUserCallback = function(data){
		if(typeof(data.successfull)=='boolean' && data.successfull){
			_self.bannedUsers[data.user_id] = true;
			_self.refreshTwitts();
		}
	}
	
	this.makeServiceCall = function(params, callback){
		var request = widget_base_url+'/index.php?output=jquery&callback=?';
		
		jQuery.ajax({
			type: "GET",
			url: request,
			data: params,
			success: callback,
			dataType: 'json'
		});
	}
	
	this.onLoadedImage = function(imageElem, callback){
		if(imageElem.complete){
			if(typeof(callback)=='function'){
				callback();
			}
			else if(typeof(callback)=='string'){
				eval(callback());
			}
		}
		else{
			setTimeout(function(){_self.onLoadedImage(imageElem, callback)}, 100);
		}
	}
	
	this.updateStatus = function(retweet_message, link, linkOptional){
		if(typeof(fan_share_post_on_twitter)=='function'){
			fan_share_post_on_twitter(retweet_message, link, '', linkOptional);
		}
		else {
			var retweet_url = 'http://twitter.com/home?status='+encodeURIComponent(retweet_message);
			window.open(retweet_url,'UpdateTwitterStatus','width=800,height=600,left=100,top=70,status=no,toolbar=no');
		}
	}
	
	this.refreshTwittsCallback = function(data){
		if(typeof(data)=='object'){
			if (typeof(data.results)=='object') {
				
				var last_twitt = false;
				
				for(var i in data.results){
					var twittDetails = data.results[i];
					
					if(typeof(_self.displayedTwitts[twittDetails.id])=='boolean'){
						continue;
					}
					
					_self.displayedTwitts[twittDetails.id] = true;
					var last_twitt = _self.displayTwitt(twittDetails, last_twitt);
				}

				while(_self.twittsContainer.children.length>_self.maxTwitts){
					_self.twittsContainer.removeChild(_self.twittsContainer.lastChild);
				}
			}
			
//			var debug = data;
//			debug.results = debug.results.length;
//			vsa_display_debug_msg(vsa_debug_object2string(debug));
			
			if(parameters.enablePagination){
				_self.has_next_page = typeof(data.next_page)=='string';
				_self.has_previous_page = typeof(data.previous_page)=='string';
				_self.display_pages(pagination_container);
			}

			_self.max_id = data.max_id;
			_self.refreshPeriod = _self.originalRefreshPeriod; // if a problem was encountered before reset the refresh time
		}
		else{ // if communication failed
			_self.refreshPeriod = _self.refreshPeriod*2; // make a longer pause between refreshes
		}
	}
	
	
	var link_regexps = Array();
	var link_prefixes = Array();
	
	link_regexps[0] = /(http[s]{0,1}:\/\/(([a-z0-9\-]+\.)+[a-z]{2,4})(\/[^\s\n\t\r]*)?)([\s\n\t\r]|$)/i;
	link_regexps[1] = /(www\.(([a-z0-9\-]+\.)+[a-z]{2,4})(\/[^\s\n\t\r]*)?)([\s\n\t\r]|$)/i;
	
	link_prefixes[0] = '';
	link_prefixes[1] = 'http://';
	
	
	/**
	 * builds html links from urls in the text
	 */
	this.build_links = function(text_with_urls){
		var found_links = Array();
		var current_link_index = 0;
		
		for(var i in link_regexps){
			var link_rexexp = link_regexps[i];
			while(link_url = text_with_urls.match(link_rexexp)){
				text_with_urls = text_with_urls.replace(link_rexexp, '<~|'+current_link_index+'|~>');
				
				var found_link = link_prefixes[i] + link_url[1];
				found_links[current_link_index] = '<a href="'+found_link+'" rel="nofollow" target="_blank">'+found_link+'</a>' + link_url[5];
				current_link_index++;
			}
		}
		
		for(var current_link_index in found_links){
			text_with_urls = text_with_urls.replace('<~|'+current_link_index+'|~>', found_links[current_link_index]);
		}		
		
		return text_with_urls;
	}
	
	this.refreshTwitts();
}