/**
 * instant messenger
 * 
 * takes care of all client side logic.
 * 
 * @author michael
 */

var Messenger = new Class({
	
	initialize: function(requestUrl, requestPrefix, initStatus, chatArray, initChatBoxes, chatOpen, doTrace){
		var self = this;
		//this.originalDocumentTitle = document.title;
		//this.initSound();
		this.requestUrl = requestUrl;
		this.requestPrefix = requestPrefix;
		this.chatArray = chatArray;
		this.doTrace = doTrace;
		if(initStatus>0){
			this.setStatus(initStatus);
		}
		if(initChatBoxes.length>0){
			initChatBoxes.each(function(item, index){
				self.initChatbox(item);
			});
		}
		if(chatOpen!=''){
			this.switchTab(chatOpen, true);
		}
		//catch all anchor clicks in IE to kill the current request
		var jsprefix = "javascript";
		var allAnchors = $('site_content').getElements('a');
		allAnchors.addEvent('click', function(event){
			if(typeof this.href != "undefined" && this.href.substring(0,1) != "#" && this.href.substring(0,jsprefix.length)!=jsprefix){
				self.killRequest();
			}
		});
	},
	
	request: '',					//currently running request
	requestUrl: '',					//communication script
	requestPrefix: '',				//request get vars
	requestCounter: 0,				//number of requests sent
	keepAliveFlag: false,			//send new request after current one completes
	chatSlots: 6,					//max concurrent chat-sessions
	chatArray: [],					//list of running chats
	chatBuffer: new Hash(),			//used to buffer messages while chatbox is not yet loaded
	chatOpen: '',					//currently open chat box
	typingArray: [],				//chatbox indicates typing
//	originalDocumentTitle: '',		//original page title (we change it around to get attention)
//	titleBlinkTimeout : false,		//title blink interval
	sendTimeout: false,				//used to delay initial connect (so we avoid always loading indicator)
	soundMethod: '',				//set automatically to 'html' or 'swf' after sound init
	soundSwiff: '',					//swiff (flash) object used for sound
	doTrace: false,					//debug
	
	unload: function(){
		$('im_bar_online').setStyle("display", "none");
		$('im_bar_friends_box').setStyle("display", "none");
		$('im_bar_chat_box').setStyle("display", "none");
		$('im_bar_offline_note').setStyle("display", "none");
		$('im_bar_expired').setStyle("display", "block");
	},
	
	killRequest: function(){
		if(this.request!='') this.request.cancel();
	},
	
	send: function(suffix){
		if(this.requestUrl=='' || this.requestPrefix=='') return false;
		if(typeof suffix=='undefined') suffix = '';
		this.killRequest();
		this.requestCounter++;
		if(Browser.Engine.trident){
			var d = new Date();
			suffix += '&t='+this.requestCounter+'-'+d.getTime();
		}
		var self = this;
		this.request = new Request({
			url: this.requestUrl,
			method: 'get',
			evalScripts: true,
			onSuccess: function(responseText, responseXML){
				if(self.keepAliveFlag){
					self.keepAliveFlag = false;
					self.send();
				}
			}
		}).send(this.requestPrefix+suffix);
	},
	
	connect: function(nustatus){
		if(this.requestUrl=='') return false;
		if(typeof nustatus=='undefined') nustatus = 2;
		$('im_bar_friends_box').setStyle("display", "block");
		$('im_bar_chat_box').setStyle("display", "block");
		this.updateStatusIndicator(nustatus);
		$('im_bar_offline_note').setStyle("display", "none");
		//delay to avoid always loading indicator
		var self = this;
		var delayedConnect = function(){
			self.send('&setsta='+nustatus);
		};
		this.sendTimeout = setTimeout(delayedConnect, 1000);
	},

	disconnect: function(nustatus){
		if(typeof nustatus=='undefined') nustatus = 0;
		this.send('&setsta='+nustatus);
		$('im_bar_chat_box').setStyle("display", "none");
		$('im_bar_chat_box').set('html', '');
		this.chatOpen = '';
		this.chatArray = [];
		this.typingArray = [];
		$('im_bar_friends_box').setStyle("display", "none");
		this.updateStatusIndicator(nustatus);
		$('im_bar_offline_note').setStyle("display", "inline");
	},

	keepAlive: function(){
		this.keepAliveFlag = true;
	},
	
	//called by gui
	setStatus: function(nustatus){
		if(this.sendTimeout!=false){
			clearTimeout(this.sendTimeout);
			this.sendTimeout=false;
		}
		if(nustatus==0){
			this.disconnect();
		}else{
			this.connect(nustatus);
		}
	},

	updateStatusIndicator: function(nustatus){
		//loop over states
		for(var i=0; i<=2; i++){
			if(i==nustatus){
				$('im_bar_stat_'+i).setStyle("display", "block");
				$('im_bar_stat_menu_'+i).addClass("btn_list_active");
			}else{
				$('im_bar_stat_'+i).setStyle("display", "none");
				$('im_bar_stat_menu_'+i).removeClass("btn_list_active");
			}
		}
	},

	chatboxRunning: function(user_id){
		//check im_slots for the provided hash, return true if found
		return this.chatArray.contains(user_id);
	},

	slotOpen: function(){
		return (this.chatArray.length<this.chatSlots);
	},
	
	//output reply
	printReply: function(user_id, reply){
		reply = reply+'';
		if(reply=='') return false;
		if(this.chatboxRunning(user_id)){
			$('chat_box_conv_'+user_id).set('html', $('chat_box_conv_'+user_id).get('html') + reply);
			if(this.chatOpen!=user_id) $('chat_tab_'+user_id).addClass("button_im_attention");
			var axListScrollToFx = new Fx.Scroll('chat_box_conv_'+user_id).toBottom();
			/*
			if(!this.titleBlinkTimeout){
				var self = this;
				var resetTitle = function(){
					document.title = self.originalDocumentTitle;
					self.titleBlinkTimeout = false;
				};
				document.title = 'New Message!';
				this.titleBlinkTimeout = setTimeout(resetTitle, 500);
			}
			*/
		}else if(this.chatBuffer.has(user_id)){
			//still loading chatbox.. append reply
			this.chatBuffer.set(user_id, this.chatBuffer.get(user_id)+reply);
		}else{
			this.loadChatbox(user_id, reply);
		}
	},
	
	showTyping: function(user_id){
		if(this.chatboxRunning(user_id)) $('chat_typing_'+user_id).setStyle("display", "block");
	},
	
	hideTyping: function(user_id){
		if(this.chatboxRunning(user_id)) $('chat_typing_'+user_id).setStyle("display", "none");
	},
	
	loadChatbox: function(user_id, reply){
		if(typeof reply=='undefined') reply = '';
		if(!this.slotOpen()) return false;
		this.chatBuffer.set(user_id, reply);
		var self = this;
		var load_chatbox = new Request({
			url: 'index.php',
			evalScripts: true,
			onSuccess: function(responseText, responseXML){
				responseText = responseText+'';
				if(responseText!='failed'){
					var newBox = new Element('div', {'html':responseText , 'class':'im_bar_slot', 'id':'chat_box_slot_'+user_id});
					$('im_bar_chat_box').grab(newBox);
					self.chatArray.include(user_id);
					if(self.chatOpen==''){
						//switch to new box
						self.switchTab(user_id);
					}else{
						//minimize new chatbox
						$('chat_box_'+user_id).setStyle("display", "none");
						$('chat_tab_'+user_id).removeClass("button_im_active");
					}
					self.initChatbox(user_id);
					if(self.chatBuffer.has(user_id)){
						var replyBuffer = self.chatBuffer.get(user_id);
						if(replyBuffer!="") self.printReply(user_id, replyBuffer);
						self.chatBuffer.erase(user_id);
					}
				}
			}
		}).send('sec=ajax&sub1=im&sub2=chatbox&user='+user_id);
	},
	
	initChatbox: function(user_id){
		var self = this;
		$('chat_box_form_'+user_id).addEvent('submit', function(e) {
			new Event(e).stop();
			if($('chat_box_reply_'+user_id).value!=''){
				self.sendReply(''+user_id, $('chat_box_reply_'+user_id).value);
				$('chat_box_reply_'+user_id).value='';
				self.typingArray.erase(user_id);
			}
		});
	},
	
	switchTab: function(user_id, silent){
		if(typeof silent=='undefined') silent = false;
		if(!this.chatboxRunning(user_id)) return false;
		if(this.chatOpen==user_id){
			//minimize chatbox
			$('chat_box_'+user_id).setStyle("display", "none");
			$('chat_tab_'+user_id).removeClass("button_im_active");
			this.chatOpen = '';
		}else{
			//make sure chat_box is open
			$('im_bar_chat_box').setStyle("display", "block");
			var self = this;
			//run through the boxes and tabs
			this.chatArray.each(function(item, index){
				if(item==user_id){
					$('chat_box_'+item).setStyle("display", "block");
					$('chat_tab_'+item).addClass("button_im_active");
					$('chat_tab_'+item).removeClass("button_im_attention");
					self.chatOpen = item;
				}else{
					$('chat_box_'+item).setStyle("display", "none");
					$('chat_tab_'+item).removeClass("button_im_active");
				}
			});
		}
		if(!silent){
			this.send("&open="+((this.chatOpen=='')? 'none' : this.chatOpen));
		}
	},
	
	//called by gui
	startChat: function(user_id){
		if(!this.chatboxRunning(user_id)){
			this.loadChatbox(user_id, "");
		}else{
			this.switchTab(user_id);
		}
	},

	disposeChatbox: function(user_id){
		if(this.chatboxRunning(user_id)){
			$('chat_box_slot_'+user_id).dispose();
			this.chatArray.erase(user_id);
			this.typingArray.erase(user_id);
			if(this.chatOpen==user_id){
				this.chatOpen='';
				this.send("&open=none&close="+user_id);
			}
		}
	},

	//called by chatbox-forms
	sendReply: function(user_id, reply){
		this.send('&user='+user_id+'&reply='+encodeURIComponent(reply));
	},

	sendTyping: function(user_id){
		if(!this.typingArray.contains(user_id)){
			this.typingArray.include(user_id);
			this.send('&user='+user_id+'&typing=1');
		}
	},
	
	loadFriends: function(){
		var tabs = '';
		this.chatArray.each(function(item, index){
			tabs += '-'+item;
		});
		if(tabs!='') tabs = '&tabs='+tabs;
		var load_friends = new Request({
			url: 'index.php',
			method: 'get',
			evalScripts: true,
			onSuccess: function(responseText, responseXML){
				responseText = responseText+'';
				if(responseText!='failed'){
					$('im_bar_friends_box').set('html', responseText);
					$('im_bar_friends_box').setStyle("display", "block");
				}
			}
		}).send('sec=ajax&sub1=im&sub2=friends'+tabs);
	},

	updateTabStates: function(user_ids, nustatus){
		var self = this;
		for(var i=0; i<=2; i++){
			user_ids.each(function(item, index){
				if(self.chatboxRunning(item)){
					if(i==nustatus){
						$('chat_tab_stat_'+item+'_'+i).setStyle("display", "inline");
					}else{
						$('chat_tab_stat_'+item+'_'+i).setStyle("display", "none");
					}
				}
			});
		}
	},
	
	initSound: function(soundname){
		if($('im_sound_cont')){
			var audioTagSupport = !!(document.createElement('audio').canPlayType);
			if(audioTagSupport){
				if(!$('im_sound_html_'+soundname)){
					var new_tag =
						'<audio id="im_sound_html_'+soundname+'">'+
							'<source src="audio/'+soundname+'.ogg" type="audio/ogg" />'+
							'<source src="audio/'+soundname+'.mp3" type="audio/mpeg" />'+
						'</audio>';
					$('im_sound_cont').set('html', $('im_sound_cont').get('html')+new_tag);
				}
				this.soundMethod = 'html';
			}else if(this.soundSwiff==''){
				this.soundSwiff = new Swiff('swf/imsound.swf', {
					id: 'im_sound_swf',
					width: 1,
					height: 1,
					container: $('im_sound_cont'),
					params: {
						wmode: 'transparent'
				    }
				});
				this.soundMethod = 'swf';
			}
		}
	},

	playSound: function(soundname){
		if(this.soundMethod=='' || (this.soundMethod=='html' && !$('im_sound_html_'+soundname))){
			this.initSound(soundname);
		}
		if(this.soundMethod=='html'){
			if($('im_sound_html_'+soundname)){
				$('im_sound_html_'+soundname).play();
			}
		}else if(this.soundMethod=='swf'){
			var mov = $('im_sound_swf');
			mov.playSound(soundname);
		}
	},

	onlineButtonCLick: function(){
		$('im_online_menu').toggle();
		$('im_bar_online_btn').toggleClass('button_im_active', true);
	},
	
	trace: function(str){
		if(this.doTrace && $('im_debug')){
			$('im_debug').setStyle("display", "block");
			str.replace('<', '&lt;');
			str.replace('>', '&gt;');
			$('im_debug_text').set('html', $('im_debug_text').get('html')+'<br>'+str);
			var axDebugScrollToFx = new Fx.Scroll('im_debug').toBottom();
		}
	}
	
});

