context: /* --------------------------------------------------------------------------
   * Copyrights
   *
   * Portions created by or assigned to Cursive Systems, Inc. are
   * Copyright (c) 2002-2008 Cursive Systems, Inc.  All Rights Reserved.  Contact
   * information for Cursive Systems, Inc. is available at
   * http://www.cursive.net/.
   *
   * License
   *
   * Jabber-Net is licensed under the LGPL.
   * See LICENSE.txt for details.
   * --------------------------------------------------------------------------*/
  using System;
  using System.Collections;
  using System.ComponentModel;
  using System.ComponentModel.Design;
  using System.Drawing;
  using System.Text;
  using System.Windows.Forms;
  using System.Xml;
  
  using bedrock.util;
  using jabber.connection;
  
  namespace muzzle
  {
      /// <summary>
      /// Base class for forms that configure XmppStream subclasses.
      /// </summary>
      [SVN(@"$Id: OptionForm.cs 724 2008-08-06 18:09:25Z hildjj $")]
      public class OptionForm : Form
      {
          private Button btnCancel;
          private Button btnOK;
          private Panel panel1;
  
          private XmppStream m_xmpp;
          private Hashtable m_extra = new Hashtable();
  
          /// <summary>
          /// ToolTips.
          /// </summary>
          protected ToolTip tip;
          /// <summary>
          /// Error notifications.
          /// </summary>
          protected ErrorProvider error;
          private IContainer components;
  
          /// <summary>
          /// Create new form
          /// </summary>
          protected OptionForm()
          {
              InitializeComponent();
  			this.AutoValidate = System.Windows.Forms.AutoValidate.Disable;
          }
  
          /// <summary>
          /// Create new form.
          /// </summary>
          /// <param name="xmpp"></param>
          protected OptionForm(XmppStream xmpp)
              : this()
          {
              m_xmpp = xmpp;
          }
  
  
          /// <summary>
          /// The client connection to manage
          /// </summary>
          public XmppStream Xmpp
          {
              get
              {
                  // If we are running in the designer, let's try to auto-hook a JabberClient
                  if ((m_xmpp == null) && DesignMode)
                  {
                      IDesignerHost host = (IDesignerHost)base.GetService(typeof(IDesignerHost));
                      if (host == null)
                          return null;
                      m_xmpp = StreamComponent.GetStreamFromHost(host);
                  }
                  return m_xmpp;
              }
              set
              {
                  m_xmpp = value;
                  if (!DesignMode)
                      ReadXmpp();
              }
          }
  
          private void WriteValues(Control parent, XmppStream stream)
          {
              if (parent.Tag != null)
              {
                  stream[(string)parent.Tag] = GetControlValue(parent);
              }
              if (parent.HasChildren)
              {
                  foreach (Control child in parent.Controls)
                  {
                      WriteValues(child, stream);
                  }
              }
          }
  
          /// <summary>
          /// Write to the XmppStream the current values.
          /// </summary>
          protected void WriteXmpp()
          {
              if (m_xmpp != null)
                  WriteValues(this, m_xmpp);
          }
  
          /// <summary>
          /// Write the configuration values to the given XmppStream.
          /// </summary>
          /// <param name="stream">The stream to configure</param>
          public void Configure(XmppStream stream)
          {
              WriteValues(this, stream);
          }
  
          private void WriteElem(XmlElement root, Control c)
          {
              if (c.Tag != null)
              {
                  root.AppendChild(root.OwnerDocument.CreateElement((string)c.Tag)).InnerText =
                      GetControlValue(c).ToString();
              }
              if (c.HasChildren)
              {
                  foreach (Control child in c.Controls)
                  {
                      WriteElem(root, child);
                  }
              }
          }
  
          /// <summary>
          /// Write the current connection properties to an XML config file.
          /// TODO: Replace this with a better ConfigFile implementation that can write.
          /// </summary>
          /// <param name="file"></param>
          public void WriteToFile(string file)
          {
              XmlDocument doc = new XmlDocument();
              string name = "JabberClient";
              if (m_xmpp != null)
                  name = m_xmpp.GetType().Name;
              XmlElement root = (XmlElement)doc.CreateElement(name);
              doc.AppendChild(root);
  
              WriteElem(root, this);
  
              foreach (DictionaryEntry ent in m_extra)
              {
                  root.AppendChild(doc.CreateElement((string)ent.Key)).InnerText = ent.Value.ToString();
              }
  
              XmlTextWriter xw = new XmlTextWriter(file, System.Text.Encoding.UTF8);
              xw.Formatting = Formatting.Indented;
              doc.WriteContentTo(xw);
              xw.Close();
          }
  
          private void ReadControls(Control parent)
          {
              if (parent == null)
                  return;
              if (m_xmpp == null)
                  return;
  
              if (parent.Tag != null)
                  SetControlValue(parent, m_xmpp[(string)parent.Tag]);
              if (parent.HasChildren)
              {
                  foreach (Control child in parent.Controls)
                  {
                      ReadControls(child);
                  }
              }
          }
  
          /// <summary>
          /// Read current values from the XmppStream
          /// </summary>
          protected void ReadXmpp()
          {
              ReadControls(this);
          }
  
          /// <summary>
          /// Read connection properties from the given file,
          /// pop up the dialog to see if the user wants to change them,
          /// save the changes, and
          /// connect to the server.
          /// </summary>
          /// <param name="propertyFile">The name of the file to store connection information in.</param>
          /// <returns>True if the user hit OK, otherwise false</returns>
          public bool Login(string propertyFile)
          {
              if (this.Xmpp == null)
                  throw new ArgumentNullException("Client must be set", "Xmpp");
              if (propertyFile != null)
                  ReadFromFile(propertyFile);
              if (ShowDialog() != DialogResult.OK)
                  return false;
              if (propertyFile != null)
                  WriteToFile(propertyFile);
              this.Xmpp.Connect();
              return true;
          }
  
          /// <summary>
          /// Set the connection properties from an XML config file.
          /// TODO: Replace this with a better ConfigFile implementation that can write.
          /// </summary>
          /// <param name="file"></param>
          public void ReadFromFile(string file)
          {
              XmlDocument doc = new XmlDocument();
              try
              {
                  doc.Load(file);
              }
              catch (XmlException)
              {
                  return;
              }
              catch (System.IO.FileNotFoundException)
              {
                  return;
              }
  
              XmlElement root = doc.DocumentElement;
              if (root == null)
                  return;
              foreach (XmlNode node in root.ChildNodes)
              {
                  XmlElement elem = node as XmlElement;
  
gt:                 if (elem == null)