context: /*
   * Smuxi - Smart MUltipleXed Irc
   *
   * Copyright (c) 2005-2006, 2009-2013 Mirco Bauer <meebey@meebey.net>
   *
   * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
   */
  
  using System;
  using System.IO;
  using System.Net;
  using System.Net.Security;
  using System.Web;
  using System.Linq;
  using System.Text.RegularExpressions;
  using System.Security.Cryptography.X509Certificates;
  using System.Threading;
  using System.Collections.Generic;
  using SysPath = System.IO.Path;
  using Smuxi.Engine;
  using Smuxi.Common;
  
  namespace Smuxi.Frontend.Gnome
  {
      [ChatViewInfo(ChatType = ChatType.Protocol)]
      public class ProtocolChatView : ChatView
      {
  #if LOG4NET
          private static readonly log4net.ILog f_Logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
  #endif
          public static Gdk.Pixbuf IconPixbuf { get; private set; }
          static Dictionary<string, string> NetworkWebsiteUrls { get; set; }
          ProxySettings ProxySettings { get; set; }
          Gdk.Pixbuf ServerIconPixbuf { get; set; }
          public string Host { get; private set; }
          public int Port { get; private set; }
          public string NetworkID { get; private set; }
          Gtk.ImageMenuItem  ReconnectItem { get; set; }
  
          protected override Gtk.Image DefaultTabImage {
              get {
                  var icon = IconPixbuf;
                  if (ServerIconPixbuf != null) {
                      icon = ServerIconPixbuf;
                  }
                  return new Gtk.Image(icon);
              }
          }
  
          static ProtocolChatView()
          {
              IconPixbuf = Frontend.LoadIcon(
                  "smuxi-protocol-chat", 16, "protocol-chat_256x256.png"
              );
              NetworkWebsiteUrls = new Dictionary<string, string>(
                  StringComparer.InvariantCultureIgnoreCase
              );
  
              // IRC
              NetworkWebsiteUrls.Add("OFTC", "http://www.oftc.net/");
              NetworkWebsiteUrls.Add("freenode", "http://freenode.net/");
              NetworkWebsiteUrls.Add("QuakeNet", "http://www.quakenet.org/");
              NetworkWebsiteUrls.Add("IRCnet", "http://www.ircnet.org/");
              NetworkWebsiteUrls.Add("DALnet", "http://www.dal.net/");
              NetworkWebsiteUrls.Add("GameSurge", "https://gamesurge.net/");
              NetworkWebsiteUrls.Add("EFnet", "http://www.efnet.org/");
              NetworkWebsiteUrls.Add("GIMPnet", "http://www.gimp.org/");
              NetworkWebsiteUrls.Add("GSDnet", "http://www.gsd-software.net/");
              NetworkWebsiteUrls.Add("ustream", "http://www.ustream.tv/");
              NetworkWebsiteUrls.Add("Infinity-IRC", "http://www.infinityirc.com/");
              NetworkWebsiteUrls.Add("GeekShed", "http://www.geekshed.net/");
  
              // Twitter
              NetworkWebsiteUrls.Add("Twitter", "http://www.twitter.com/");
  
              // XMPP - with federation
              NetworkWebsiteUrls.Add("XMPP", "http://xmpp.org/");
              NetworkWebsiteUrls.Add("jabber.org", "http://planet.jabber.org/");
              NetworkWebsiteUrls.Add("jabber.de", "http://www.jabber.de/");
              NetworkWebsiteUrls.Add("jabber.at", "http://planet.jabber.org/");
              NetworkWebsiteUrls.Add("jabber.ccc.de", "http://web.jabber.ccc.de/");
              NetworkWebsiteUrls.Add("xmpp-gmx.gmx.net", "http://planet.jabber.org/");
              NetworkWebsiteUrls.Add("xmpp-webde.gmx.net", "http://planet.jabber.org/");
              NetworkWebsiteUrls.Add("jabber.gmx.net", "http://planet.jabber.org/");
              // XMPP - without federation
              NetworkWebsiteUrls.Add("talk.google.com", "http://www.google.com/talk/");
              NetworkWebsiteUrls.Add("chat.facebook.com", "http://www.facebook.com/");
  
              // JabbR
              NetworkWebsiteUrls.Add("jabbr.net", "http://jabbr.net/");
  
              // Campfire
              NetworkWebsiteUrls.Add("Campfire", "http://campfirenow.com");
  
              // support downloading favicons via https
              var whitelist = Session.CertificateValidator.HostnameWhitelist;
              lock (whitelist) {
                  foreach (var url in NetworkWebsiteUrls.Values) {
                      var uri = new Uri(url);
                      var hostname = uri.Host;
                      if (whitelist.Contains(hostname)) {
                          continue;
                      }
                      whitelist.Add(hostname);
                  }
              }
          }
  
          public ProtocolChatView(ChatModel chat) : base(chat)
          {
              Trace.Call(chat);
              
              ProxySettings = new ProxySettings();
  
              Add(OutputScrolledWindow);
  
              ReconnectItem = new Gtk.ImageMenuItem(_("Reconnect"));
              ReconnectItem.Image = new Gtk.Image(Gtk.Stock.Refresh, Gtk.IconSize.Menu);
              ReconnectItem.Activated += new EventHandler(OnTabMenuReconnectActivated);
              TabMenu.Prepend(ReconnectItem);
              TabMenu.ShowAll();
  
              ShowAll();
          }
  
          public override void Sync()
          {
              Trace.Call();
  
              base.Sync();
  
              Host = ProtocolManager.Host;
              Port = ProtocolManager.Port;
              NetworkID = ProtocolManager.NetworkID;
  
              try {
                  CheckIcon();
              } catch (Exception ex) {
  #if LOG4NET
                  f_Logger.Error("Sync(): CheckIcon() threw exception!", ex);
  #endif
              }
          }
  
          public override void Close()
          {
              Trace.Call();
              
              // show warning if there are open chats (besides protocol chat)
              var ownedChats = 0;
              foreach (var chatView in Frontend.MainWindow.ChatViewManager.Chats) {
                  if (chatView.ProtocolManager == ProtocolManager) {
                      ownedChats++;
                  }
              }
              if (ownedChats > 1) {
                  Gtk.MessageDialog md = new Gtk.MessageDialog(
                      Frontend.MainWindow,
                      Gtk.DialogFlags.Modal,
                      Gtk.MessageType.Warning,
                      Gtk.ButtonsType.YesNo,
                      _("Closing the protocol chat will also close all open chats connected to it!\n"+
                        "Are you sure you want to do this?"));
                  int result = md.Run();
                  md.Destroy();
                  if ((Gtk.ResponseType) result != Gtk.ResponseType.Yes) {
                      return;
                  }
              }
  
              ThreadPool.QueueUserWorkItem(delegate {
                  try {
                      // no need to call base.Close() as CommandNetwork() will
                      // deal with it
                      Frontend.Session.CommandNetwork(
                          new CommandModel(
                              Frontend.FrontendManager,
                              ChatModel,
                              "close"
                          )
                      );
                  } catch (Exception ex) {
                      Frontend.ShowException(ex);
                  }
              });
          }
  
          public override void ApplyConfig(UserConfig config)
          {
              Trace.Call(config);
  
              if (config == null) {
                  throw new ArgumentNullException("config");
              }
  
              base.ApplyConfig(config);
  
              ProxySettings.ApplyConfig(config);
          }
  
          void CheckIcon()
          {
              Trace.Call();
  
              var cachePath = Platform.CachePath;
              var iconPath = SysPath.Combine(cachePath, "server-icons");
              // REMOTING CALL
              var protocol = ProtocolManager.Protocol;
              iconPath = SysPath.Combine(iconPath, protocol);
              if (!Directory.Exists(iconPath)) {
                  Directory.CreateDirectory(iconPath);
              }
              iconPath = SysPath.Combine(iconPath,
                                         String.Format("{0}.ico", ID));
              var iconFile = new FileInfo(iconPath);
              if (iconFile.Exists && iconFile.Length > 0) {
                  // cached icon, use right away
                  UpdateServerIcon(iconPath);
              }
  
              string websiteUrl = null;
  
gt:             lock (NetworkWebsiteUrls) {