using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VRageMath;

namespace UIFun.Menu
{
	public class MenuObject
	{
		protected Vector2D m_Position = Vector2D.Zero;
		protected bool m_Visible = false;
		protected bool m_MouseHover = false;
		protected bool m_isSelected = false;
		protected List<MenuObject> m_SubItems = new List<MenuObject>();
		protected Action m_OnMouseOverCallBack;
		private Action onClickCallback;
		protected MenuObject m_Parent;
		protected Vector2D m_Size = Vector2D.Zero; //size of included elements
		protected MenuObject Selected;
		protected Vector2D m_Max = Vector2D.Zero;
		protected Vector2D m_Min = Vector2D.Zero;
		protected Vector2D Offset = Vector2D.Zero;
		public MenuObject(Vector2D position, bool visible = true, MenuObject parent = null, Action mouseOver = null, Action onClick = null)
		{
			m_Visible = visible;
			Position = position;
			if(parent != null)
			{
				parent.AddSubObject(this);
			}
			m_OnMouseOverCallBack = mouseOver;
			OnClickCallback = onClick;
		}

		public Action OnClickCallback
		{
			get
			{
				return onClickCallback;
			}

			set
			{
				onClickCallback = value;
			}
		}

		public bool Visible
		{
			get
			{
				return m_Visible;
			}
			set
			{
				m_Visible = value;
			}
		}
		public Vector2D Position
		{
			get
			{
				return m_Position;
			}
			set
			{
				if(m_Position != value)
				{
					m_Position = value;
					UpdateBounds();
				}

            }
		}
		public Vector2D Size
		{
			get
			{
				return m_Size;
			}
			set
			{
				if(m_Size != value)
				{
					m_Size = value;
					UpdateBounds();
				}

			}
		}
		virtual public void UpdateBounds()
		{
			var pos = ScreenPosition();
			m_Max.X = pos.X + m_Size.X;
			m_Max.Y = pos.Y;
			m_Min.X = pos.X;
			m_Min.Y = pos.Y + m_Size.Y;
			foreach(var item in m_SubItems)
			{
				item.UpdateBounds();
			}
			//SetOffset(m_Size);
        }
		virtual public bool IsActive
		{
			get
			{
				return false;
			}
			set
			{

			}
		}
		public Vector2D Max
		{
			get
			{
				return m_Max;
			}
		}
		public Vector2D Min
		{
			get
			{
				return m_Min;
			}
		}

		//should find out where we should start drawing. 
		protected Vector2D ScreenPosition()
		{
			MenuObject mTree = this;
			Vector2D screenposition = Vector2D.Zero;
			while (mTree != null)
			{
				screenposition += mTree.Position;
				
				mTree = mTree.Parent;
				if(mTree != null)
					screenposition.X += mTree.Size.X;
			}
			return screenposition;
		}
		virtual public void SetOffset(Vector2D offset)
		{
			return;
		}
		public MenuObject Parent
		{
			get
			{
				return m_Parent;
			}
		}



		virtual public void AddSubObject(MenuObject obj)
		{
			obj.m_Parent = this;
			m_SubItems.Add(obj);
		}
		virtual public void RemoveSubObject(MenuObject obj)
		{
			if(obj.m_Parent == this)
			{
				m_SubItems.Remove(obj);
				obj.m_Parent = null;
			}

		}
		virtual public void Clear()
		{
			for (int i = m_SubItems.Count - 1; i > 0; i--)
			{
				RemoveSubObject(m_SubItems[i]);
            }
		}
		virtual public void Draw()
		{
			if(Visible)
			{
				foreach(var obj in m_SubItems)
				{
					obj.Draw();
				}
			}
			m_MouseHover = false;
		}
		virtual public void OnMouseOver(Vector2D MousePosition)
		{
			if (!Visible)
				return;
			
			if((MousePosition.X <= m_Max.X) && (MousePosition.X >= m_Min.X) && (MousePosition.Y <= m_Max.Y) && (MousePosition.Y >= m_Min.Y))
			{
				m_MouseHover = true;
                if (m_OnMouseOverCallBack != null)
					m_OnMouseOverCallBack();
			}
			foreach (var item in m_SubItems)
			{
				if(item.Visible)
					item.OnMouseOver(MousePosition);
			}

		}
		virtual public void OnClick(Vector2D MousePosition)
		{
			if ((MousePosition.X <= m_Max.X) && (MousePosition.X >= m_Min.X) && (MousePosition.Y <= m_Max.Y) && (MousePosition.Y >= m_Min.Y))
			{
				if (m_Parent != null)
				{
					if (m_Parent.Selected != this)
					{
						if(m_Parent.Selected != null)
							m_Parent.Selected.UnSelect();
						m_Parent.Selected = this;
						Select();
					}
					else
					{
						if (m_Parent.Selected != null)
							m_Parent.Selected.UnSelect();//unselect. 
						m_Parent.Selected = null;
                    }
				}
				onClickCallbackCall();
            }
			foreach (var item in m_SubItems)
			{
				if(item.Visible)
					item.OnClick(MousePosition);
			}
		}
		virtual public void OnMouseRelease(Vector2D Position)
		{
			foreach(var item in m_SubItems)
			{
				if(item.Visible)
				{
					item.OnMouseRelease(Position);
				}
			}
		}
		virtual public void Refresh()
		{
			foreach(var item in m_SubItems)
			{
				item.Refresh();
			}
		}
		virtual public void onClickCallbackCall()
		{
			if (OnClickCallback != null)
				OnClickCallback();
		}
		virtual public void UnSelect()
		{
			m_isSelected = false;
			foreach (var item in m_SubItems)
			{
				item.Visible = false;
			}
		}
		virtual public void Select()
		{
			foreach(var item in m_SubItems)
			{
				item.Visible = true;
			}
			m_isSelected = true;
		}
		public void GetArea()
		{
			
		}
		virtual public void OnRemove()
		{

		}

	}
}
