//jQuery noConflict var should be JQ
var chat_images = 'http://www.bghora.com/images/default/chat/';
var chat_player = 'http://www.bghora.com/flash/niftyplayer.swf';
var chat_sound = 'http://www.bghora.com/files/chat_beep.mp3';
var lib_path = 'http://www.bghora.com/js/';
//var BOSH_SERVICE = 'http://puiako.com/http-bind/';
var BOSH_SERVICE = 'http://www.bghora.com/http-bind/';
var pubsub_service = 'pubsub.puiako.com';
var chat_room = 'bghora@conference.puiako.com';
var chat_domain = 'puiako.com';
var chat_wait = 60;
var connection = null;
var chat_resource = '/bghora';
var chat_node = 'bghora';
var uinfo;
var ulist = new Object();
var chat_on_focus = '';
var friends_in_chat_label = 'Приятели в чата';
var wait_for_subscription = 0
var active_chats = new Array();
var visible_chats = new Array();
var searching = 0;
var window_width = 0;
var window_height = 0;

JQ(window).unload(function(){
	disconnectFromChatServer();
});

JQ(document).ready(function()
{
	//disable esc key
	JQ(document).bind('keypress keydown keyup', function(e)
		{
			var code = (e.keyCode ? e.keyCode : e.which);
			if(code == 27)
			{
				e.preventDefault();
				return false;
			}
	});
	
	//load sound player
	loadSoundPlayer();
	
	Strophe.addNamespace('PUBSUB',"http://jabber.org/protocol/pubsub");
  Strophe.addNamespace('PUBSUB_SUBSCRIBE_OPTIONS',
		Strophe.NS.PUBSUB+"#subscribe_options");
  Strophe.addNamespace('PUBSUB_ERRORS',Strophe.NS.PUBSUB+"#errors");
  Strophe.addNamespace('PUBSUB_EVENT',Strophe.NS.PUBSUB+"#event");
  Strophe.addNamespace('PUBSUB_OWNER',Strophe.NS.PUBSUB+"#owner");
  Strophe.addNamespace('PUBSUB_AUTO_CREATE',
		Strophe.NS.PUBSUB+"#auto-create");
  Strophe.addNamespace('PUBSUB_PUBLISH_OPTIONS',
		Strophe.NS.PUBSUB+"#publish-options");
  Strophe.addNamespace('PUBSUB_NODE_CONFIG',
		Strophe.NS.PUBSUB+"#node_config");
  Strophe.addNamespace('PUBSUB_CREATE_AND_CONFIGURE',
		Strophe.NS.PUBSUB+"#create-and-configure");
  Strophe.addNamespace('PUBSUB_SUBSCRIBE_AUTHORIZATION',
		Strophe.NS.PUBSUB+"#subscribe_authorization");
  Strophe.addNamespace('PUBSUB_GET_PENDING',
		Strophe.NS.PUBSUB+"#get-pending");
  Strophe.addNamespace('PUBSUB_MANAGE_SUBSCRIPTIONS',
		Strophe.NS.PUBSUB+"#manage-subscriptions");
  Strophe.addNamespace('PUBSUB_META_DATA',
		Strophe.NS.PUBSUB+"#meta-data");
	Strophe.addNamespace('DISCO', "http://jabber.org/protocol/disco");
	Strophe.addNamespace('DISCO_ITEMS',
		Strophe.NS.DISCO+"#items");
	
	connectToChatServer();
	
	JQ('#chat_list_button').click( function() {
		panExpandChat();
	});
	
});

function panExpandChat()
{
	//expanded open
	if(JQ('#chat_expanded_holder').length == 0)
	{
		//main holder
		var mhl = document.createElement('div');
		mhl.id = 'chat_expanded_holder';
		
		//label
		var dhl = document.createElement('div');
		dhl.id = 'chat_header_label';
		dhl.className = 'chat_header_label';
		dhl.innerHTML = 'Чат'
		dhl.onclick = function(){ JQ('#chat_list_button').click(); };
		
		//settings
		var shl = document.createElement('div');
		shl.id = 'chat_list_options';
		shl.className = 'chat_list_options';
		
		var chl_1 = document.createElement('div');
		chl_1.id = 'chl_1';
		chl_1.className = 'chat_list_options_menu';
		chl_1_html = '<a href="javascript:void(0);" title="Списъци с приятели">';
		chl_1_html += '<img src="' + chat_images + '/chat_list_icon.png" alt="Списъци с приятели"/> Списъци с приятели';
		chl_1_html += '</a>';
		JQ(chl_1).append(chl_1_html);
		
		var chl_2 = document.createElement('div');
		chl_2.id = 'chl_2';
		chl_2.className = 'chat_list_options_menu';
		chl_2_html = '<a href="javascript:void(0);" title="Настройки">';
		chl_2_html += '<img src="' + chat_images + '/chat_settings_icon.png" alt="Настройки"/> Настройки';
		chl_2_html += '</a>';
		JQ(chl_2).append(chl_2_html);
		
		JQ(shl).append(chl_1);
		JQ(shl).append(chl_2);
		JQ(shl).append('<div class="clrbth"></div>');
		
		//chat list
		var lhl = document.createElement('div');
		lhl.id = 'chat_list_users';
		lhl.className = 'chat_list_results';
		lhl.innerHTML = '<div id="srch_no_result" class="chr">Няма онлайн потребители</div>';
		
		//search field
		var srchl = document.createElement('div');
		srchl.id = 'chat_search_field';
		srchl.className = 'chat_search_field';
		var srchfld = '<div id="field_wrapper" class="field_wrapper"><form name="search_un_form" method="post" action="" onsubmit="return false;">';
		srchfld += '<input id="search_un" type="text" name="search_un" class="search_un" value="' + friends_in_chat_label + '" onfocus="searchFieldFocus(\'focus\', this, \'' + friends_in_chat_label + '\');" onblur="searchFieldFocus(\'blur\', this, \'' + friends_in_chat_label + '\');" onkeyup="searchFieldFocus(\'search\', this, \'' + friends_in_chat_label + '\');"/>';
		srchfld += '</form></div>';
		JQ(srchl).append(srchfld);
		JQ(srchl).append('<div class="clrbth"></div>');
		
		JQ(mhl).append(dhl);
		//JQ(mhl).append(shl);
		JQ(mhl).append(lhl);
		JQ(mhl).append(srchl);
		
		JQ('#chat_holder').prepend(mhl);
		
		JQ('#chat_list_button').removeClass('chat_bottom_hide').addClass('chat_bottom_hide_hover');
		
		setChatFoldConditions();
		
		generateOnlineList();
	}
	else
	{
		foldChat()
	}
}

function setChatFoldConditions()
{
	document.body.onclick = function(e)
	{
		var target = e ? e.target : event.srcElement;
		if(target != document.getElementById('chat_expanded_holder')
			&& target != document.getElementById('chat_list_button')
			&& target != document.getElementById('chat_list_options')
			&& target.className != 'chat_list_options_menu'
			&& target.className != 'chat_list_options_menu_selected'
			&& target.className != 'chat_list_results'
			&& target.className != 'chat_search_field'
			&& target.id != 'search_un' && target.id != 'sfclose_img'
			&& target.id != 'chat_status_person' && target.id != 'chat_status_circle'
			&& target.id != 'chat_online_status' && target.id != 'online_friends_count'
		)
		{
			foldChat()
		}
	};
}

function foldChat()
{
	clearSearchInUsersList();
	JQ('#chat_expanded_holder').remove();
	JQ('#chat_list_button').removeClass('chat_bottom_hide_hover').addClass('chat_bottom_hide');
	document.body.onclick = function(){ return; };
}

function fixFieldValue(field, default_phrase)
{
	if(trim(field.value) == default_phrase || field.value.length == '') field.value = '';
	else if(trim(field.value) == '') field.value(default_phrase);
}

function searchFieldFocus(ftype, field, default_phrase)
{
	fixFieldValue(field, default_phrase);
	
	var value_length = field.value.length;
	switch(ftype)
	{
		//search
		case 'search':
			searchInUsersList(field.value);
			createSearchClearButton(field.value, default_phrase);
			break;
		//focus
		case 'focus':
			JQ(field).addClass('search_un_selected');
			//show close button
			if(value_length > 0)
			{
				createSearchClearButton(field.value, default_phrase);
			}
			else
			{
				JQ('#sfclose_img').remove();
			}
			break;
		//blur
		case 'blur':
			if(value_length == 0)
			{
				field.value = default_phrase;
				JQ(field).addClass('search_un').removeClass('search_un_selected');
				JQ('#sfclose_img').remove();
			}
			break;
	}
}

function createSearchClearButton(fvalue, default_phrase)
{
	if(JQ('#sfclose_img').length == 0 && trim(fvalue) != '' && trim(fvalue) != default_phrase)
	{
		var close_img = '<a href="javascript:void(0);" title="Премахни" onclick="clearSearchInUsersList();">';
		close_img += '<img id="sfclose_img" src="' + chat_images + 'chat_close_icon_gray.png" alt="Премахни" class="chat_search_field_close_icon"/>';
		close_img += '</a>';
		
		JQ('#field_wrapper').append(close_img);
		
		JQ('#sfclose_img').mouseover( function() {
			this.src = chat_images + '/chat_close_icon_white.png';
			JQ(this).addClass('chat_search_field_close_icon_selected').removeClass('chat_search_field_close_icon');
		})
		.mouseout( function() {
			this.src = chat_images + '/chat_close_icon_gray.png';
			JQ(this).addClass('chat_search_field_close_icon').removeClass('chat_search_field_close_icon_selected');
		});
	}
}

function connectToChatServer(remote)
{
	//remote login
	if(typeof(remote) !== 'undefined' && remote == 1)
	{
		JQ.post("http://www.bghora.com/ajax/connect_to_chat.php", { 'do': 1 }, function(data) {
			ujson = data;
			connectToChatServer();
		});
	}
	else if(uinfo = JQ.parseJSON(ujson))
	{
		//Strophe.addNamespace('COMMANDS', 'http://jabber.org/protocol/commands');
		//Strophe.addNamespace('ADMIN', 'http://jabber.org/protocol/admin');
		connection = new Strophe.Connection(BOSH_SERVICE);
		
	  //connection.connect(uinfo.username + "@"+ chat_domain + chat_resource, uinfo.password, onConnect, chat_wait);
	  connection.attach(uinfo.jid, uinfo.sid, uinfo.rid, onConnect, chat_wait);
	}
}

function disconnectFromChatServer()
{
	if(connection)
	{
		connection.disconnect();
		connection.reset();
	}
}

function onConnect(status)
{
	//check connected
	if(status === Strophe.Status.ATTACHED)
	{
		connection.addHandler(notifyUser, null, null, null, null, null);
    connection.addHandler(systemPresence, null, 'presence', null, null, null);
    connection.addHandler(showMessages, null, 'message', null, null, pubsub_service);
    //connection.send($iq({type: 'get', xmlns: Strophe.NS.CLIENT}).c('query', {xmlns: Strophe.NS.ROSTER}).tree());
    if(typeof(ufriends) !== 'undefined') connection.send($pres({ uinfo_json: ujson }).tree());
    else connection.send($pres({to: chat_room + '/' + Strophe.getBareJidFromJid(connection.jid), uinfo_json: ujson}).tree());
    connection.flush();
    
    JQ('#chat_status_circle').attr('src', chat_images + 'chat_online_circle.png');
  }
  //check terminated
  else if(status === Strophe.Status.DISCONNECTED)
  {
  	connectToChatServer(1);
  }
  return true;
}

function startChat(tojid, message, folded)
{
	connection.resume();
	
	tojid_json = JQ.parseJSON(ulist[tojid]);
	if(tojid_json !== null)
	{
		//clear user search
		searchInUsersList('');
		
		var node_name = uinfo.user_id + '_and_' + tojid_json.user_id;
		var node_name_reverse = tojid_json.user_id + '_and_' + uinfo.user_id;
		
		if(JQ('#' + node_name).length > 0 || JQ('#' + node_name_reverse).length > 0 )
		{
			node_name = (JQ('#' + node_name).length > 0 ? node_name : node_name_reverse);
			
			if(chat_on_focus != node_name && folded != 1)
			{
				//check if node is visible
				if(in_array(visible_chats, node_name) !== false) openChatWindow(tojid);
				else scrollToChatWindow(node_name, tojid);
			}
			else if(chat_on_focus == node_name && in_array(visible_chats, node_name) === false) scrollToChatWindow(node_name, tojid);
			return true;
		}
		else
		{
			//create chat node
			var item_expire = 60 * 60 * 24 * 5 * 1000;
			var schid = connection.getUniqueId('start_chat');
			var ask = $iq({
				id: schid,
				to: pubsub_service,
				from: connection.jid,
				type: "set"
			}).c('pubsub', { xmlns: Strophe.NS.PUBSUB })
				.c('create', { node: node_name })
				.up().c('configure').c('x', { xmlns: 'jabber:x:data', type: 'submit' })
				.c('field', { 'var': 'FORM_TYPE', type: 'hidden' }).c('value').t(Strophe.NS.PUBSUB_NODE_CONFIG)
				.up().up().c('field', { 'var': 'pubsub#access_model' }).c('value').t('authorize')
				.up().up().c('field', { 'var': 'pubsub#publish_model' }).c('value').t('publishers')
				.up().up().c('field', { 'var': 'pubsub#notify_sub' }).c('value').t('1')
				.up().up().c('field', { 'var': 'pubsub#max_payload_size' }).c('value').t('10240')
				.up().up().c('field', { 'var': 'pubsub#max_items' }).c('value').t('10')
				.up().up().c('field', { 'var': 'pubsub#item_expire' }).c('value').t(item_expire.toString())
				.up().up().c('field', { 'var': 'pubsub#persist_items' }).c('value').t('1')
				.up().up().c('field', { 'var': 'pubsub#deliver_payloads' }).c('value').t('1')
				//tojid_json.user_id
				.up().up().c('field', { 'var': 'pubsub#publisher' }).c('value').t(tojid_json.username + '@' + chat_domain)
				.up().up().up().up().c('custom_fields', { 'tojid': tojid, 'message': (message != undefined ? message : '') });
			connection.addHandler(function(msg) {
					//14101988
					//var node_name = msg.getElementsByTagName('create')[0].getAttribute('node');
					//var tojid = msg.getElementsByTagName('custom_fields')[0].getAttribute('tojid');
					//var tojid_message = msg.getElementsByTagName('custom_fields')[0].getAttribute('message');
					var conversation = new Array();
					
					if(msg.getElementsByTagName('error').length == 0)
					{
						//subscribe users to chat node
						var sschid = connection.getUniqueId('subscribe_chat');
						var ask = $iq({
							id: sschid,
							to: pubsub_service,
							from: connection.jid,
							type: "set"
						}).c('pubsub', { xmlns: Strophe.NS.PUBSUB_OWNER })
							.c('subscriptions', { node: node_name })
							//tojid_json.user_id
							.c('subscription', { jid: tojid_json.username + '@' + chat_domain + chat_resource, subscription: 'subscribed' });
						
						connection.send(ask.tree());
					}
					//check old messages
					else
					{
						//my messages
						var sitemsid = connection.getUniqueId('items');
						var ask = $iq({
							id: sitemsid,
							to: pubsub_service,
							from: connection.jid,
							type: "get"
						}).c('pubsub', { xmlns: Strophe.NS.PUBSUB })
							.c('items', { node: node_name });
						connection.addHandler(function(msg) {
							var messages = msg.getElementsByTagName('message');
							for(var a = 0; a < messages.length; a++)
							{
								var time_sent = Math.round((new Date().getTime() / 1000) - messages[a].getAttribute('time_sent'));
								conversation[time_sent] = { body: Strophe.getText(messages[a].getElementsByTagName('body')[0]), tojid: uinfo.user_id, time: messages[a].getAttribute('time_sent') * 1000 };
							}
							
							//opponent messages
							var subid = connection.getUniqueId('subscriptions');
							var ask = $iq({
								id: subid,
								to: pubsub_service,
								from: connection.jid,
								type: "get"
							}).c('pubsub', { xmlns: Strophe.NS.PUBSUB })
								.c('subscriptions', { node: node_name_reverse });
							connection.addHandler(function(msg) {
								
								var subid = '';
								var subscriptions = msg.getElementsByTagName('subscription');
								for(var a = 0; a < subscriptions.length; a++)
								{
									if(subscriptions[a].getAttribute('jid') == connection.jid)
									{
										subid = subscriptions[a].getAttribute('subid');
										break;
									}
								}
								
								var sitemsrid = connection.getUniqueId('items_reverse');
								var ask = $iq({
									id: sitemsrid,
									to: pubsub_service,
									from: connection.jid,
									type: "get"
								}).c('pubsub', { xmlns: Strophe.NS.PUBSUB })
									.c('items', { node: node_name_reverse, subid: subid });
								connection.addHandler(function(msg) {
									var messages = msg.getElementsByTagName('message');
									if(messages.length > 0)
									{
										var tojid_json = JQ.parseJSON(Strophe.getText(messages[0].getElementsByTagName('uinfo_json')[0]));
										for(var a = 0; a < messages.length; a++)
										{
											var time_sent = Math.round((new Date().getTime() / 1000) - messages[a].getAttribute('time_sent'));
											conversation[time_sent] = { body: Strophe.getText(messages[a].getElementsByTagName('body')[0]), tojid: tojid_json.user_id, time: messages[a].getAttribute('time_sent') * 1000 };
										}
										
										conversation = sortObj(conversation);
										
										for(var i in conversation)
										{
											if(typeof(conversation[i]) !== 'undefined' && typeof(conversation[i].body) !== 'undefined')
											{
												var msg = {};
												msg.message = conversation[i].body;
												msg.time = conversation[i].time;
												generateMessage(node_name, msg, conversation[i].tojid, 0);
											}
										}
									}
									
								} , null, 'iq', null, sitemsrid, pubsub_service, null);
								connection.send(ask.tree());
								
							} , null, 'iq', null, subid, pubsub_service, null);
							connection.send(ask.tree());
							
						} , null, 'iq', null, sitemsid, pubsub_service, null);
						connection.send(ask.tree());
					}
					
					openChatLabel(tojid, folded);
					
					generateOnlineList();
					
					//receive message
					if(typeof(message) !== 'undefined')
					{
						var msg = {};
						msg.message = message;
						msg.time = new Date().getTime();
						
						generateMessage(node_name, msg, tojid, folded);
						playSound();
					}
				} , null, 'iq', null, schid, pubsub_service, null);
			connection.send(ask.tree());
		}
	}
}

function openChatLabel(tojid, folded)
{
	tojid_json = JQ.parseJSON(ulist[tojid]);
	
	var node_name = uinfo.user_id + '_and_' + tojid_json.user_id;
	var node_name_reverse = tojid_json.user_id + '_and_' + uinfo.user_id;
	
	if(JQ('#' + node_name).length == 0 && JQ('#' + node_name_reverse).length == 0)
	{
		var nchm = document.createElement('div');
		nchm.id = node_name;
		if(folded == 1) nchm.className = 'chat_message_hide_blink';
		else nchm.className = 'chat_message_hide_hover';
		nchm.innerHTML = cutString(tojid_json.name, 15);
		JQ(nchm).click( function(){
			if(in_array(new Array('chat_message_hide','chat_message_hide_blink'), JQ(this).attr('class')) !== false) openChatWindow(tojid);
			else hideChatLabel(node_name);
		});
		
		var close_img = '<a href="javascript:void(0);" title="Затвори" onclick="closeChatLabel(\'' + node_name + '\');">';
		close_img += '<img id="cmhclose_img_' + node_name + '" src="' + chat_images + 'chat_close_icon_gray.png" alt="Затвори" class="chat_search_field_close_icon"/>';
		close_img += '</a>';
		
		JQ(nchm).append(close_img);
		if(JQ('#' + node_name).length == 0) JQ('#chat_messages').append(nchm);
		
		JQ('#cmhclose_img_' + node_name).mouseover( function() {
			this.src = chat_images + '/chat_close_icon_white.png';
			JQ(this).addClass('chat_search_field_close_icon_selected').removeClass('chat_search_field_close_icon');
		})
		.mouseout( function() {
			this.src = chat_images + '/chat_close_icon_gray.png';
			JQ(this).addClass('chat_search_field_close_icon').removeClass('chat_search_field_close_icon_selected');
		});
		
		if(JQ('#' + node_name).length == 1)
		{
			active_chats.push(node_name);
			active_chats = array_unique(active_chats);
		}
	}
	
	//calclulate window width
	if(window_width == 0)
	{
		var chatbox = JQ(JQ('#chat_messages').children()[0]);
		window_width = Math.round( parseInt(chatbox.width()) + parseInt(chatbox.css('padding-left')) +
		+ parseInt(chatbox.css('padding-right')) + parseInt(chatbox.css('borderRightWidth')) +
		+ parseInt(chatbox.css('borderLeftWidth')) );
		
		//calculate chat wrapper width
		var endel = JQ('#lastLi');
		var wrapper = JQ('div.chat_messages_wrapper');
		var maxleft = parseInt(endel.position().left) + parseInt(endel.width()) + parseInt(endel.css('padding-left')) +
		+ parseInt(endel.css('padding-right'));
		cwidth = JQ(window).width() - maxleft - parseInt(wrapper.css('right')) - 70;
		wrapper.css('width', (Math.floor(wrapper.width() / window_width) * window_width));
	}
	
	openChatWindow(tojid, folded);
	
	fixChatLabels();
}

function closeChatLabel(node_name)
{
	JQ('#' + node_name + '_win').remove();
	JQ('#' + node_name).remove();
	
	for(var i in active_chats)
	{
		if(active_chats[i] == node_name)
		{
			active_chats.splice(i, 1);
			
			//fix margins
			var a = 0;
			JQ('#chat_windows').children().each( function(){
				if(a >= i) JQ(this).css('margin-right', function(index, value){ return parseInt(value) - window_width - 1; } );
				a++;
			});
			
			break;
		}
	}
	if(chat_on_focus == node_name) chat_on_focus = '';
	
	fixChatLabels();
	
	generateOnlineList();
}

function hideChatLabel(node_name)
{
	JQ('#' + node_name + '_win').hide();
	JQ('#' + node_name).removeClass('chat_message_hide_hover').addClass('chat_message_hide');
	chat_on_focus = '';
}

function fixChatLabels()
{
	var max_length = parseInt(JQ('div.chat_messages_wrapper').css('width'));
	var chat_width = 0;
	var arrow_width = 35;
	
	if((active_chats.length * window_width) > max_length)
	{
		var coef = parseInt(((active_chats.length * window_width) - max_length) / window_width);
		
		//create arrows
		if(JQ('div.left_chat_arrow').length == 0)
		{
			var left_chat_arrow = document.createElement('div');
			left_chat_arrow.id = 'left_chat_arrow';
			left_chat_arrow.className = 'left_chat_arrow';
			JQ(left_chat_arrow).css('right', (arrow_width + max_length + parseInt(JQ('div.chat_messages_wrapper').css('right'))));
			JQ(left_chat_arrow).click( function(){
				if(!JQ(this).hasClass('waiting')) {
					JQ(this).addClass('waiting'); moveChatLabelsLeft(chat_width);
				}
			});
			
			var right_chat_arrow = document.createElement('div');
			right_chat_arrow.id = 'right_chat_arrow';
			right_chat_arrow.className = 'right_chat_arrow';
			JQ(right_chat_arrow).css('right', (parseInt(JQ('div.chat_messages_wrapper').css('right'))));
			JQ(right_chat_arrow).click( function(){
				if(!JQ(this).hasClass('waiting')) {
					JQ(this).addClass('waiting'); moveChatLabelsRight(chat_width);
				}
			});
			
			JQ(left_chat_arrow).append('<img src="' + chat_images + 'chat_left_arrow.png" alt=""/> <span id="lca_count">0</span>');
			JQ(right_chat_arrow).append('<span id="rca_count">0</span> <img src="' + chat_images + 'chat_right_arrow.png" alt=""/>');
			
			JQ('div.chat_messages_wrapper').after(right_chat_arrow);
			JQ('div.chat_messages_wrapper').before(left_chat_arrow);
			
			JQ('div.chat_messages_wrapper').css('right', function(index, value) { return parseInt(value) + arrow_width; });
			JQ('#chat_windows').css('right', function(index, value) { return parseInt(value) + arrow_width; });
		}
		
		JQ('#chat_messages').css('margin-right', function(index, value) { return -(window_width * coef); });
		JQ('#chat_windows').css('margin-right', function(index, value) { return -(window_width * coef); });
		
		JQ('#rca_count').html(coef);
		JQ('#lca_count').html('0');
		
		//set visible chats
		visible_chats = new Array();
		var cmchildren = JQ('#chat_messages').children();
		for(var i = cmchildren.length; i > (cmchildren.length - Math.round(max_length / window_width)); i--)
		{
			visible_chats.push(JQ(cmchildren[(i - 1)]).attr('id'));
		}
		visible_chats = array_unique(visible_chats);
	}
	else if(JQ('div.left_chat_arrow').length > 0)
	{
		visible_chats = active_chats;
		
		JQ('div.chat_messages_wrapper').css('right', function(index, value) { return parseInt(value) - arrow_width; });
		JQ('#chat_messages').css('margin-right', 0);
		JQ('#chat_windows').css('margin-right', 0);
		JQ('#chat_windows').css('right', function(index, value) { return parseInt(value) - arrow_width; });
		JQ('div.left_chat_arrow').remove();
		JQ('div.right_chat_arrow').remove();
		
		if(chat_on_focus != '') JQ('#' + chat_on_focus + '_win').css('display','block');//JQ('#' + chat_on_focus + '_win').show('fast');
	}
	else visible_chats = active_chats;
	
	fixUnreadLabels();
}

function moveChatLabelsRight(chat_width, coef, tojid)
{
	if(parseInt(JQ('#chat_messages').css('margin-right')) < 0)
	{
		coef = coef != null ? coef : 1;
		cwindow_width = window_width * coef;
		if(chat_on_focus != '') JQ('#' + chat_on_focus + '_win').hide();
		
		var step = 0;
		JQ('#chat_messages').animate( {'margin-right': "+=" + cwindow_width },
			{
				duration: 200,
				complete: function() {
					if(parseInt(JQ('#chat_windows').css('margin-right')) + cwindow_width == 0) JQ('#chat_windows').css('margin-right', '0');
					else JQ('#chat_windows').css('margin-right', function(index, value) { return parseInt(value) + cwindow_width; });
					
					JQ('#rca_count').html(parseInt(JQ('#rca_count').html()) - coef);
					JQ('#lca_count').html(parseInt(JQ('#lca_count').html()) + coef);
					
					//set visible chats
					var npos = in_array(active_chats, visible_chats[(visible_chats.length - 1)]);
					for(var i = 1; i <= coef; i++)
					{
						var addchild = JQ(JQ('#chat_messages').children()[(npos - i)]).attr('id');
						visible_chats.splice(0, 1);
						visible_chats.push(addchild);
					}
					visible_chats = array_unique(visible_chats);
					
					fixUnreadLabels();
					
					if(tojid != null) openChatWindow(tojid);
					if(chat_on_focus != '')
					{
						var cofpos = in_array(active_chats, chat_on_focus);
						
						if( cofpos === false || ( cofpos < (active_chats.length - parseInt(JQ('#lca_count').html())) && cofpos >= parseInt(JQ('#rca_count').html()) ) )
						{
							JQ('#' + chat_on_focus + '_win').css('display','block');
						}
					}
					JQ('#right_chat_arrow').removeClass('waiting');
				},
				step: function(now, fx) {
					if((Math.abs(now) % (cwindow_width / coef)) == 0)
					{
						if(step > 0)
						{
							var cel = (Math.abs(now) / (cwindow_width / coef));
							var vel = in_array(active_chats, visible_chats[0]);
							
							//right label
							var cnode = active_chats[cel];
							if(typeof(cnode) !== 'undefined')
							{
								var uel = JQ('#' + cnode);
								var glunread = JQ('#chat_unread_' + cnode);
								if(uel.attr('class') == 'chat_message_hide_blink' && glunread.length > 0)
								{
									uel.append(glunread);
									glunread.removeClass('global_chat_unread_messages').addClass('chat_unread_messages');
								}
							}
							
							//left label
							var cnode = active_chats[(vel + cel)];
							if(typeof(cnode) !== 'undefined')
							{
								var uel = JQ('#' + cnode);
								var glunread = JQ('#chat_unread_' + cnode);
								if(uel.attr('class') == 'chat_message_hide_blink' && glunread.length > 0)
								{
									JQ('#left_chat_arrow').append(glunread);
									glunread.removeClass('chat_unread_messages').addClass('global_chat_unread_messages');
								}
							}
						}
						step++;
					}
				}
		});
	}
	else JQ('#right_chat_arrow').removeClass('waiting');
}

function moveChatLabelsLeft(chat_width, coef, tojid)
{
	coef = coef != null ? coef : 1;
	cwindow_width = window_width * coef;
	
	if(typeof(active_chats[(in_array(active_chats, visible_chats[0]) + coef)]) !== 'undefined')
	{
		if(chat_on_focus != '') JQ('#' + chat_on_focus + '_win').hide();
		
		var step = 0;
		JQ('#chat_messages').animate( {'margin-right': "-=" + cwindow_width },
			{
				duration: 200,
				complete: function() {
					if(parseInt(JQ('#chat_windows').css('margin-right')) - cwindow_width == 0) JQ('#chat_windows').css('margin-right', '0');
					else JQ('#chat_windows').css('margin-right', function(index, value) { return parseInt(value) - cwindow_width; });
					
					JQ('#rca_count').html(parseInt(JQ('#rca_count').html()) + coef);
					JQ('#lca_count').html(parseInt(JQ('#lca_count').html()) - coef);
					
					//set visible chats
					var ppos = in_array(active_chats, visible_chats[0]);
					for(var i = 1; i <= coef; i++)
					{
						var addchild = JQ(JQ('#chat_messages').children()[(ppos + i)]).attr('id');
						visible_chats.splice((visible_chats.length - 1), 1);
						visible_chats.splice(0, 0, addchild);
					}
					visible_chats = array_unique(visible_chats);
					
					fixUnreadLabels();
					
					if(tojid != null) openChatWindow(tojid);
					if(chat_on_focus != '')
					{
						var cofpos = in_array(active_chats, chat_on_focus);
						
						if( cofpos === false || ( cofpos < (active_chats.length - parseInt(JQ('#lca_count').html())) && cofpos >= parseInt(JQ('#rca_count').html()) ) )
						{
							JQ('#' + chat_on_focus + '_win').css('display','block');
						}
					}
					
					JQ('#left_chat_arrow').removeClass('waiting');
				},
				step: function(now, fx) {
					if((Math.abs(now) % (cwindow_width / coef)) == 0)
					{
						if(step > 0)
						{
							var cel = (Math.abs(now) / (cwindow_width / coef));
							var vel = in_array(active_chats, visible_chats[(visible_chats.length - 1)]);
							
							//left label
							var cnode = active_chats[(cel + 1)];
							if(typeof(cnode) !== 'undefined')
							{
								var uel = JQ('#' + cnode);
								var glunread = JQ('#chat_unread_' + cnode);
								if(uel.attr('class') == 'chat_message_hide_blink' && glunread.length > 0)
								{
									uel.append(glunread);
									glunread.removeClass('global_chat_unread_messages').addClass('chat_unread_messages');
								}
							}
							
							//right label
							var cnode = active_chats[(vel + cel - 1)];
							if(typeof(cnode) !== 'undefined')
							{
								var uel = JQ('#' + cnode);
								var glunread = JQ('#chat_unread_' + cnode);
								if(uel.attr('class') == 'chat_message_hide_blink' && glunread.length > 0)
								{
									JQ('#right_chat_arrow').append(glunread);
									glunread.removeClass('chat_unread_messages').addClass('global_chat_unread_messages');
								}
							}
						}
						step++;
					}
				}
		});
	}
	else JQ('#left_chat_arrow').removeClass('waiting');
}

function scrollToChatWindow(node_name, tojid)
{
	var chat_width = 0;
	var npos = in_array(active_chats, node_name);
	var lpos = in_array(active_chats, visible_chats[0]);
	var rpos = in_array(active_chats, visible_chats[(visible_chats.length - 1)]);
	
	//check if left
	if(npos > lpos)
	{
		var coef = (npos - lpos);
		if(!JQ('#left_chat_arrow').hasClass('waiting')) {
			JQ(this).addClass('waiting');
			moveChatLabelsLeft(chat_width, coef, tojid);
		}
	}
	//check if right
	else if(npos < rpos)
	{
		var coef = (rpos - npos);
		if(!JQ('#right_chat_arrow').hasClass('waiting')) {
			JQ(this).addClass('waiting');
			moveChatLabelsRight(chat_width, coef, tojid);
		}
	}
}

function fixUnreadLabels()
{
	var lpos = in_array(active_chats, visible_chats[0]);
	var rpos = in_array(active_chats, visible_chats[(visible_chats.length - 1)]);
	
	for(var i = 0; i < active_chats.length; i++)
	{
		var uel = JQ('#' + active_chats[i]);
		var glunread = JQ('#chat_unread_' + active_chats[i]);
		var vel_id = in_array(visible_chats, active_chats[i]);
		
		//fix chat on focus
		if(chat_on_focus == active_chats[i] && (i > lpos || i < rpos) && vel_id === false)
		{
			chat_on_focus = '';
			uel.removeClass('chat_message_hide_hover').addClass('chat_message_hide');
		}
		
		//check if appeared visible
		if(uel.attr('class') == 'chat_message_hide_blink' && glunread.attr('class') == 'global_chat_unread_messages' && vel_id !== false)
		{
			uel.append(glunread);
			glunread.removeClass('global_chat_unread_messages').addClass('chat_unread_messages');
		}
		//check if moved from right to left arrow
		else if(uel.attr('class') == 'chat_message_hide_blink'
			&& glunread.attr('class') == 'global_chat_unread_messages'
			&& vel_id === false
			&& i > lpos
			&& JQ('#right_chat_arrow').children('[id="chat_unread_' + active_chats[i] + '"]').length > 0
		)
		{
			JQ('#left_chat_arrow').append(glunread);
		}
		//check if moved from left to right arrow
		else if(uel.attr('class') == 'chat_message_hide_blink'
			&& glunread.attr('class') == 'global_chat_unread_messages'
			&& vel_id === false
			&& i < rpos
			&& JQ('#left_chat_arrow').children('[id="chat_unread_' + active_chats[i] + '"]').length > 0
		)
		{
			JQ('#right_chat_arrow').append(glunread);
		}
		//check if moved from visible to left arrow
		else if(uel.attr('class') == 'chat_message_hide_blink'
			&& glunread.attr('class') == 'chat_unread_messages'
			&& vel_id === false
			&& i > lpos
		)
		{
			JQ('#left_chat_arrow').append(glunread);
			glunread.removeClass('chat_unread_messages').addClass('global_chat_unread_messages');
		}
		//check if moved from visible to right arrow
		else if(uel.attr('class') == 'chat_message_hide_blink'
			&& glunread.attr('class') == 'chat_unread_messages'
			&& vel_id === false
			&& i < rpos
		)
		{
			JQ('#right_chat_arrow').append(glunread);
			glunread.removeClass('chat_unread_messages').addClass('global_chat_unread_messages');
		}
	}
}

function openChatWindow(tojid, folded)
{
	tojid_json = JQ.parseJSON(ulist[tojid]);
	
	var node_name = uinfo.user_id + '_and_' + tojid_json.user_id;
	var node_name_reverse = tojid_json.user_id + '_and_' + uinfo.user_id;
	
	//user offline
	if(tojid_json.status == 'offline')
	{
		var offmsg = tojid_json.name + ' не е на линия. Вашето съобщение ще бъде изпратено като писмо.';
		var offline_dstatus = document.createElement('div');
		offline_dstatus.className = 'chat_messages_offline_message';
		offline_dstatus.innerHTML = offmsg;
	}
	
	if(JQ('#' + node_name + '_win').length == 0 && JQ('#' + node_name_reverse + '_win').length == 0)
	{
		var chwin = document.createElement('div');
		chwin.id = node_name + '_win';
		chwin.className = 'chat_window';
		if(folded == 1) chwin.style.display = 'none';
		
		//fix margin
		chwin.style.marginRight = (window_width * parseInt(in_array(active_chats, node_name))) - 1 + 'px' ;
		
		//chat window label
		var chlabel = document.createElement('div');
		chlabel.id = 'chat_header_label';
		chlabel.className = 'chat_header_label';
		chlabel.innerHTML = tojid_json.name;
		chlabel.onclick = function(){ hideChatLabel(node_name); };
		
		//chat messages
		var chmsg = document.createElement('div');
		chmsg.id = 'chat_messages_dialog' + node_name;
		chmsg.className = 'chat_messages_show';
		
		//user offline
		if(typeof(offline_dstatus) !== 'undefined')
		{
			JQ(chmsg).append(offline_dstatus);
		}
		
		//chat type field
		var chtpl = document.createElement('div');
		chtpl.id = 'chat_type_field';
		chtpl.className = 'chat_search_field';
		var chfld = '<div id="field_wrapper_' + node_name + '" class="field_wrapper">';
		chfld += '<form name="' + node_name + '_form" method="post" action="" onsubmit="return false">';
		chfld += '<input type="text" id="typemsg_' + node_name + '" name="typemsg" class="search_un" value=""/>';
		chfld += '</form>';
		chfld += '</div>';
		JQ(chtpl).append(chfld);
		
		chwin.appendChild(chlabel);
		chwin.appendChild(chmsg);
		chwin.appendChild(chtpl);
		
		if(JQ('#' + node_name + '_win').length == 0) JQ('#chat_windows').append(chwin);
		
		if(folded != 1) JQ('#typemsg_' + node_name).focus();
		
		JQ('#typemsg_' + node_name).bind('keyup', function(e) {
				var code = (e.keyCode ? e.keyCode : e.which);
				if(code == 13) { sendMessage(node_name, this.value); this.value = ""; }
				else if(code == 27) { closeChatLabel(node_name); }
			});
		
		if(chat_on_focus != '' && folded != 1)
		{
			JQ('#' + chat_on_focus + '_win').hide();
			JQ('#' + chat_on_focus).removeClass('chat_message_hide_hover').addClass('chat_message_hide');
		}
		
		if(folded != 1) chat_on_focus = node_name;
	}
	else
	{
		node_name = (JQ('#' + node_name + '_win').length > 0 ? node_name : node_name_reverse);
		
		if(chat_on_focus != '' && folded != 1)
		{
			JQ('#' + chat_on_focus + '_win').hide();
			JQ('#' + chat_on_focus).removeClass('chat_message_hide_hover').addClass('chat_message_hide');
		}
		
		//user online
		if(tojid_json.status == 'online' && JQ('#chat_messages_dialog' + node_name).children('[class="chat_messages_offline_message"]').length > 0)
		{
			JQ('#chat_messages_dialog' + node_name).children('[class="chat_messages_offline_message"]').each(function(){
				JQ(this).remove();
			});
		}
		//user offline
		else if(typeof(offline_dstatus) !== 'undefined' && JQ('#chat_messages_dialog' + node_name).children('[class="chat_messages_offline_message"]').length == 0)
		{
			JQ('#chat_messages_dialog' + node_name).append(offline_dstatus);
		}
		
		if(folded != 1)
		{
			//JQ('#' + node_name + '_win').show( 'fast', function() {
				JQ('#' + node_name + '_win').css('display','block');
				scrollToBottom(node_name);
				
				var unread_main = JQ('#chat_messages_dialog' + node_name).children('[unread="1"]');
				var unread_sub = JQ('#chat_messages_dialog' + node_name).children().children('span[unread="1"]');
				
				//clean unread messages
				if(unread_main.length > 0)
				{
					JQ(unread_main).attr('unread', '0');
				}
				if(unread_sub.length > 0)
				{
					JQ(unread_sub).attr('unread', '0');
				}
				if(JQ('#chat_unread_' + node_name).length > 0) { JQ('#chat_unread_' + node_name).remove(); }
			//});
			
			JQ('#typemsg_' + node_name).focus();
			
			JQ('#' + node_name).removeClass('chat_message_hide').removeClass('chat_message_hide_blink').addClass('chat_message_hide_hover');
			
			chat_on_focus = node_name;
		}
		else chat_on_focus = '';
	}
}

function notifyUser(msg)
{
	//console.log(msg);
	
	return true;
}

function systemPresence(msg)
{
	if(typeof(ufriends) !== 'undefined')
	{
		check_friends = 1;
		ufriends_json = JQ.parseJSON(ufriends);
		
		var cu = msg.getAttribute('from');
		var cutp = msg.getAttribute('type') ? msg.getAttribute('type') : '';
		var check_friends = 0;
		
		if(msg.getAttribute('uinfo_json')) var muinfo_json = msg.getAttribute('uinfo_json');
		else
		{
			var muinfo_json = ulist[in_object(ufriends_json, getNameFromJid(Strophe.getBareJidFromJid(msg.getAttribute('from')), chat_domain))];
		}
		
		var muinfo_json_parsed = JQ.parseJSON(muinfo_json);
	}
	else
	{
		var muinfo_json = msg.getAttribute('uinfo_json');
		var muinfo_json_parsed = JQ.parseJSON(muinfo_json);
		
		var elems = msg.getElementsByTagName('item');
		var cu = elems[0].getAttribute('jid');
		var cutp = msg.getAttribute('type') ? msg.getAttribute('type') : '';
		var check_friends = 0;
	}
	
	if(typeof(muinfo_json_parsed.user_id) !== 'undefined' && ulist[muinfo_json_parsed.user_id] != 'undefined' && cu != connection.jid)
	{
		if((check_friends == 1 && in_object(ufriends_json, muinfo_json_parsed.user_id) !== false) || check_friends == 0)
		{
			if(cutp == 'unavailable')
			{
				muinfo_json_parsed.status = 'offline';
				muinfo_json = Stringify(muinfo_json_parsed);
				
				ulist[muinfo_json_parsed.user_id] = muinfo_json;
			}
			else
			{
				muinfo_json_parsed.status = 'online';
				muinfo_json = Stringify(muinfo_json_parsed);
				
				ulist[muinfo_json_parsed.user_id] = muinfo_json;
			}
		}
	}
	
	generateOnlineList();
	
	return true;
}

function generateOnlineList()
{
	ulist_html = '';
	ulist_length = 0;
	for(var i in ulist)
	{
		var start_chat_function =' startChat(\'' + i + '\');'
		var uinfo_json = JQ.parseJSON(ulist[i]);
		
		//if(JQ('#' + uinfo_json.user_id + '_and_' + uinfo.user_id).length == 0 && JQ('#' + uinfo.user_id + '_and_' + uinfo_json.user_id).length == 0)
		//{
			ulist_html += '<div id="uchr_' + uinfo_json.user_id + '" uchr_id="' + uinfo_json.user_id + '" class="chr" onclick="' + start_chat_function + '">';
			//ulist_html += '<a href="javascript:void(0);" title="Пиши на ' + uinfo_json.name + '" onclick="' + start_chat_function+ '"><img src="' + uinfo_json.avatar + '" alt="Пиши на ' + uinfo_json.name + '" class="avatar"/></a>';
			//ulist_html += '<a href="javascript:void(0);" title="Пиши на ' + uinfo_json.name + '" onclick="' + start_chat_function+ '">' + cutString(uinfo_json.name, 20) + '</a><br/>';
			ulist_html += '<img src="' + uinfo_json.avatar + '" alt="Пиши на ' + uinfo_json.name + '" class="avatar"/>';
			ulist_html += cutString(uinfo_json.name, 20);
			ulist_html += '<img src="' + chat_images + 'chat_' + uinfo_json.status + '_circle' + (uinfo_json.status == 'offline' ? '_chat' : '')+ '.png" alt="' + uinfo_json.status + '" class="sticon"/>';
			
			//unread messages
			var uche = JQ('#chat_unread_' + uinfo.user_id + '_and_' + uinfo_json.user_id);
			if(uche.length > 0)
			{
				var ulum = '<div id="ul_chat_unread_' + msg_node + '" class="ulist_chat_unread_messages">' + uche.html() + '</div>';
				
				ulist_html += ulum;
			}
			
			ulist_html += '</div>';
		//}
		
		if(uinfo_json.status == 'online') ulist_length += 1;
	}
	
	if(searching == 0) JQ('#chat_list_users').html(ulist_length > 0 ? ulist_html : '<div id="srch_no_result" class="chr">Няма онлайн потребители</div>');
	JQ('#online_friends_count').html(ulist_length);
	
	//set users list height
	if(window_height == 0 && ulist_length > 0 && JQ('#chat_list_users').length > 0)
	{
		var global_height = parseInt(JQ(window).height());
		var clbutton = JQ('#chat_list_button');
		var chlheight = parseInt(clbutton.height()) + parseInt(clbutton.css('padding-top')) +
			+ parseInt(clbutton.css('padding-bottom')) + parseInt(clbutton.css('borderTopWidth')) +
			+ parseInt(clbutton.css('borderBottomWidth'));
		var chfheight = JQ('#chat_search_field');
		var chfheight = parseInt(chfheight.height()) + parseInt(chfheight.css('padding-top')) +
			+ parseInt(chfheight.css('padding-bottom')) + parseInt(chfheight.css('borderTopWidth')) +
			+ parseInt(chfheight.css('borderBottomWidth'));
		var chlabheight = JQ('#chat_header_label');
		var chlabheight = parseInt(chlabheight.height()) + parseInt(chlabheight.css('padding-top')) +
			+ parseInt(chlabheight.css('padding-bottom')) + parseInt(chlabheight.css('borderTopWidth')) +
			+ parseInt(chlabheight.css('borderBottomWidth'));
		var single_user_el = JQ(JQ('#chat_list_users').children('[class="chr"]')[0]);
		var single_user_height = parseInt(single_user_el.height()) + 
			+ parseInt(single_user_el.css('padding-top')) + parseInt(single_user_el.css('padding-bottom')) +
			+ parseInt(single_user_el.css('margin-top')) + parseInt(single_user_el.css('margin-bottom')) +
			+ parseInt(single_user_el.css('borderTopWidth')) + parseInt(single_user_el.css('borderBottomWidth'));
		
		window_height = global_height - (chlheight + chfheight + chlabheight + 215);
		JQ('#chat_list_users').css('max-height', (Math.floor(window_height / single_user_height) * window_height));
	}
}

function searchInUsersList(phrase)
{
	searching = 1;
	phrase = trim(phrase);
	if(phrase == '') { clearSearchInUsersList(); return; }
	
	var reshow = new Array();
	
	//search in user name
	for(var i in ulist)
	{
		var cuj = JQ.parseJSON(ulist[i]);
		eval("if(cuj.name.search(/" + phrase + "/i) > -1 || cuj.username.search(/" + phrase + "/i) > -1) reshow.push(i);");
	}
	
	//render results
	JQ('#chat_list_users').children().each( function() {
		
		var clu_id = JQ(this).attr('uchr_id');
		if(in_array(reshow, clu_id) === false) JQ(this).css('display', 'none');
		else JQ(this).css('display', 'block');
		
	});
	
	if(reshow.length == 0)
	{
		if(JQ('#srch_no_result').length == 0) JQ('#chat_list_users').append('<div id="srch_no_result" class="chr">Няма намерени потребители.</div>');
	}
	else
	{
		JQ('#srch_no_result').remove();
	}
}

function clearSearchInUsersList()
{
	searching = 0;
	
	JQ('#search_un').val('');
	
	if(document.getElementById('search_un')) fixFieldValue(document.getElementById('search_un'), friends_in_chat_label);
	JQ('#search_un').blur();
	
	JQ('#chat_list_users').children().each( function() {
		
		JQ(this).css('display', 'block');
		
	});
	
	if(JQ('#chat_list_users').children().length > 0) JQ('#srch_no_result').remove();
	JQ('#sfclose_img').remove();
}

function sendMessage(node, msg, attribute)
{
	if(msg != '' && typeof(attribute) === 'undefined')
	{
		var message = {};
		message.message = msg;
		message.time = new Date().getTime();
		
		generateMessage(node, message, uinfo.user_id, 0);
	}
	connection.resume();
	
	//send message
	eval("var message = { xmlns: 'jabber:client', time_sent: Math.round(new Date().getTime() / 1000)" + (typeof(attribute) !== 'undefined' ? ', ' + attribute : '') + " }");
	var msgid = connection.getUniqueId('message_chat');
	var ask = $iq({
		id: msgid,
		to: pubsub_service,
		from: connection.jid,
		type: "set"
	}).c('pubsub', { xmlns: Strophe.NS.PUBSUB })
		.c('publish', { 'node': node }).c('item')
		.c('message', message)
		.c('body').t(msg)
		.up().c('uinfo_json').t(ujson);
	
	connection.send(ask.tree());
}

function showMessages(msg)
{
	if(msg.getAttribute('to') == connection.jid)
	{
		var unread = 0;
		var time_sent = '';
		
		//get node
		var msg_node_array = msg.getElementsByTagName('items');
		var msg_node_reverse = msg_node_array[0].getAttribute('node');
		var split_msg_node = msg_node_reverse.split('_and_');
		msg_node = split_msg_node[1] + '_and_' + split_msg_node[0];
		var muinfo_json = JQ.parseJSON(Strophe.getText(msg.getElementsByTagName('uinfo_json')[0]));
		
		var chat_dialog = '';
		var elems = msg_node_array[0].getElementsByTagName('message');
		time_sent = elems[0].getAttribute('time_sent');
		friends_approval = elems[0].getAttribute('friends');
		var mbody = elems[0].getElementsByTagName('body');
		
		if(Strophe.getText(mbody[0]) != '' && parseInt(friends_approval) != 1)
		{
			if(JQ('#' + msg_node + '_win').length == 0 && JQ('#' + msg_node_reverse + '_win').length == 0)
			{
				startChat(muinfo_json.user_id, '', (chat_on_focus != '' ? 1 : 0));
			}
			else
			{
				msg_node = (JQ('#' + msg_node + '_win').length > 0 ? msg_node : msg_node_reverse);
				if(chat_on_focus != msg_node)
				{
					unread = 1;
					
					//show unread messages count
					var unread_main = JQ('#chat_messages_dialog' + msg_node).children('[unread="1"]');
					var unread_sub = JQ('#chat_messages_dialog' + msg_node).children().children('span[unread="1"]');
					
					var unread_messages_count = (unread_main.length + unread_sub.length) + 1;
					
					if(JQ('#chat_unread_' + msg_node).length > 0)
					{
						JQ('#chat_unread_' + msg_node).html(unread_messages_count);
					}
					else
					{
						//set global unread icon
						if(in_array(visible_chats, msg_node) === false)
						{
							var gl_chunmsg = document.createElement('div');
							gl_chunmsg.id = 'chat_unread_' + msg_node;
							gl_chunmsg.className = 'global_chat_unread_messages';
							JQ(gl_chunmsg).html(unread_messages_count);
							
							var npos = in_array(active_chats, msg_node);
							var lpos = in_array(active_chats, visible_chats[0]);
							var rpos = in_array(active_chats, visible_chats[(visible_chats.length - 1)]);
							
							//check if left
							if(npos > lpos)
							{
								var arrow = JQ('#left_chat_arrow');
							}
							//check if right
							else if(npos < rpos)
							{
								var arrow = JQ('#right_chat_arrow');
							}
							
							arrow.append(gl_chunmsg);
						}
						else
						{
							var chunmsg = document.createElement('div');
							chunmsg.id = 'chat_unread_' + msg_node;
							chunmsg.className = 'chat_unread_messages';
							JQ(chunmsg).html(unread_messages_count);
							JQ('#' + msg_node).append(chunmsg);
						}
					}
					
					JQ('#' + msg_node).removeClass('chat_message_hide').addClass('chat_message_hide_blink');
					
					//play sound for new message
					playSound();
					
					//upadte users list
					var uche = JQ('#uchr_' + + muinfo_json.user_id);
					if(uche.length > 0)
					{
						var ulum = '<div id="ul_chat_unread_' + msg_node + '" class="ulist_chat_unread_messages">' + unread_messages_count + '</div>';
						if(JQ('#ul_chat_unread_' + msg_node).length > 0) JQ('#ul_chat_unread_' + msg_node).html(unread_messages_count);
						else uche.append(ulum);
					}
				}
				
				var msg = {};
				msg.message = Strophe.getText(mbody[0]);
				msg.time = new Date().getTime();
				
				generateMessage(msg_node, msg, muinfo_json.user_id, (muinfo_json.user_id == uinfo.user_id ? 0 : unread));
			}
		}
		else if(friends_approval !== null)
		{
			if(typeof(ufriends) !== 'undefined' && muinfo_json != '')
			{
				//add friend
				if(parseInt(friends_approval) == 1)
				{
					var ufriends_json = JQ.parseJSON(ufriends);
					ufriends_json.push(muinfo_json.user_id);
					ufriends = stringifyArray(ufriends_json);
					
					muinfo_json.status = 'online';
					ulist[muinfo_json.user_id] = Stringify(muinfo_json);
					
					generateOnlineList();
					
					//subscribe to friend presence
					var frjid = muinfo_json.username + '@' + chat_domain + chat_resource;
    			var prscr = connection.getUniqueId('presubscr');
					var ask = $iq({
						id: prscr,
						type: "set"
					}).c('query', { xmlns: Strophe.NS.ROSTER })
						.c('item', { 'jid': frjid });
					connection.send(ask.tree());
					
					connection.send($pres({to: frjid, type: 'subscribed'}));
				}
				//remove friend
				else if(parseInt(friends_approval) == 0)
				{
					var ufriends_json = JQ.parseJSON(ufriends);
					
					var ukey = in_object(ufriends_json, muinfo_json.user_id);
					
					if(ukey !== false)
					{
						ufriends_json.splice(ukey, 1);
						ufriends = stringifyArray(ufriends_json);
						
						delete ulist[muinfo_json.user_id];
						
						closeChatLabel(msg_node);
						closeChatLabel(msg_node_reverse);
					}
				}
			}
		}
	}
	
	return true;
}

function generateMessage(node_name, msg, tojid, unread)
{
	mjson = tojid == uinfo.user_id ? uinfo : JQ.parseJSON(ulist[tojid]);
	var cmd_children = JQ('#chat_messages_dialog' + node_name).children();
	
	msg.message = wordwrap( setEmoticons( fixUrls(msg.message) ), 28, "\n", true );
	
	if(cmd_children.length > 0 && JQ(cmd_children[(cmd_children.length - 1)]).attr('fuid') == mjson.user_id)
	{
		JQ(cmd_children[(cmd_children.length - 1)]).append('<br/><span unread="' + unread + '">' + msg.message + '</span>');
	}
	else
	{
		var nmsg = document.createElement('div');
		nmsg.className = 'chat_msg_block';
		JQ(nmsg).append(msg.message);
		
		var avatar = document.createElement('img');
		avatar.src = mjson.avatar;
		avatar.setAttribute('alt', mjson.name);
		avatar.className = 'avatar';
		JQ(nmsg).prepend(avatar);
		
		var ndate = new Date();
		ndate.setTime(msg.time);
		var timeshow = document.createElement('div');
		timeshow.style.display = 'none';
		timeshow.className = 'timeshow';
		timeshow.innerHTML = ndate.getHours() + ':' + ndate.getMinutes();
		JQ(nmsg).prepend(timeshow);
		
		JQ(nmsg).mouseover( function(){ JQ(timeshow).css('display', 'block') } );
		JQ(nmsg).mouseout( function(){ JQ(timeshow).css('display', 'none') } );
		
		nmsg.setAttribute('fuid', mjson.user_id);
		nmsg.setAttribute('unread', unread);
		
		//user offline
		var prepend = 0;
		if(mjson == uinfo || mjson.status == 'offline')
		{
			if(mjson.status == 'offline')
			{
				var offmsg = mjson.name + ' не е на линия. Вашето съобщение ще бъде изпратено като писмо.';
				var offline_dstatus = document.createElement('div');
				offline_dstatus.className = 'chat_messages_offline_message';
				offline_dstatus.innerHTML = offmsg;
				
				if(JQ('#chat_messages_dialog' + node_name).children('[class="chat_messages_offline_message"]').length == 0)
				{
					JQ('#chat_messages_dialog' + node_name).append(offline_dstatus);
				}
			}
			
			if(JQ('#chat_messages_dialog' + node_name).children('[class="chat_messages_offline_message"]').length > 0)
			{
				prepend = 1;
			}
		}
		
		if(prepend == 0) JQ('#chat_messages_dialog' + node_name).append(nmsg);
		else JQ('#chat_messages_dialog' + node_name).children('[class="chat_messages_offline_message"]').each(function(){
			JQ(this).before(nmsg);
		});
	}
	
	scrollToBottom(node_name);
}

function scrollToBottom(node_name)
{
	if(JQ("#chat_messages_dialog" + node_name).length > 0)
	{
		JQ("#chat_messages_dialog" + node_name).animate({ scrollTop: JQ("#chat_messages_dialog" + node_name)[0].scrollHeight }, 200);
	}
}

function rebuildFriends(touser_json, uaction)
{
	var muinfo_json = JQ.parseJSON(touser_json);
	var node_name = uinfo.user_id + '_and_' + muinfo_json.user_id;
	var node_name_reverse = muinfo_json.user_id + '_and_' + uinfo.user_id;
	var frjid = muinfo_json.username + '@' + chat_domain + chat_resource;
	
	switch(uaction)
	{
		//add friend
		case 'ok':
			//create chat node
			var schid = connection.getUniqueId('subscribe_friends');
			var ask = $iq({
				id: schid,
				to: pubsub_service,
				from: connection.jid,
				type: "set"
			}).c('pubsub', { xmlns: Strophe.NS.PUBSUB })
				.c('create', { node: node_name })
				.up().c('configure').c('x', { xmlns: 'jabber:x:data', type: 'submit' })
				.c('field', { 'var': 'FORM_TYPE', type: 'hidden' }).c('value').t(Strophe.NS.PUBSUB_NODE_CONFIG)
				.up().up().c('field', { 'var': 'pubsub#access_model' }).c('value').t('whitelist')
				.up().up().c('field', { 'var': 'pubsub#publish_model' }).c('value').t('publishers')
				.up().up().c('field', { 'var': 'pubsub#notify_sub' }).c('value').t('1')
				.up().up().c('field', { 'var': 'pubsub#maxPayloadSize' }).c('value').t('4096')
				//to_userid
				.up().up().c('field', { 'var': 'pubsub#publisher' }).c('value').t(muinfo_json.username + '@' + chat_domain)
				.up().up().up().up().c('custom_fields', { 'tojid': muinfo_json.username });
			connection.addHandler(function(msg) {
				
				if(msg.getElementsByTagName('error').length == 0)
				{
					//subscribe users to chat node
					var sschid = connection.getUniqueId('subscribe_chat');
					var ask = $iq({
						id: sschid,
						to: pubsub_service,
						from: connection.jid,
						type: "set"
					}).c('pubsub', { xmlns: Strophe.NS.PUBSUB_OWNER })
						.c('subscriptions', { node: node_name })
						//to_userid
						.c('subscription', { jid: frjid, subscription: 'subscribed' });
					connection.send(ask.tree());
					
					//subscribe to friend presence
    			var prscr = connection.getUniqueId('presubscr');
					var ask = $iq({
						id: prscr,
						type: "set"
					}).c('query', { xmlns: Strophe.NS.ROSTER })
						.c('item', { 'jid': frjid });
					connection.send(ask.tree());
					
    			connection.send($pres({to: frjid, type: 'subscribed'}));
				}
				muinfo_json.status = 'online';
				ulist[muinfo_json.user_id] = Stringify(muinfo_json);
				
				sendMessage(node_name, '', 'friends:1');
				
				generateOnlineList();
				
			} , null, 'iq', null, schid, pubsub_service, null);
			connection.send(ask.tree());
		break;
		
		//remove friend
		case 'del':
			//unsubscribe users to chat node
			var sschid = connection.getUniqueId('unsubscribe_chat');
			var ask = $iq({
				id: sschid,
				to: pubsub_service,
				from: connection.jid,
				type: "set"
			}).c('pubsub', { xmlns: Strophe.NS.PUBSUB_OWNER })
				.c('subscriptions', { node: node_name })
				//to_userid
				.c('subscription', { jid: frjid, subscription: 'unsubscribed' });
			connection.send(ask.tree());
			
			//unsubscribe to friend presence
			connection.send($pres({to: frjid, type: 'unsubscribed'}));
			
			sendMessage(node_name, '', 'friends:0');
			
			//remove friend
			
			delete ulist[muinfo_json.user_id];
			
			closeChatLabel(node_name);
			closeChatLabel(node_name_reverse);
			
			connection.send($pres({to: chat_room + '/' + Strophe.getBareJidFromJid(connection.jid), uinfo_json: ujson}).tree());
		break;
	}
}

function getNameFromJid(jid, domain)
{
	return jid.replace('@' + domain, '')
}

//help functions
// Removes leading whitespaces
function LTrim( value )
{
	var re = /\s*((\S+\s*)*)/;
	return value.replace(re, "$1");
}

// Removes ending whitespaces
function RTrim( value )
{
	var re = /((\s*\S+)*)\s*/;
	return value.replace(re, "$1");
}

// Removes leading and ending whitespaces
function trim( value )
{
	return LTrim(RTrim(value));
}

function cutString(str, cutl)
{
	if(str.length <= cutl) return str;
	
	return str.substr(0, cutl) + '...';
}

function in_object(arr, str)
{
	var len = arr.length;
	for ( var x in arr )
	{
		if ( arr[x] == str ) return x;
	}
	return false;
}

function in_array(arr, str)
{
	var len = arr.length;
	for ( var x = 0 ; x < len ; x++ )
	{
		if ( arr[x] == str ) return x;
	}
	return false;
}

function array_unique(arr)
{
	var temp = new Array();
	var len = arr.length;
	for ( var x = 0 ; x < len ; x++ )
	{
		if(in_array(temp, arr[x]) === false) temp.push(arr[x]);
	}
	
	return temp;
}

function loadSoundPlayer()
{
	var flashvars = {
		file: chat_sound,
		as: 0
	};
	var params = {
		movie: chat_player,
		wmode: 'transparent',
		width: 1,
		height: 1
	};
	var attributes = {
		id: 'chatplayer',
		name: 'chatplayer',
		style: 'width:1px;height:1px;position:absolute;top:0px;left:0px;'
	};
	swfobject.embedSWF(chat_player, "chat_sound_player", "1", "1", "9.0.0","expressInstall.swf", flashvars, params, attributes);
}

function playSound()
{
	niftyplayer('chatplayer').play();
}

function Stringify(jsonData)
{
	var strJsonData = '{';
	var itemCount = 0;
	
	for (var item in jsonData) {
		if (itemCount > 0) {
			strJsonData += ', ';
		}
		strJsonData += '"' + item + '":"' + jsonData[item] + '"';
		itemCount++;
	}
	strJsonData += '}';
	
	return strJsonData;
}

function stringifyArray(arr)
{
	var count = 0;
	var ret = '[';
	
	for(var i in arr)
	{
		if(count > 0) ret += ',';
		ret += '"' + arr[i] + '"';
		count++;
	}
	
	ret += ']';
	
	return ret;
}

function wordwrap( str, width, brk, cut ) {
	
	brk = brk || '\n';
	width = width || 75;
	cut = cut || false;
	
	if (!str) { return str; }
	
	var regex = '.{1,' +width+ '}(\\s|$)' + (cut ? '|.{' +width+ '}|.+$' : '|\\S+?(\\s|$)');
	
	return str.match( RegExp(regex, 'g') ).join( brk );

}

function fixUrls(str)
{
	var re = /(^|\s)((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)/gi;
	//var re = /(\w+):\/\/[\S]+(\b|$)/gim;
	
	return str.replace(re, '<a href="$&" title="$&" target="_blank">$&</a>');
}

function setEmoticons(str)
{
	if(typeof(chat_emoticons) !== 'undefined' && JQ.parseJSON(chat_emoticons).length > 0)
	{
		var emoticons = JQ.parseJSON(chat_emoticons);
		var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\' ];
		eval("var regstring = /(\\" + specials.join('|\\') + ")/gi;");
		
		for(var i = 0; i < emoticons.length; i++)
		{
			var estring = emoticons[i].sign;
			eval("estring = /" + estring.replace(regstring, '\\$&') + "/gi;");
			str = str.replace(estring, '<img src="http://www.bghora.com/images/default/emoticons/' + emoticons[i].pic + '" alt="' + emoticons[i].title + '" class="emoticon"/>');
		}
	}
	
	return str;
}

function sortObj(arr)
{
	// Setup Arrays
	var sortedKeys = new Array();
	var sortedObj = new Array();
	
	// Separate keys and sort them
	for (var i in arr)
	{
		sortedKeys.push(i);
	}
	
	sortedKeys = sortedKeys.sort( function(a, b) { return (b - a); } );
	
	// Reconstruct sorted obj based on keys
	for (var i in sortedKeys)
	{
		sortedObj[i] = arr[sortedKeys[i]];
	}
	
	return sortedObj;
} 
