/*
 * EVENTS :
 * connected 	- Called when a connection is successfully made
 * disconnected - The chat connection got disconnected
 * roster_changed - The roster has changed (presence/iq change)
 * chat_started - When a chat session is started (not used)
 * chat_ended 	- When a chat session has ended
 * message_send - When a new message needs to be sent
 * status_changed - When MY mood or language has changed
 */

var connection = DMC = null;
var chat_msg_counter = 0;
var snRequestSent = false;
var ready_count = 0;

ChatConfig.LOAD_USERS_URL	= '/index.php/index/ajax/m:anonUsers/';
ChatConfig.UPDATE_STATUS_URL	= '/index.php/achat/ajax/m:updateStatus/';
ChatConfig.CHAT_OVER_COOKIE_NAME = 'chatover';

var ChatHandlers = {
	onConnected : function(){
		connection.addHandler(Handlers.onGCMessageReceived,null,"message","groupchat");
		connection.addHandler(Handlers.onMessageReceived  ,null,"message","chat");
		connection.addHandler(Handlers.onGCMessageReceived,null,"message","deny-join-request");
		connection.addHandler(ChatDetect.onTypingMessageReceived,null, "message","typing-start");
		connection.addHandler(ChatDetect.onTypingMessageReceived,null, "message","typing-end");
		Me.initialize();
		Handlers.newChat(ChatController.partner);
	},

	newChat : function(chat_partner) {
		ChatController.room = connection.rid+getTime().replace(':','') +'@'+ ChatConfig.CONFERENCE_DOMAIN;

		var lang_code	= Me.language;
		var lang_id		= ChatLanguages.getLanguageId(lang_code);
		var lang_name	= ChatLanguages.getLanguageName(lang_code);
		var name		= Me.name;

		connection.muc.joinRoom(connection.jid, "anonymous", ChatController.room, 0, Me.name, Me.image, Me.mood, lang_code, lang_id, lang_name);
		connection.muc.invite(connection.jid, chat_partner, ChatController.room, name);

		if(!DMC)
			DMC = new DOMChat($("#demoChat"),$('#chatClone')); //initialize objects for chat

		ChatHandlers.onChatStart(chat_partner);
		$('#demoChat').attr('class', '');
		return true;
	},

	onRosterChanged : function(event, roster){
		for(var jid in roster.contacts)
		{
			var cur	 = connection.roster.contacts[jid];
			var status = (cur.online())?'':'offline';

			/*
			 * THIS IS WHERE CLICK HANDLERS FOR USERS ARE (UN)SET
			 */
			if(status == 'offline'){
				DMC.setTitleBar(jid, RosterManager.getName(jid)+" "+ChatMessages.offline);//DMC.removeChat(jid);
				DMC.disable(jid);
				ChatTimer.stop(Strophe.getNodeFromJid(jid));
				var obj = DMC.getChat(jid);
				$(obj).find('.myInfo').addClass('hideLinks');
			}
			else
			{
				//When the partner sends a presence, that is when we start the chat
				if(!DMC.getChat(jid)) continue;

				var info = DMC.getInfo(jid);
				if(!info.id) DMC.addPartnerInfo(jid,cur.id,cur.name,cur.image);

				ChatTimer.stop(jid);
				DMC.enable(jid);

				DMC.setInfo(jid,cur.language(),cur.mood());
				DMC.setMode(jid,(cur.language() == DMC.getMyInfo(jid).lang),ChatConfig.SEE_TRANSLATIONS_ONLY);

				var obj = DMC.getChat(jid);
				$(obj).find('.myInfo').removeClass('hideLinks');
				ChatView.displayLoader(false,obj);

				if(ready_count == 0){
					DMC.addSystemMessage(jid, ChatMessages.ready);
					ChatController.updateStatus(jid,AnonChatStatus.ACCEPT);
					ready_count++;
				}
			}
		}
	},

	onGCMessageReceived : function(msg){
		if($(msg).find('status').length > 0)return true; //This message was sent from Ejabberd, informing us that this room is not anonymous

		var from = Strophe.getNodeFromJid($(msg).attr('from'));
		var v = DMC.getChat(from);
		try{if(v) ChatView.displayLoader(false,v);}catch(e){}//hide the loader

		if($(msg).attr('type') == 'deny-join-request'){
			DMC.showDenyMessage(from,RosterManager.getName(from)+ChatMessages.partner_declined);
			ChatTimer.stop(from);
			ChatController.updateStatus(from,AnonChatStatus.DENY);
		}
		else if($(msg).attr('type') == 'approve-join-request'){
			sendPresence(from); //Will send default PRESENCE stanza to user
		}
	},

	onChatStart : function(jid, sid){
		if(!DMC.__hasObj(jid)){
			DMC.newChat(jid,Strophe.getNodeFromJid(jid));

			var node = Strophe.getNodeFromJid(jid);
			var info = '';

			for(var i in SNFriends){
				if(SNFriends[i].jid == node){
					info = SNFriends[i];
					break;
				}
			}

			if(!info) info = {jid:node, id : undefined, name:'Member', image:'', lang:''};

			RosterManager.set(jid, info.id, info.name, info.image, ChatConfig.DEFAULT_RESOURCE, info.lang, ChatConfig.DEFAULT_MOOD);
			ChatTimer.start(node);
			DMC.addPartnerInfo(jid,info.id,info.name,info.image);
			DMC.setInfo(jid,info.lang,ChatConfig.DEFAULT_MOOD,info.image);
			DMC.setMyInfo(jid, Me.name, Me.language, Me.mood, Me.id);

			/*
			 * If a message has been sent for the first time, this user will not have its session id
			 * If the session id was not set, set it here
			 * else, use the session id that was passed
			 */
			DMC.setSessionId(jid,(!sid)?connection.rid:sid);
		}

		DMC.showChat(jid,ChatConfig.SEE_TRANSLATIONS_ONLY);
		DMC.getChat(jid).addClass('initial');
		return true;
	},

	onChatEnd : function(event, jid) {
		//if(window.console) console.log('onChatEnd ',jid)
		connection.muc.leaveRoom(Me.jid,ChatController.room);
		connection.roster.disconnect(Me.jid,jid); 

		ChatTimer.stop(jid);
		DMC.removeChat(jid);
		ChatController.partner = ChatController.room = null;
		$('#demoChat').attr('class', 'showInfo');
		ChatController.updateStatus(jid,AnonChatStatus.CLOSED);
		ready_count = 0;
		return true;
	},

	messageCounter : function(event, jid, obj){
		if(chat_msg_counter < ChatConfig.ANONYMOUS_MESSAGE_LIMIT){
			chat_msg_counter++;
			var title = ChatMessages.messages_left.replace('!',(ChatConfig.ANONYMOUS_MESSAGE_LIMIT - chat_msg_counter));
			DMC.setTitleBar(jid, RosterManager.getName(jid)+ ' '+title)
		}else{
			ChatView.chatOver();
			setTimeout(function(){ //Wait for a sec so the message gets sent.
				//DMC.removeChat(jid);
				connection.muc.leaveRoom(connection.jid,ChatController.room);
				disconnect();
				//DROP a cookie
				var exdate=new Date();
				exdate.setDate(exdate.getDate()+1);
				setCookie(ChatConfig.CHAT_OVER_COOKIE_NAME,'true',exdate.toGMTString());
			}, 1000);
		}
	},

	onDisconnected : function() {ready_count = 0;},
	
	bind : function(){
		Handlers.onConnected = this.onConnected
		Handlers.onDisconnected = this.onDisconnected
		Handlers.newChat = this.newChat
		Handlers.onChatStart = this.onChatStart
		Handlers.onChatEnd = this.onChatEnd
		Handlers.onRosterChanged = this.onRosterChanged
		Handlers.onGCMessageReceived = this.onGCMessageReceived
		Handlers.messageCounter = this.messageCounter		
	}
}

var AnonChatStatus = {ACCEPT : 1 ,DENY : 2 , CLOSED : 3};

DOMChat.prototype.addNotAvailableMessage = function(jid, msg) {
	if(!this.__hasObj(jid))return false;
	jid = this.__getName(jid);
	var chatbox = this.objects[jid].find(".chatMessages");

	chatbox.append( "<li class='busy'>" +
					"<p>"+msg+"<span></span></p>" +
					"<span class='time'>"+getTime()+"</span>"+
					"</li>");
	chatbox.scrollTo('100%',150);
	return true;
}

DOMChat.prototype.hideNotAvailableMessages = function(jid) {
	if(!this.__hasObj(jid))return false;
	jid = this.__getName(jid);
	this.objects[jid].find(".chatMessages .busy").hide();
	return true;
}

DOMChat.prototype.showDenyMessage = function(jid, msg) {
	if(!this.__hasObj(jid))return false;
	jid = this.__getName(jid);
	var chatbox = this.objects[jid].find(".chatMessages");

	chatbox.prepend( "<li class='deny'>" +
					"<p>"+msg+"</p>" +
					"<span class='time'>"+getTime()+"</span>"+
					"</li>");
	chatbox.scrollTo('0%',150);
	return true;
}

var ChatTimer = {
	timers : new Object(),
	start : function(jid){
		this.timers[jid] = setTimeout(function(){
			DMC.addNotAvailableMessage(jid,ChatMessages.no_response);
		},ChatConfig.PRESENCE_RESPONSE_TIMEOUT); //Wait for a minute.
	},

	stop : function(jid){
		jid = Strophe.getNodeFromJid(jid) || jid;
		clearTimeout(this.timers[jid]);
	}
}

var ChatView = {
	displayLoader : function( bool, obj ){
		if(obj == undefined) obj = $('.connect');

		if(bool)
			obj.find('.connect').show();
		else
			obj.find('.connect').hide();
	},

	chatOver : function(){
		var p = $('div.chat[id!=chatClone]');
		if(p.length < 1) p =$('div#chatClone');
		p.show().addClass('limitFinished');
		p.find('textarea').disabled = true;
		$('.randomList').hide();
	},

	addUsers : function(data){
		$('.randomPeople').html(data);
		$('.randomPeople li').hover(function(){$(this).find('.speech-bubble').addClass('active')}, function(){$(this).find('.speech-bubble').removeClass('active')});
	}
}

var ChatController = {
	partner : null,
	room	: null,

	reloadUsers : function(){
		$.ajax({
			url: ChatConfig.LOAD_USERS_URL,
			data: {},
			success: ChatView.addUsers,
			dataType: 'text'
		});
	},

	updateStatus : function(jid,status){
		if(snRequestSent == true) return; // If a request has been sent once, dont send it again

		var sid = DMC.getSessionId(jid);
		jid = ((jid.indexOf('@') > 0)?Strophe.getNodeFromJid(jid):jid);
		var url = ChatConfig.UPDATE_STATUS_URL+'s:'+sid+'/u:'+jid+'/a:'+status;

		if(status != AnonChatStatus.ACCEPT) $('.randomPeople a[href=#'+jid+']').parent().remove();
		else DMC.hideNotAvailableMessages(jid);
		
		if($('.randomPeople a').length < 1) ChatController.reloadUsers();
		
		$.post(url, {}, function(evt, json){
			if(!json || !json.type || json.type.toLowerCase() != 'success') return;
			snRequestSent = true;
		},'json');
	},

	init : function(){

		if(getCookie(ChatConfig.CHAT_OVER_COOKIE_NAME).length > 0){
			ChatView.chatOver();
			return true;
		}

		ChatHandlers.bind();
		bindDefaultHandlers();
		initSound(ChatConfig.SOUND_FILE_NAME);
		
		$(document).bind('message_send',Handlers.messageCounter);

		$('.randomPeople a').live('click',function(){
			if(ChatController.partner) return true;
			
			var node = $(this).attr('href').substr(1);
			if(!node) return true; //if the URL has no jid for any reason, dont open the popup.
			
			//ChatView.displayLoader(true); //show the loader

			ChatController.partner = node + '@'+ ChatConfig.DOMAIN +'/'+ChatConfig.DEFAULT_RESOURCE;
			Me.name = $('#name').val() || '';
			if(Me.name.length < 1) Me.name = ChatMessages.anonymous_name;
			
			$('.randomPeople .speech-bubble').removeClass('active'); //Hide the speech bubble
			$('.randomePeople > li').removeClass('selected');
			$(this).parents('li').addClass('selected');

			if(!isConnected()){
				connect();
				mt_load();
			}
			else
				Handlers.newChat(ChatController.partner);
		});

		$('.randomPeople li').hover(function(){$(this).find('.speech-bubble').addClass('active')}, function(){$(this).find('.speech-bubble').removeClass('active')});
		$('.chatInfoMessage a').live('click',function(){$('#testInfo').addClass('active');return false;})
		$('#testInfo input[name=btnClose]').click(function(){$('#testInfo').removeClass('active');})
	},
	
	dest : function(){
		/*if(!window.connection) return false;
		var pres_req = $pres({type: "unavailable", to:ChatController.partner, from:connection.jid});
		connection.send(pres_req.tree());
		//if(window.console) console.log('ChatController.dest',pres_req.toString())
		connection.muc.leaveRoom(connection.jid,ChatController.room);
		connection.disconnect();*/
		disconnect();
	}
}

function connect()
{
	connection = new Strophe.Connection(ChatConfig.BOSH_SERVICE);

    var user = ChatConfig.PUBLIC_DOMAIN+'/'+ChatConfig.DEFAULT_RESOURCE;//$.trim($('#username').val())+'/'+ChatConfig.DEFAULT_RESOURCE;
    var pass = 'xx';

    if(user == '' || pass == '') return;

    try{
		//Strophe.TIMEOUT = 43;
		var wait = 35;
		connection.connect(user,pass,Handlers.onConnect,wait); 
    }catch(e){if(window.console) console.log(e)}

}

$(document).ready(ChatController.init);
$(window).unload( ChatController.dest);
