using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;

using CategoryTheory;

namespace DiagramUI
{
	/// <summary>
	/// 
	/// </summary>
	internal class ChildObjectLabel : Panel
	{
		static private readonly int width = 10;
		static private readonly int height = 10;
		static private readonly Color back = Color.Black;
		private INamedComponent nc;
		private ContainerObjectLabel parent;
		private int x;
		private int y;
		private Form form;
		internal ChildObjectLabel(ContainerObjectLabel parent, string name, INamedComponent nc, object[] o)
		{
			this.nc = nc;
			Height = height;
			Width = width;
			BackColor = back;
			ToolTip t = new ToolTip();
			t.ShowAlways = true;
			t.SetToolTip(this, name + " :: " + o[2]);
			x = (int) o[0];
			y = (int) o[1];
			this.parent = parent;
			parent.Parent.Controls.Add(this);
			move();
			MouseUp += new MouseEventHandler(onMouseUpShow) + new MouseEventHandler(onMouseUpArrow);
			MouseDown += new MouseEventHandler(onMouseDownMoveEventHandler);
			MouseMove += new MouseEventHandler(onMouseMoveArrow);

		}


		#region Specific Members

		internal void move()
		{
			Left = parent.Left + x;
			Top = parent.Top + y;
		}

		internal void remove()
		{
			removeForm();
			PanelDesktop desktop = Parent as PanelDesktop;
            if (desktop != null)
            {
                desktop.remove(this);
            }
			nc.Remove();
		}

		internal void removeForm()
		{
			if (form != null)
			{
                if (!form.IsDisposed)
				{
					form.Dispose();
				}
				form = null;
				GC.Collect();
			}
		}

		/// <summary>
		/// The on mouse up event handler
		/// </summary>
		/// <param name="sender">The sender</param>
		/// <param name="e">The event arguments</param>
		private void onMouseUpShow(object sender, MouseEventArgs e)
		{
			if (e.Button != MouseButtons.Right)
			{
				return;
			}
			showForm();
		}

		internal void showForm()
		{
			PanelDesktop desktop = Parent as PanelDesktop;
			try
			{
				if (form == null)
				{
					form = desktop.Tools.Factory.CreateForm(nc);
				}
				if (form != null)
				{
                    if (form.IsDisposed)
                    {
                        form = desktop.Tools.Factory.CreateForm(nc);
                    }
					form.Show();
					form.BringToFront();
					form.Activate();
					form.Focus();
					form.Show();
				}

			}
			catch (Exception ex)
			{
				desktop.Tools.Factory.ShowError(ex);
			}

		}

		/// <summary>
		/// The on mouse up event handler
		/// </summary>
		/// <param name="sender">The sender</param>
		/// <param name="e">The event arguments</param>
		protected void onMouseUpArrow(object sender, MouseEventArgs e)
		{
			//isMoved = false;
			PanelDesktop desktop = Parent as PanelDesktop;
			ICategoryArrow arrow = desktop.ActiveArrow;
			if (e.Button == MouseButtons.Right)
			{
				return;
			}
			if (!(nc is IObjectLabel))
			{
				return;
			}
			IObjectLabel ol = nc as IObjectLabel;
			ICategoryObject obj = ol.Object;
			try
			{
				if (arrow == null)
				{
					return;
				}
				int x = Left + e.X;
				int y = Top + e.Y;
				for (int i = 0; i < desktop.Controls.Count; i++)
				{
					if (!(desktop.Controls[i] is ChildObjectLabel) & !(desktop.Controls[i] is ObjectLabel))
					{
						continue;
					}
					Control c = desktop.Controls[i];
					bool hor = x < c.Left | x > c.Left + c.Width;
					bool vert = y < c.Top | y > c.Top + c.Height;
					if (hor | vert)
					{
						continue;
					}
					IObjectLabel label = null;
					if (desktop.Controls[i] is IObjectLabel)
					{
						label = desktop.Controls[i] as IObjectLabel;
					}
					else
					{
						ChildObjectLabel child = desktop.Controls[i] as ChildObjectLabel;
						label = child.label;
					}
					arrow.Target = label.Object;
					ArrowLabel lab = desktop.Tools.Factory.CreateArrowLabel(desktop.Tools.Active, arrow, ol, label);
					lab.Arrow.Object = lab;
					desktop.AddArrowLabel(lab);
					break;
				}
			}
			catch (Exception ex)
			{
				if (arrow != null)
				{
					if (arrow is IRemovableObject)
					{
						IRemovableObject rem = arrow as IRemovableObject;
						rem.RemoveObject();
					}
				}
				desktop.Tools.Factory.ShowError(ex);
			}
			desktop.ActiveArrow = null;
			desktop.Redraw();
		}

		internal IObjectLabel label
		{
			get
			{
				if (nc is IObjectLabel)
				{
					return nc as IObjectLabel;
				}
				return null;
			}
		}

		/// <summary>
		/// The on mouse down event handler
		/// </summary>
		/// <param name="sender">The sender</param>
		/// <param name="e">The event arguments</param>
		private void onMouseDownMoveEventHandler(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Right)
			{
				return;
			}
			IObjectLabel lab = label;
			if (lab == null)
			{
				return;
			}
			PanelDesktop desktop = Parent as PanelDesktop;
			PaletteButton active = desktop.Tools.Active;
			if (active != null)
			{
				if (active.IsArrow & !(active.Kind == -1))
				{
					try
					{
						ICategoryArrow arrow = desktop.Tools.Factory.CreateArrow(active);
						arrow.Source = lab.Object;
						desktop.ActiveArrow = arrow;
						desktop.ActiveObjectLabel = lab;
						return;
					}
					catch (Exception ex)
					{
						desktop.Tools.Factory.ShowError(ex);
					}
				}
			}
		}

		/// <summary>
		/// The on mouse move event handler
		/// Draws correspond arrows
		/// </summary>
		/// <param name="sender">The sender</param>
		/// <param name="e">The event arguments</param>
		protected void onMouseMoveArrow(object sender, MouseEventArgs e)
		{
			PanelDesktop desktop = Parent as PanelDesktop;
			if (e.Button == MouseButtons.Right)
			{
				return;
			}
			if (desktop.ActiveArrow == null)
			{
				return;
			}
			desktop.DrawArrow(this, e);
		}






		#endregion
	}
}
