using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using TD.SandDock.Rendering;

namespace TD.SandDock
{
	[DefaultEvent("Closing")]
	[ToolboxItem(false)]
	[Designer(typeof(DockControlDesigner))]
	public class DockControl : ContainerControl
	{
		public event CancelEventHandler Closing
		{
			[MethodImpl(MethodImplOptions.Synchronized)]
			add
			{
				this.v = (CancelEventHandler)Delegate.Combine(this.v, value);
			}
			[MethodImpl(MethodImplOptions.Synchronized)]
			remove
			{
				this.v = (CancelEventHandler)Delegate.Remove(this.v, value);
			}
		}

		public event EventHandler Closed
		{
			[MethodImpl(MethodImplOptions.Synchronized)]
			add
			{
				this.w = (EventHandler)Delegate.Combine(this.w, value);
			}
			[MethodImpl(MethodImplOptions.Synchronized)]
			remove
			{
				this.w = (EventHandler)Delegate.Remove(this.w, value);
			}
		}

		public event EventHandler BeforeFirstShown
		{
			[MethodImpl(MethodImplOptions.Synchronized)]
			add
			{
				this.x = (EventHandler)Delegate.Combine(this.x, value);
			}
			[MethodImpl(MethodImplOptions.Synchronized)]
			remove
			{
				this.x = (EventHandler)Delegate.Remove(this.x, value);
			}
		}

		public DockControl()
		{
			if (DockControl.d == null)
			{
				DockControl.d = Image.FromStream(typeof(DockControl).Assembly.GetManifestResourceStream("TD.SandDock.sanddock.png"));
			}
			base.SetStyle(ControlStyles.ResizeRedraw, true);
			base.SetStyle(ControlStyles.DoubleBuffer, true);
			base.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
			base.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
		}

		protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
		{
			if (this.b != null)
			{
				if (keyData == (Keys.LButton | Keys.Space | Keys.Control))
				{
					int num = this.b.Controls.IndexOf(this);
					num--;
					if (num < 0)
					{
						num = this.b.Controls.Count - 1;
					}
					this.b.Controls[num].Open();
					this.b.Controls[num].Activate();
					return true;
				}
				if (keyData == (Keys.RButton | Keys.Space | Keys.Control))
				{
					int num2 = this.b.Controls.IndexOf(this);
					num2++;
					if (num2 >= this.b.Controls.Count)
					{
						num2 = 0;
					}
					this.b.Controls[num2].Open();
					this.b.Controls[num2].Activate();
					return true;
				}
				if (keyData == (Keys.LButton | Keys.MButton | Keys.Back | Keys.ShiftKey | Keys.Space | Keys.F17 | Keys.Alt) && this.b.IsInContainer)
				{
					this.b.DockContainer.OnShowControlContextMenu(new ShowControlContextMenuEventArgs(this, new Point(0, 0)));
					return true;
				}
				if (keyData == Keys.Escape && this.Manager != null && this.IsFloating && this.Manager.OwnerForm != null)
				{
					this.Manager.OwnerForm.Activate();
					return true;
				}
			}
			return base.ProcessCmdKey(ref msg, keyData);
		}

		internal int LastIndexInFixedLayoutSystem
		{
			get
			{
				return this.u;
			}
			set
			{
				this.u = value;
			}
		}

		public DockControl(Control control, string text) : this()
		{
			base.Controls.Add(control);
			control.Dock = DockStyle.Fill;
			this.Text = text;
		}

		public static DockControl FromForm(Form form)
		{
			DockControl dockControl = new DockControl();
			form.Visible = false;
			form.TopLevel = false;
			form.FormBorderStyle = FormBorderStyle.None;
			dockControl.Controls.Add(form);
			dockControl.Text = form.Text;
			form.Dock = DockStyle.Fill;
			form.Visible = true;
			return dockControl;
		}

		internal bool IgnoreFontEvents
		{
			get
			{
				return this.g;
			}
			set
			{
				this.g = value;
			}
		}

		[Browsable(false)]
		public override DockStyle Dock
		{
			get
			{
				return base.Dock;
			}
			set
			{
				base.Dock = value;
			}
		}

		public override Rectangle DisplayRectangle
		{
			get
			{
				Rectangle displayRectangle = base.DisplayRectangle;
				switch (this.f)
				{
				case TD.SandDock.Rendering.BorderStyle.Flat:
				case TD.SandDock.Rendering.BorderStyle.RaisedThin:
				case TD.SandDock.Rendering.BorderStyle.SunkenThin:
					displayRectangle.Inflate(-1, -1);
					break;
				case TD.SandDock.Rendering.BorderStyle.RaisedThick:
				case TD.SandDock.Rendering.BorderStyle.SunkenThick:
					displayRectangle.Inflate(-2, -2);
					break;
				}
				return displayRectangle;
			}
		}

		internal static void a(Control A_0, Graphics A_1, TD.SandDock.Rendering.BorderStyle A_2)
		{
			if (A_2 == TD.SandDock.Rendering.BorderStyle.None)
			{
				return;
			}
			Rectangle rectangle = new Rectangle(0, 0, A_0.Width, A_0.Height);
			if (A_2 == TD.SandDock.Rendering.BorderStyle.Flat)
			{
				rectangle.Width--;
				rectangle.Height--;
				A_1.DrawRectangle(SystemPens.ControlDark, rectangle);
				return;
			}
			Border3DStyle style;
			switch (A_2)
			{
			case TD.SandDock.Rendering.BorderStyle.Flat:
				style = Border3DStyle.Flat;
				goto IL_7F;
			case TD.SandDock.Rendering.BorderStyle.RaisedThick:
				style = Border3DStyle.Raised;
				goto IL_7F;
			case TD.SandDock.Rendering.BorderStyle.RaisedThin:
				style = Border3DStyle.RaisedInner;
				goto IL_7F;
			case TD.SandDock.Rendering.BorderStyle.SunkenThick:
				style = Border3DStyle.Sunken;
				goto IL_7F;
			}
			style = Border3DStyle.SunkenOuter;
			IL_7F:
			ControlPaint.DrawBorder3D(A_1, rectangle, style);
		}

		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);
			DockControl.a(this, e.Graphics, this.f);
		}

		internal void a(Size A_0, Point A_1, DockLocation A_2)
		{
			this.n = A_0;
			this.o = A_1;
			this.q = A_2;
		}

		[Category("Appearance")]
		[DefaultValue(typeof(TD.SandDock.Rendering.BorderStyle), "None")]
		[Description("The type of border to be drawn around the control.")]
		public TD.SandDock.Rendering.BorderStyle BorderStyle
		{
			get
			{
				return this.f;
			}
			set
			{
				this.f = value;
				base.PerformLayout();
				base.Invalidate();
			}
		}

		[Browsable(false)]
		public ControlLayoutSystem LayoutSystem
		{
			get
			{
				return this.b;
			}
		}

		internal DockLocation DockLocation
		{
			get
			{
				return this.q;
			}
		}

		internal void a(DockContainer A_0)
		{
			if (A_0 != null)
			{
				if (A_0.Manager != null && A_0.Manager != this.Manager)
				{
					this.Manager = A_0.Manager;
				}
				if (A_0.IsFloating)
				{
					this.q = DockLocation.Float;
					return;
				}
				switch (A_0.Dock)
				{
				case DockStyle.Top:
					this.q = DockLocation.Top;
					break;
				case DockStyle.Bottom:
					this.q = DockLocation.Bottom;
					break;
				case DockStyle.Left:
					this.q = DockLocation.Left;
					break;
				case DockStyle.Right:
					this.q = DockLocation.Right;
					break;
				case DockStyle.Fill:
					this.q = DockLocation.Center;
					break;
				}
				this.r = this.q;
				this.s = A_0.LayoutSystem.LayoutSystems.IndexOf(this.b);
				this.t = this.b.Guid;
			}
		}

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public SandDockManager Manager
		{
			get
			{
				return this.a;
			}
			set
			{
				if (this.a != null)
				{
					this.a.b(this);
				}
				this.a = value;
				if (this.a != null)
				{
					this.a.a(this);
				}
			}
		}

		private void b()
		{
			if (this.a == null || this.a.a.Count == 0)
			{
				throw new InvalidOperationException("No SandDockManager is associated with this DockControl.");
			}
		}

		public void Float(Rectangle bounds)
		{
			bool flag = false;
			this.b();
			if (this.IsFloating)
			{
				throw new InvalidOperationException("The dockable window is already floating.");
			}
			Size size = this.n;
			if (this.b != null)
			{
				size = new Size((int)this.b.f.Width, (int)this.b.f.Height);
				if (this.b is DocumentLayoutSystem)
				{
					flag = true;
				}
				TD.SandDock.g.a(this);
			}
			ControlLayoutSystem layoutSystem;
			if (flag)
			{
				layoutSystem = new DocumentLayoutSystem(size.Width, size.Height, new DockControl[]
				{
					this
				}, this);
			}
			else
			{
				layoutSystem = new ControlLayoutSystem(size.Width, size.Height, new DockControl[]
				{
					this
				}, this);
			}
			m m = this.a.b();
			m.LayoutSystem.LayoutSystems.Add(layoutSystem);
			m.a(bounds, true, true);
		}

		public void Float()
		{
			this.Float(this.h());
		}

		internal Rectangle h()
		{
			if (this.o.X == -1 && this.o.Y == -1)
			{
				Rectangle workingArea = Screen.PrimaryScreen.WorkingArea;
				this.o = new Point(workingArea.X + workingArea.Width / 2 - this.n.Width / 2, workingArea.Y + workingArea.Height / 2 - this.n.Height / 2);
			}
			return new Rectangle(this.o, this.n);
		}

		public void Open()
		{
			this.Open(this.q);
		}

		public void Open(DockLocation dockLocation)
		{
			ControlLayoutSystem controlLayoutSystem = this.b;
			this.q = dockLocation;
			if (dockLocation != DockLocation.Float)
			{
				this.r = dockLocation;
			}
			if (controlLayoutSystem == null)
			{
				controlLayoutSystem = this.LastControlLayoutSystem;
				if (!controlLayoutSystem.Controls.Contains(this))
				{
					controlLayoutSystem.Controls.Add(this);
				}
			}
			controlLayoutSystem.SelectedControl = this;
			if (this.IsFloating)
			{
				((m)this.b.DockContainer).i();
				return;
			}
			if (this.b.Collapsed && this.b.DockContainer.CanShowCollapsed)
			{
				this.b.DockContainer.AutoHideManager.a(this, true, true);
			}
		}

		public void Close()
		{
			if (!this.IsInContainer)
			{
				return;
			}
			DocumentClosingEventArgs documentClosingEventArgs = new DocumentClosingEventArgs(this, false);
			if (this.b.DockContainer is DocumentContainer)
			{
				((DocumentContainer)this.b.DockContainer).OnDocumentClosing(documentClosingEventArgs);
			}
			if (documentClosingEventArgs.Cancel)
			{
				return;
			}
			CancelEventArgs cancelEventArgs = new CancelEventArgs();
			this.OnClosing(cancelEventArgs);
			if (cancelEventArgs.Cancel)
			{
				return;
			}
			if (this.IsFloating && ((m)this.b.DockContainer).HasSingleControlLayoutSystem && this.b.Controls.Count == 1)
			{
				((m)this.b.DockContainer).f();
			}
			else
			{
				TD.SandDock.g.a(this);
			}
			this.OnClosed(EventArgs.Empty);
		}

		protected internal virtual void OnClosing(CancelEventArgs e)
		{
			if (this.v != null)
			{
				this.v(this, e);
			}
		}

		protected internal virtual void OnClosed(EventArgs e)
		{
			if (this.w != null)
			{
				this.w(this, e);
			}
		}

		protected internal virtual void OnBeforeFirstShown(EventArgs e)
		{
			if (this.x != null)
			{
				this.x(this, e);
			}
		}

		public void Activate()
		{
			if (this.b != null && this.b.SelectedControl != this)
			{
				this.b.SelectedControl = this;
			}
			base.SelectNextControl(this, true, true, true, true);
			if (!base.ContainsFocus)
			{
				if (base.Controls.Count == 1)
				{
					base.Controls[0].Focus();
				}
				else
				{
					base.Focus();
				}
			}
			if (this.IsInContainer && this.b.DockContainer is DocumentContainer)
			{
				((DocumentContainer)this.b.DockContainer).c(this);
			}
		}

		[Browsable(false)]
		public Guid Guid
		{
			get
			{
				return this.m;
			}
			set
			{
				this.m = value;
			}
		}

		[Browsable(false)]
		public bool IsFloating
		{
			get
			{
				return this.IsInContainer && this.b.DockContainer.IsFloating;
			}
		}

		[Browsable(false)]
		public bool IsInContainer
		{
			get
			{
				return this.b != null && this.b.DockContainer != null;
			}
		}

		[Browsable(false)]
		public bool IsOpen
		{
			get
			{
				bool flag = this.IsInContainer && this.b != null && this.b.SelectedControl == this;
				if (flag && this.b.Collapsed)
				{
					flag = this.b.IsPoppedUp;
				}
				if (flag && this.IsFloating)
				{
					flag = ((m)this.b.DockContainer).j();
				}
				return flag;
			}
		}

		public override Color BackColor
		{
			get
			{
				return base.BackColor;
			}
			set
			{
				base.BackColor = value;
				if (this.b != null && this.b.DockContainer != null)
				{
					this.b.DockContainer.Invalidate(this.b.Bounds);
				}
			}
		}

		public override Color ForeColor
		{
			get
			{
				return base.ForeColor;
			}
			set
			{
				base.ForeColor = value;
				if (this.b != null && this.b.DockContainer != null)
				{
					this.b.DockContainer.Invalidate(this.c);
				}
			}
		}

		[Description("Indicates the default size this control will assume when floating on its own.")]
		[DefaultValue(typeof(Size), "250, 400")]
		[Category("Layout")]
		public Size FloatingSize
		{
			get
			{
				return this.n;
			}
			set
			{
				if (value.Width <= 0 || value.Height <= 0)
				{
					throw new ArgumentOutOfRangeException();
				}
				this.n = value;
				if (this.IsFloating && this.FloatingDockContainer.g() != this.n)
				{
					this.FloatingDockContainer.a(this.n);
				}
			}
		}

		[DefaultValue(typeof(Point), "-1, -1")]
		[Browsable(false)]
		public Point FloatingLocation
		{
			get
			{
				return this.o;
			}
			set
			{
				this.o = value;
				if (this.IsFloating && this.FloatingDockContainer.h() != this.o)
				{
					this.FloatingDockContainer.a(this.o);
				}
			}
		}

		private m FloatingDockContainer
		{
			get
			{
				return this.b.DockContainer as m;
			}
		}

		protected override void OnMouseDown(MouseEventArgs e)
		{
			base.OnMouseDown(e);
			this.Activate();
		}

		public void PerformDock()
		{
			ControlLayoutSystem controlLayoutSystem = this.LastControlLayoutSystem;
			if (controlLayoutSystem != this.b)
			{
				TD.SandDock.g.a(this);
				int num = this.LastIndexInFixedLayoutSystem;
				if (num < 0)
				{
					num = 0;
				}
				else if (num > controlLayoutSystem.Controls.Count)
				{
					num = controlLayoutSystem.Controls.Count;
				}
				controlLayoutSystem.Controls.Insert(num, this);
			}
		}

		internal ControlLayoutSystem LastControlLayoutSystem
		{
			get
			{
				this.b();
				bool a_ = false;
				if (this.b is DocumentLayoutSystem)
				{
					a_ = true;
				}
				return TD.SandDock.g.a(this.Manager, this.r, this.s, this.t, a_);
			}
		}

		public void PerformDock(ControlLayoutSystem layoutSystem)
		{
			this.PerformDock(layoutSystem, 0);
		}

		public void PerformDock(ControlLayoutSystem layoutSystem, int index)
		{
			if (this.b != layoutSystem)
			{
				TD.SandDock.g.a(this);
				layoutSystem.Controls.Insert(index, this);
			}
			else
			{
				layoutSystem.Controls.SetChildIndex(this, index);
			}
			layoutSystem.SelectedControl = this;
		}

		[Category("Docking")]
		[DefaultValue(true)]
		[Description("Indicates whether this control will be closable by the user.")]
		public bool Closable
		{
			get
			{
				return this.k;
			}
			set
			{
				this.k = value;
				if (this.b != null)
				{
					this.b.f();
				}
			}
		}

		[DefaultValue(true)]
		[Description("Indicates whether the user will be able to put this control in to auto-hide mode.")]
		[Category("Docking")]
		public bool Collapsible
		{
			get
			{
				return this.l;
			}
			set
			{
				this.l = value;
				if (this.b != null)
				{
					this.b.f();
				}
			}
		}

		protected override void OnFontChanged(EventArgs e)
		{
			base.OnFontChanged(e);
			if (this.b != null && !this.IgnoreFontEvents)
			{
				this.b.f();
			}
		}

		private bool ShouldSerializeTabText()
		{
			return this.j.Length != 0 && this.j != this.Text;
		}

		[Localizable(true)]
		[DefaultValue("")]
		[Description("Gets or sets the text that appears as a ToolTip for the control tab.")]
		[Category("Appearance")]
		public string ToolTipText
		{
			get
			{
				return this.i;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException();
				}
				this.i = value;
			}
		}

		[Localizable(true)]
		[Category("Appearance")]
		[Description("The text to display on the tab for the DockControl. This can be different to the standard text.")]
		public string TabText
		{
			get
			{
				if (this.j.Length == 0)
				{
					return this.Text;
				}
				return this.j;
			}
			set
			{
				if (value == null)
				{
					throw new ArgumentNullException();
				}
				this.j = value;
				if (this.b != null)
				{
					this.b.f();
				}
			}
		}

		public override string Text
		{
			get
			{
				return base.Text;
			}
			set
			{
				base.Text = value;
				if (this.b != null)
				{
					this.b.f();
				}
				if (this.IsFloating && ((m)this.b.DockContainer).HasSingleControlLayoutSystem && this.b.SelectedControl == this)
				{
					((m)this.b.DockContainer).e();
				}
			}
		}

		internal Image WorkingTabImage
		{
			get
			{
				if (this.e == null)
				{
					return DockControl.d;
				}
				return this.e;
			}
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (this.b != null)
				{
					TD.SandDock.g.a(this);
				}
				if (this.e != null)
				{
					this.e.Dispose();
				}
				if (this.Manager != null)
				{
					this.Manager = null;
				}
			}
			base.Dispose(disposing);
		}

		public Rectangle TabBounds
		{
			get
			{
				return this.c;
			}
		}

		[Description("The image displayed for this control on docking tabs.")]
		[AmbientValue(typeof(Image), null)]
		[Category("Appearance")]
		[DefaultValue(typeof(Image), null)]
		public Image TabImage
		{
			get
			{
				return this.e;
			}
			set
			{
				if (value != null && (value.Width != 16 || value.Height != 16))
				{
					throw new ArgumentException("Image must be 16x16 pixels.");
				}
				this.e = value;
				if (this.b != null)
				{
					this.b.f();
				}
			}
		}

		private SandDockManager a = null;

		internal ControlLayoutSystem b = null;

		internal Rectangle c = Rectangle.Empty;

		private static Image d = null;

		private Image e = null;

		private TD.SandDock.Rendering.BorderStyle f = TD.SandDock.Rendering.BorderStyle.None;

		private bool g = false;

		internal bool h = false;

		private string i = "";

		private string j = "";

		private bool k = true;

		private bool l = true;

		private Guid m = Guid.NewGuid();

		private Size n = new Size(250, 400);

		private Point o = new Point(-1, -1);

		internal bool p = false;

		private DockLocation q = DockLocation.Right;

		private DockLocation r = DockLocation.Right;

		private int s = -1;

		private Guid t = Guid.Empty;

		private int u = -1;

		private CancelEventHandler v;

		private EventHandler w;

		private EventHandler x;
	}
}
