context: namespace StockSharp.Studio.Controls
  {
  	using System;
  	using System.Linq;
  	using System.Windows;
  	using System.Windows.Controls;
  	using System.Windows.Input;
  	using System.Runtime.InteropServices;
  
  	using Ecng.ComponentModel;
  	using Ecng.Configuration;
  	using Ecng.Collections;
  	using Ecng.Common;
  	using Ecng.Xaml;
  
  	using StockSharp.Community;
  	using StockSharp.Studio.Core.Commands;
  	using StockSharp.Localization;
  
  	[DisplayNameLoc(LocalizedStrings.Str3205Key)]
  	[DescriptionLoc(LocalizedStrings.Str3206Key)]
  	[Icon("Images/chat_24x24.png")]
  	[Guid("82C59D8C-D3F8-4294-97E8-B1F4BFD27EB0")]
  	public partial class ChatPanel
  	{
  		public static RoutedCommand CreateRoomCommand = new RoutedCommand();
  		public static RoutedCommand DeleteRoomCommand = new RoutedCommand();
  		public static RoutedCommand JoinRoomCommand = new RoutedCommand();
  		public static RoutedCommand LeaveRoomCommand = new RoutedCommand();
  		public static RoutedCommand SendMessageCommand = new RoutedCommand();
  		public static RoutedCommand AcceptJoinCommand = new RoutedCommand();
  		public static RoutedCommand RejectJoinCommand = new RoutedCommand();
  
  		private readonly ThreadSafeObservableCollection<RoomItem> _chatRooms;
  
  		public event Action<bool> UnreadMessages;
  
  		private RoomItem SelectedRoom
  		{
  			get { return ChatRoomsTree == null ? null : ChatRoomsTree.SelectedItem as RoomItem; }
  		}
  
  		public ChatPanel()
  		{
  			InitializeComponent();
  
  			var context = new ObservableCollectionEx<RoomItem>();
  			ChatRoomsTree.DataContext = context;
  
  			_chatRooms = new ThreadSafeObservableCollection<RoomItem>(context);
  
  			WhenLoaded(ChatControl_OnLoaded);
  		}
  
  		private static ChatClient Client
  		{
  			get { return ConfigManager.GetService<ChatClient>(); }
  		}
  
  		private void ChatControl_OnLoaded()
  		{
  			var client = Client;
  
  			client.AuthorAdded += OnAuthorAdded;
  			client.AuthorDeleted += OnAuthorDeleted;
  			client.JoinAccepted += OnJoinAccepted;
  			client.JoinRejected += OnJoinRejected;
  			client.JoinSended += OnJoinSended;
  			client.LoggedIn += OnLoggedIn;
  			client.LoggedOut += OnLoggedOut;
  			client.MessageCreated += OnMessageCreated;
  			client.MessageUpdated += OnMessageUpdated;
  			client.MessageDeleted += OnMessageDeleted;
  			client.RoomCreated += OnRoomCreated;
  			client.RoomDeleted += OnRoomDeleted;
  			client.RoomUpdated += OnRoomUpdated;
  
  			var cmdSvc = ConfigManager.GetService<IStudioCommandService>();
  
  			cmdSvc.Register<LoggedInCommand>(this, false, cmd =>
  			{
  				IsEnabled = true;
  
  				var rooms = _chatRooms.ToDictionary(i => i.Room, i => i);
  
  				foreach (var room in client.AllRooms)
  				{
  					var item = rooms.TryGetValue(room);
  
  					if (item != null)
  					{
  						rooms.Remove(room);
  						continue;
  					}
  					
  					item = new RoomItem(room);
  					item.Users.AddRange(client.GetAuthors(room));
  					_chatRooms.Add(item);
  				}
  
  				_chatRooms.RemoveRange(rooms.Values);
  				UpdateTitle();
  			});
  			cmdSvc.Register<LoggedOutCommand>(this, false, cmd =>
  			{
  				IsEnabled = false;
  				UpdateTitle();
  			});
  
  			IsEnabled = ConfigManager.GetService<AuthenticationClient>().IsLoggedIn;
  			UpdateTitle();
  
  			if (IsEnabled)
  				return;
  
  			var res = new MessageBoxBuilder()
  					.Owner(this)
  					.Text(LocalizedStrings.Str3207)
  					.Warning()
  					.YesNo()
  					.Show();
  
  			if (res == MessageBoxResult.Yes)
  				cmdSvc.Process(this, new LogInCommand());
  		}
  
  		#region Chat
  
  		private void OnRoomUpdated(ChatRoom room)
  		{
  		}
  
  		private void OnRoomDeleted(ChatRoom room)
  		{
  			_chatRooms.RemoveWhere(r => r.Room == room);
  		}
  
  		private void OnRoomCreated(ChatRoom room)
  		{
  			var item = new RoomItem(room);
  
  			item.Users.AddRange(Client.GetAuthors(room));
  
  			_chatRooms.Add(item);
  		}
  
  		private void OnMessageCreated(ChatMessage message)
  		{
  			var item = _chatRooms.FirstOrDefault(r => r.Room.Id == message.RoomId);
  
  			if (item == null)
  				return;
  
  			item.Messages.Add(message);
  
  			GuiDispatcher.GlobalDispatcher.AddAction(() =>
  			{
  				if (item != SelectedRoom)
  				{
  					item.HasNewItems = true;
  					UnreadMessages.SafeInvoke(true);
  				}
  				else
  				{
  					var scroll = Messages.FindVisualChild<ScrollViewer>();
  					if (scroll != null)
  						scroll.ScrollToEnd();
  				}
  			});
  		}
  
  		private void OnMessageUpdated(ChatMessage message)
  		{
  			
  		}
  
  		private void OnMessageDeleted(ChatMessage message)
  		{
  			
  		}
  
  		private void OnLoggedOut(User user)
  		{
  		}
  
  		private void OnLoggedIn(User user)
  		{
  		}
  
  		private void OnJoinSended(ChatJoin join)
  		{
  			var item = _chatRooms.FirstOrDefault(r => r.Room.Id == join.RoomId);
  
  			if (item == null)
  				return;
  
  			item.Messages.Add(join);
  		}
  
  		private void OnJoinRejected(ChatJoin request, ChatJoin response)
  		{
  			var item = _chatRooms.FirstOrDefault(r => r.Room.Id == response.RoomId);
  
  			if (item == null)
  				return;
  
  			item.Messages.Add(response);
  		}
  
  		private void OnJoinAccepted(ChatJoin join)
  		{
  			var item = _chatRooms.FirstOrDefault(r => r.Room.Id == join.RoomId);
  
  			if (item == null)
  				return;
  
  			item.Messages.Add(join);
  		}
  
  		private void OnAuthorDeleted(User author, ChatRoom room, User by)
  		{
  			var chatRoom = _chatRooms.First(r => r.Room == room);
  
  			chatRoom
  				.Users
  				.Remove(author);
  
  			chatRoom.Messages.Add(new ChatMessage
  			{
  				Body = LocalizedStrings.Str3208Params.Put(author.Name),
  				CreationDate = TimeHelper.Now,
  			});
  		}
  
  		private void OnAuthorAdded(User author, ChatRoom room, User by)
  		{
  			var chatRoom = _chatRooms.First(r => r.Room == room);
  
  			chatRoom
  				.Users
  				.Add(author);
  
  			chatRoom.Messages.Add(new ChatMessage
  			{
  				Body = LocalizedStrings.Str3209Params.Put(author.Name),
  				CreationDate = TimeHelper.Now,
  			});
  		}
  
  		#endregion
  
  		public override void Dispose()
  		{
  			var cmdSvc = ConfigManager.GetService<IStudioCommandService>();
  
  			cmdSvc.UnRegister<LoggedInCommand>(this);
  			cmdSvc.UnRegister<LoggedOutCommand>(this);
  
  			var client = Client;
  
  			client.AuthorAdded -= OnAuthorAdded;
  
gt: 			client.AuthorDeleted -= OnAuthorDeleted;