context: using System;
  using System.Diagnostics.CodeAnalysis;
  using System.Drawing;
  using System.Security.Permissions;
  using System.Windows.Forms;
  using WeifenLuo.WinFormsUI.Docking.Win32;
  
  namespace WeifenLuo.WinFormsUI.Docking
  {
      public class FloatWindow : Form, INestedPanesContainer, IDockDragSource
      {
          internal const int WM_CHECKDISPOSE = (int) (Msgs.WM_USER + 1);
          private bool m_allowEndUserDocking = true;
          private DockPanel m_dockPanel;
          private bool m_doubleClickTitleBarToDock = true;
          private NestedPaneCollection m_nestedPanes;
  
          protected internal FloatWindow(DockPanel dockPanel, DockPane pane)
          {
              InternalConstruct(dockPanel, pane, false, Rectangle.Empty);
          }
  
          protected internal FloatWindow(DockPanel dockPanel, DockPane pane, Rectangle bounds)
          {
              InternalConstruct(dockPanel, pane, true, bounds);
          }
  
          public bool AllowEndUserDocking
          {
              get { return m_allowEndUserDocking; }
              set { m_allowEndUserDocking = value; }
          }
  
          public bool DoubleClickTitleBarToDock
          {
              get { return m_doubleClickTitleBarToDock; }
              set { m_doubleClickTitleBarToDock = value; }
          }
  
          public DockPanel DockPanel
          {
              get { return m_dockPanel; }
          }
  
          public NestedPaneCollection NestedPanes
          {
              get { return m_nestedPanes; }
          }
  
          public VisibleNestedPaneCollection VisibleNestedPanes
          {
              get { return NestedPanes.VisibleNestedPanes; }
          }
  
          public DockState DockState
          {
              get { return DockState.Float; }
          }
  
          public bool IsFloat
          {
              get { return DockState == DockState.Float; }
          }
  
          public virtual Rectangle DisplayingRectangle
          {
              get { return ClientRectangle; }
          }
  
          private void InternalConstruct(DockPanel dockPanel, DockPane pane, bool boundsSpecified, Rectangle bounds)
          {
              if (dockPanel == null)
                  throw (new ArgumentNullException(Strings.FloatWindow_Constructor_NullDockPanel));
  
              m_nestedPanes = new NestedPaneCollection(this);
  
              FormBorderStyle = FormBorderStyle.SizableToolWindow;
              ShowInTaskbar = false;
              if (dockPanel.RightToLeft != RightToLeft)
                  RightToLeft = dockPanel.RightToLeft;
              if (RightToLeftLayout != dockPanel.RightToLeftLayout)
                  RightToLeftLayout = dockPanel.RightToLeftLayout;
  
              SuspendLayout();
              if (boundsSpecified)
              {
                  Bounds = bounds;
                  StartPosition = FormStartPosition.Manual;
              }
              else
              {
                  StartPosition = FormStartPosition.WindowsDefaultLocation;
                  Size = dockPanel.DefaultFloatWindowSize;
              }
  
              m_dockPanel = dockPanel;
              Owner = DockPanel.FindForm();
              DockPanel.AddFloatWindow(this);
              if (pane != null)
                  pane.FloatWindow = this;
  
              ResumeLayout();
          }
  
          protected override void Dispose(bool disposing)
          {
              if (disposing)
              {
                  if (DockPanel != null)
                      DockPanel.RemoveFloatWindow(this);
                  m_dockPanel = null;
              }
              base.Dispose(disposing);
          }
  
          internal bool IsDockStateValid(DockState dockState)
          {
              foreach (DockPane pane in NestedPanes)
                  foreach (IDockContent content in pane.Contents)
                      if (!DockHelper.IsDockStateValid(dockState, content.DockHandler.DockAreas))
                          return false;
  
              return true;
          }
  
          protected override void OnActivated(EventArgs e)
          {
              DockPanel.FloatWindows.BringWindowToFront(this);
              base.OnActivated(e);
              // Propagate the Activated event to the visible panes content objects
              foreach (DockPane pane in VisibleNestedPanes)
                  foreach (IDockContent content in pane.Contents)
                      content.OnActivated(e);
          }
  
          protected override void OnDeactivate(EventArgs e)
          {
              base.OnDeactivate(e);
              // Propagate the Deactivate event to the visible panes content objects
              foreach (DockPane pane in VisibleNestedPanes)
                  foreach (IDockContent content in pane.Contents)
                      content.OnDeactivate(e);
          }
  
          protected override void OnLayout(LayoutEventArgs levent)
          {
              VisibleNestedPanes.Refresh();
              RefreshChanges();
              Visible = (VisibleNestedPanes.Count > 0);
              SetText();
  
              base.OnLayout(levent);
          }
  
          [SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters",
              MessageId = "System.Windows.Forms.Control.set_Text(System.String)")]
          internal void SetText()
          {
              DockPane theOnlyPane = (VisibleNestedPanes.Count == 1) ? VisibleNestedPanes[0] : null;
  
              if (theOnlyPane == null || theOnlyPane.ActiveContent == null)
              {
                  Text = " ";
                  // use " " instead of string.Empty because the whole title bar will disappear when ControlBox is set to false.
                  Icon = null;
              }
              else
              {
                  Text = theOnlyPane.ActiveContent.DockHandler.TabText;
                  Icon = theOnlyPane.ActiveContent.DockHandler.Icon;
              }
          }
  
          protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
          {
              Rectangle rectWorkArea = SystemInformation.VirtualScreen;
  
              if (y + height > rectWorkArea.Bottom)
                  y -= (y + height) - rectWorkArea.Bottom;
  
              if (y < rectWorkArea.Top)
                  y += rectWorkArea.Top - y;
  
              base.SetBoundsCore(x, y, width, height, specified);
          }
  
          [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
          protected override void WndProc(ref Message m)
          {
              switch (m.Msg)
              {
                  case (int) Msgs.WM_NCLBUTTONDOWN:
                  {
                      if (IsDisposed)
                          return;
  
                      uint result = Win32Helper.IsRunningOnMono
                          ? 0
                          : NativeMethods.SendMessage(Handle, (int) Msgs.WM_NCHITTEST, 0, (uint) m.LParam);
                      if (result == 2 && DockPanel.AllowEndUserDocking && AllowEndUserDocking) // HITTEST_CAPTION
                      {
                          Activate();
                          m_dockPanel.BeginDrag(this);
                      }
                      else
                          base.WndProc(ref m);
  
                      return;
                  }
                  case (int) Msgs.WM_NCRBUTTONDOWN:
                  {
                      uint result = Win32Helper.IsRunningOnMono
                          ? 0
                          : NativeMethods.SendMessage(Handle, (int) Msgs.WM_NCHITTEST, 0, (uint) m.LParam);
  
gt:                     if (result == 2) // HITTEST_CAPTION