text: /**
   *	Chat Plugin
   *
   *	Created by: Arlind Nushi
   *
   *	www.laborator.co
   */
  
  var neonChat = neonChat || {
  	$current_user: null,
  	isOpen: false,
  	chat_history: [],
  	statuses: {
  		online: {class: 'is-online', order: 1, label: 'Online'},
  		offline: {class: 'is-offline', order: 4, label: 'Offline'},
  		idle: {class: 'is-idle', order: 3, label: 'Idle'},
  		busy: {class: 'is-busy', order: 2, label: 'Busy'}
  	}
  };
  
  ;(function($, window, undefined)
  {
  	"use strict";
  	
  	var $chat = $("#chat"),
  		$chat_inner = $chat.find('.chat-inner'),
  		$chat_badge = $chat.find('.badge').add($('.chat-notifications-badge')),
  		$conversation_window = $chat.find(".chat-conversation"),
  		$conversation_header = $conversation_window.find(".conversation-header"),
  		$conversation_body = $conversation_window.find('.conversation-body'),
  		$textarea = $conversation_window.find('.chat-textarea textarea'),
  		
  		sidebar_default_is_open = ! $(".page-container").hasClass('sidebar-collapsed');
  		
  	
  	$.extend(neonChat, {	
  		
  		init: function()
  		{
  			// Conversation Close
  			$conversation_window.on('click', '.conversation-close', neonChat.close);
  			
  			$("body").on('click', '.chat-close', function(ev)
  			{
  				ev.preventDefault();
  				
  				var animate = $(this).is('[data-animate]');
  				
  				neonChat.hideChat(animate);
  			});
  			
  			$("body").on('click', '.chat-open', function(ev)
  			{
  				ev.preventDefault();
  				
  				var animate = $(this).is('[data-animate]');
  				
  				neonChat.showChat(animate);
  			});
  			
  			
  			// Texarea
  			$textarea.keydown(function(e)
  			{
  				if(e.keyCode == 13 && !e.shiftKey)
  				{
  					e.preventDefault();
  					neonChat.submitMessage();
  					return false;
  				}
  				else
  				if(e.keyCode == 27)
  				{
  					neonChat.close();
  				}
  			});
  			
  							
  			$chat.on('click', '.chat-group a', function(ev)
  			{
  				ev.preventDefault();
  				
  				var $chat_user = $(this);
  				
  				if($chat_user.hasClass('active'))
  				{
  					neonChat.close();
  				}
  				else
  				{
  					neonChat.open($chat_user);
  				}
  			});
  			
  			$chat.find('.chat-group a').each(function(i, el)
  			{
  				var $this = $(el);
  				
  				$this.append('<span class="badge badge-info is-hidden">0</span>');
  			});
  			
  			neonChat.refreshUserIds();
  			neonChat.orderGroups();
  			neonChat.prefetchMessages();
  			neonChat.countUnreadMessages();
  			neonChat.puffUnreads();
  			
  			// Chat
  			if($chat.hasClass('fixed') && $chat_inner.length && $.isFunction($.fn.niceScroll))
  			{
  				$chat.find('.chat-inner').niceScroll({
  					cursorcolor: '#454a54',
  					cursorborder: '1px solid #454a54',
  					railpadding: {right: 3},
  					railalign: 'right',
  					cursorborderradius: 1
  				});
  			}
  			
  			// Chat Toggle
  			$("body").on('click', '[data-toggle="chat"]', function(ev)
  			{
  				ev.preventDefault();
  				
  				var $this = $(this),
  					with_animation = $this.is('[data-animate]'),
  					collapse_sidebar = $this.is('[data-collapse-sidebar]');
  				
  				neonChat.toggleChat(with_animation, collapse_sidebar);
  			});
  		},
  		
  		open: function($user_link)
  		{
  			this.refreshUserIds();
  			
  			if(typeof $user_link == 'string')
  			{
  				$user_link = $($user_link);
  			}
  			
  			// Set Active Class
  			$chat.find('.chat-group a').not($user_link).removeClass('active');
  			$user_link.addClass('active');
  		
  			// Chat Header
  			var user_status = this.statuses[ this.chat_history[$user_link.attr('id')].status ];
  			
  			
  			$conversation_header.find('.display-name').html($user_link.find('em').text());
  			
  			if(user_status)
  			{
  				$conversation_header.find('.user-status').attr('class', 'user-status ' + user_status.class);
  				$conversation_header.find('small').html(user_status.label);
  			}
  			
  			$conversation_window.show();
  			$textarea.val('');
  			
  			this.updateScrollbars();			
  			this.updateConversationOffset($user_link);
  			
  			
  			$textarea.focus();
  			
  			this.$current_user = $user_link;
  			this.isOpen = true;
  			
  			this.renderMessages(this.$current_user.attr('id'));
  			this.resetUnreads(this.$current_user.attr('id'));
  			this.puffUnreadsAll();
  		},
  		
  		close: function()
  		{
  			$chat.find('.chat-group a').removeClass('active');
  			
  			$conversation_window.hide().css({top: 0, opacity: 0});
  			
  			$conversation_body.find('li.unread').removeClass('unread');
  			
  			this.$current_user = null;
  			this.isOpen = false;
  			
  			return false;
  		},
  		
  		updateScrollbars: function()
  		{
  			scrollToBottom('#chat .chat-conversation .conversation-body');
  		},
  		
  		updateConversationOffset: function($el)
  		{
  			var top_h = $conversation_window.find('.conversation-body').position().top + 1,
  				offset = $el.position().top - top_h,
  				minus = 0,
  				
  				con_h = $conversation_window.height(),
  				win_h = $(window).height();
  			
  			if($chat.hasClass('fixed') && offset + con_h > win_h)
  			{
  				minus = offset + con_h - win_h;
  			}
  			
  			if($(".page-container.horizontal-menu").length)
  			{
  				minus += $(".page-container.horizontal-menu .navbar").height();
  			}
  			
  			offset -= minus;
  			
  			$conversation_window.transition({
  				top: offset,
  				opacity: 1
  			});
  			
  		},
  		
  		getChatHistoryLength: function()
  		{
  			var max_chat_history = parseInt($chat.data('max-chat-history'), 10);
  			
  			if( ! max_chat_history || max_chat_history < 1)
  			{
  				max_chat_history = 25;
  			}
  			
  			return max_chat_history;
  	
  		},
  		
  		submitMessage: function() // Submit whats on textarea
  		{
  			var msg = $.trim($textarea.val());
  			
  			$textarea.val('');
  			
  			if(this.isOpen && this.$current_user)
  			{
  				var id = this.$current_user.uniqueId().attr('id');
  				
  				this.pushMessage(id, msg.replace( /<.*?>/g, '' ), $chat.data('current-user'), new Date());
  				this.renderMessages(id);
  			}
  		},
  		
  		refreshUserIds: function()
  		{
  			$('#chat .chat-group a').each(function(i, el)
  			{
  				var $this = $(el),
  					$status = $this.find('.user-status');
  				
  				$this.uniqueId();
  				
  				var id = $this.attr('id');
  				
  				if(typeof neonChat.chat_history[id] == 'undefined')
  				{
  					var status = $this.data('status');
  					
  					if( ! status)
  					{
  						for(var i in neonChat.statuses)
  						{
  							if($status.hasClass(neonChat.statuses[i].class))
  							{
  								status = i;
  								break;
  							}
  						}
  					}
  					
  					neonChat.chat_history[id] = {
  						$el: $this,
  						messages: [],
  						unreads: 0,
  						status: status
  					};
  				}
  			});
  			
  		},
  		
  		pushMessage: function(id, msg, from, time, fromOpponent, unread)
  		{
  			if(id && msg)
  			{
  				this.refreshUserIds();
  				
  				var max_chat_history = this.getChatHistoryLength();
  				
  				if(this.chat_history[id].messages.length >= max_chat_history)
  				{
  					this.chat_history[id].messages = this.chat_history[id].messages.reverse().slice(0, max_chat_history - 1).reverse();
  				}
  				
  				this.chat_history[id].messages.push({
  					message: msg,
  					from: from,
  					time: time,
  					fromOpponent: fromOpponent,
  					unread: unread
  				});
  				
  				if(unread)
  				{
  					this.puffUnreadsAll();
  				}
  				
  				this.puffUnreads();
  			}
  		},
  		
  		renderMessages: function(id, slient)
  		{
  			if(typeof this.chat_history[id] != 'undefined')
  			{
  				$conversation_body.html('');
  				
  				for(var i in this.chat_history[id].messages)
  				{
  					var entry = this.chat_history[id].messages[i],
  						$entry = $('<li><span class="user"></span><p></p><span class="time"></span></li>'),
  						date = entry.time,
  						date_formated = date;
  					
  					if(typeof date == 'object')
  					{
  						var	hour = date.getHours(),
  							hour = (hour < 10 ? "0" : "") + hour,
  	
  							min  = date.getMinutes(),
  							min = (min < 10 ? "0" : "") + min,
  							
  							sec  = date.getSeconds();
  							sec = (sec < 10 ? "0" : "") + sec;
  						
  						date_formated = hour + ':' + min;
  					}
  					
  					
  					
  					
  					// Populate message DOM
  					$entry.find('.user').html(entry.from);
  					$entry.find('p').html(entry.message.replace(/\n/g, '<br>'));
  					$entry.find('.time').html(date_formated);
  					
  					if(entry.fromOpponent)
  					{
  						$entry.addClass('odd');
  					}
  					
  					if(entry.unread && typeof slient == 'undefined')
  					{
  						$entry.addClass('unread');
  						entry.unread = false;
  					}
  					
  					$conversation_body.append($entry);
  				}
  				
  				this.updateScrollbars();
  			}
  		},
  		
  		getStatus: function(id)
  		{
  			if(typeof id == 'object')
  			{
  				id = id.attr('id');
  			}
  				
  			var user = neonChat.chat_history[id];
  			
  			if(user)
  			{
  				return user.status;
  			}
  			
  			return null;
  		},
  		
  		setStatus: function(id, status)
  		{
  			var $user = typeof id == 'string' ? $('.chat-group a#'+id.replace('#', '')) : id;
  			
  			if($user.$el)
  			{
  				$user = $user.$el;
  			}
  			
  			if($user.length && this.statuses[status].class)
  			{
  				var $status = $user.find('.user-status');
  				
  				for(var i in this.statuses)
  				{
  					$status.removeClass(this.statuses[i].class);
  				}
  				
  				$status.addClass(this.statuses[status].class);
  				$user.data('status', status);
  				
  				neonChat.chat_history[ $user.attr('id') ].status = status;
  				this.orderGroups();
  			}
  		},
  		
  		orderGroups: function()
  		{
  			var $groups = $chat.find('.chat-group');
  			
  			if( ! $chat.data('order-by-status'))
  			{
  				return false;
  			}
  			
  			$groups.each(function(i, el)
  			{
  				var $group = $(el),
  					$contacts = $group.find('> a');
  				
  				$contacts.each(function(i, el)
  				{
  					var $contact = $(el),
  						$status = $contact.find('.user-status');
  					
  					for(var i in neonChat.statuses)
  					{
  						var status = neonChat.statuses[i];
  						
  						if(i == $contact.data('status'))
  						{
  							$contact.data('order-id', status.order);
  							return true;
  						}
  						else
  						if($status.hasClass(status.class))
  						{
  							$contact.data('order-id', status.order);
  							return true;
  						}
  					}
  				});
  				
  				var $new_order = $contacts.sort(function(a,b){
  					return parseInt($(a).data('order-id'), 10) > parseInt($(b).data('order-id'), 10);
  				}).appendTo($group);
  			});
  			
  			return true;
  		},
  		
  		prefetchMessages: function()
  		{
  			$chat.find('.chat-group a').each(function(i, el)
  			{
  				var $contact = $(el),
  					id = $contact.attr('id'),
  					history_container = $contact.data('conversation-history');
  				
  				if(history_container && history_container.length)
  				{
  					$($(history_container)).find('> li').each(function(j, el2)
  					{
  						var $entry = $(el2),
  							from = $entry.find('.user').html(),
  							message = $entry.find('p').html(),
  							time = $entry.find('.time').html(),
  							fromOpponent = $entry.hasClass('even') || $entry.hasClass('odd') || $entry.hasClass('opponent'),
  							unread = $entry.hasClass('unread');
  						
  						neonChat.pushMessage(id, message, from, time, fromOpponent, unread)
  					});
  				}
  				
  			});
  		},
  		
  		countUnreadMessages: function(id)
  		{
  			var counter = 0;
  			
  			if( ! id)
  			{
  				for(var id in neonChat.chat_history)
  				{
  					var user = neonChat.chat_history[id],
  						current_user_count = 0;
  					
  					for(var i in user.messages)
  					{
  						if(user.messages[i].unread)
  						{
  							counter++;
  							current_user_count++;
  						}
  					}
  					
  					user.unreads = current_user_count;
  				}
  			}
  			else
  			{
  				if(typeof id == 'object')
  				{
  					id = id.attr('id');
  				}
  					
  				var user = neonChat.chat_history[id];
  				
  				if(user)
  				{				
  					return user.unreads;
  				}
  			}
  			
  			return counter;
  		},
  		
  		puffUnreads: function()
  		{	
  			for(var i in this.chat_history)
  			{
  				var entry = neonChat.chat_history[i],
  					$badge = entry.$el.find('.badge');
  				
  				if(entry.unreads > 0)
  				{
  					$badge.html(entry.unreads).removeClass('is-hidden');
  				}
  				else
  				{
  					$badge.html(entry.unreads).addClass('is-hidden');
  				}
  			}
  		},
  		
  		puffUnreadsAll: function()
  		{
  			var total_unreads = this.countUnreadMessages();
  			
  			$chat_badge.html(total_unreads);
  			$chat_badge[total_unreads > 0 ? 'removeClass' : 'addClass']('is-hidden');
  		},
  		
  		resetUnreads: function(id)
  		{			
  			if(typeof id == 'object')
  			{
  				id = id.attr('id');
  			}
  				
  			var user = neonChat.chat_history[id];
  			
  			if(user)
  			{
  				user.unreads = 0;
  				user.$el.find('.badge').html('0').addClass('is-hidden');
  			}
  		},
  		
  		// Groups
  		createGroup: function(name, prepend)
  		{
  			var $group = $('<div class="chat-group"><strong>'+name+'</strong></div>');
  			
  			if(prepend)
  			{
  				$group.insertBefore( $chat.find('.chat-group:first') );
  			}
  			else
  			{
  				$group['appendTo']($chat);
  			}
  			
  			$group.hide().slideDown();
  			
  			$group = $group.uniqueId();
  			
  			return $group.attr('id');
  		},
  		
  		removeGroup: function(group_id, move_users_to_group)
  		{
  			var $group = $chat.find("#" + group_id.replace('#', '') + '.chat-group');
  			
  			if($group.length)
  			{
  				if(move_users_to_group)
  				{
  					var $group_2 = $chat.find("#" + move_users_to_group.replace('#', '') + '.chat-group');
  					
  					if($group_2.length)
  					{
  						$group.find('a').each(function(i, el)
  						{
  							var $user = $(el);
  							
  							$group_2.append($user);
  							
  							$user.hide().slideDown();
  						});
  					}
  					
  					this.orderGroups();
  				}
  				
  				$group.slideUp(function()
  				{
  					$group.remove();
  				});
  			}
  		},
  		
  		addUser: function(group_id, display_name, status, prepend, user_id)
  		{
  			var $group = group_id;
  			
  			if(typeof group_id == 'string')
  			{
  				$group = $chat.find("#" + group_id.replace('#', '') + '.chat-group');
  			}
  			
  			if($group && $group.length)
  			{
  				var status = this.statuses[status],
  					$user = $('<a href="#"><span class="user-status '+ status.class +'"></span> <em>'+ display_name +'</em> <span class="badge badge-info is-hidden>0</span></a>');
  				
  				if(user_id)
  				{
  					$user.attr('id', user_id);
  				}
  				
  				if(prepend)
  				{
  					$user.insertAfter( $group.find('> strong') );
  				}
  				else
  				{
  					$user['appendTo']($group);
  				}
  				
  				$user.hide().slideDown();
  				
  				this.refreshUserIds();
  				this.orderGroups();
  				
  				return $user.uniqueId().attr('id');
  			}
  			
  			return null;
  		},
  		
  		addUserId: function(group_id, user_id, display_name, status, prepend)
  		{
  			return this.addUser(group_id, display_name, status, prepend, user_id);
  		},
  		
  		getUser: function(id)
  		{
  			return this.chat_history[id] ? this.chat_history[id] : null;
  		},
  		
  		moveUser: function(user_id, new_group_id, prepend)
  		{
  			var $new_group = $chat.find("#" + new_group_id.replace('#', '') + '.chat-group'),
  				user = this.chat_history[user_id];
  			
  			
  			if($new_group.length && user)
  			{
  				if(prepend)
  				{
  					user.$el.insertAfter($new_group.find('> strong'));
  				}
  				else
  				{
  					user.$el['appendTo']($new_group);
  				}
  				
  				this.orderGroups();
  				
  				return true;
  			}
  			
  			return false;
  		},
  		
  		// Chat Container
  		showChat: function(animated)
  		{
  			var visible_class = 'chat-visible';
  			
  			if(isxs())
  			{
  				visible_class += ' toggle-click';
  			}
  			
  			if(animated)
  			{			
  				if($chat.data('is-busy'))
  				{
  					return false;
  				}
  			
  				$chat.data('is-busy', true);
  				
  				public_vars.$pageContainer.addClass(visible_class);
  				
  				var mc_padding_right = parseInt(public_vars.$mainContent.css('padding-right'), 10),
  					mc_padding_left = parseInt(public_vars.$mainContent.css('padding-left'), 10),
  					chat_width = $chat.width();
  				
  				public_vars.$pageContainer.removeClass(visible_class);
  				
  				if(public_vars.$pageContainer.hasClass('right-sidebar'))
  				{
  					public_vars.$mainContent.transition({
  						paddingLeft: mc_padding_left,
  						duration: 500
  					});
  				}
  				else
  				{
  					public_vars.$mainContent.transition({
  						paddingRight: mc_padding_right,
  						duration: 500
  					});
  				}
  				
  				$chat.show();
  				TweenMax.set($chat, {css: {autoAlpha: public_vars.$body.hasClass('boxed-layout') ? 0 : 1, transform: "translateX("+((public_vars.$pageContainer.hasClass('right-sidebar') ? -1 : 1) * chat_width)+"px)"}});
  				
  				TweenMax.to($chat, .65, {css: {autoAlpha: 1, transform: "translateX(0)"}, ease: Sine.easeOut, onComplete: function()
  				{
  					public_vars.$pageContainer.addClass(visible_class);
  					public_vars.$mainContent.attr('style', '');
  					
  					TweenMax.set($chat, {css: {transform: '', paddingRight: '', paddingLeft: ''}});
  					
  					$chat.data('is-busy', false);
  				}});
  			}
  			else
  			{
  				public_vars.$pageContainer.addClass(visible_class);
  			}
  		},
  		
  		hideChat: function(animated)
  		{
  			var visible_class = 'chat-visible';
  			
  			
  			if(isxs())
  			{
  				visible_class += ' toggle-click';
  			}
  			
  			if(animated)
  			{			
  				if($chat.data('is-busy'))
  				{
  					return false;
  				}
  				
  				$chat.data('is-busy', true);
  			
  				disableXOverflow();
  				
  				public_vars.$pageContainer.removeClass(visible_class);
  				
  				var mc_padding_right = parseInt(public_vars.$mainContent.css('padding-right'), 10),
  					mc_padding_left = parseInt(public_vars.$mainContent.css('padding-left'), 10),
  					chat_width = $chat.width();
  					
  				public_vars.$pageContainer.addClass(visible_class);
  				
  				// Close any opened conversation
  				neonChat.close();
  				
  				TweenMax.to($chat, .4, {css: {autoAlpha: (public_vars.$body.hasClass('boxed-layout') ? 0 : 1), transform: "translateX("+ ((public_vars.$pageContainer.hasClass('right-sidebar') ? -1 : 1) * chat_width) +"px)"}, ease: Sine.easeIn});
  				
  				var opts = {
  					paddingRight: mc_padding_right,
  					duration: 700,
  					complete: function()
  					{
  						public_vars.$pageContainer.attr('style', '');	
  						public_vars.$mainContent.attr('style', '');
  						$chat.attr('style', '');
  						
  						public_vars.$pageContainer.removeClass(visible_class);
  						enableXOverflow();
  						$chat.data('is-busy', false);
  					}
  				};
  				
  				if(public_vars.$pageContainer.hasClass('right-sidebar'))
  				{
  					delete opts.paddingRight;
  					opts.paddingLeft = mc_padding_left;
  				}
  				
  				public_vars.$mainContent.transition(opts);
  			}
  			else
  			{
  				public_vars.$pageContainer.removeClass(visible_class);
  			}
  		},
  		
  		toggleChat: function(animated, collapse_sidebar)
  		{
  			var _func = public_vars.$pageContainer.hasClass('chat-visible') ? 'hideChat' : 'showChat';
  			
  			if(isxs())
  			{
  				_func = public_vars.$pageContainer.hasClass('toggle-click') ? 'hideChat' : 'showChat';
  			}
  			
  			neonChat[_func](animated);
  			
  			if(collapse_sidebar)
  			{
  				if(sidebar_default_is_open)
  				{
  					if(_func == 'hideChat') // Hide Sidebar
  					{
  						show_sidebar_menu(animated);
  					}
  					else
  					{
  						hide_sidebar_menu(animated);
  					}
  				}
  			}
  		}
  	});
  	
  	
  	// Set Cursor
  	$conversation_body.on('click', function()
  	{
  		$textarea.focus();
  	});
  	
  	
  	// Refresh Ids
  	neonChat.init();
  	
  })(jQuery, window);