using Quik.CommandMachine;

namespace Quik.Controls
{
    public sealed class RootControl : Container
    {
        // public QuikContext Context { get; }
        public Control FocusedControl { get; private set; }

        public RootControl(object context)
        {
            // Context = context;
        }

        public void Focus(Control which)
        {
            FocusChangedEventArgs args = new FocusChangedEventArgs(which);

            FocusedControl?.NotifyFocusChanged(args);
            (FocusedControl = which).NotifyFocusChanged(args);
        }

        public new void NotifyUpdate()
        {
            base.NotifyUpdate();
        }

        public new void NotifyPaint(CommandQueue draw)
        {
            base.NotifyPaint(draw);
        }

        private MouseState LastMouseState;
        public void NotifyMouse(in MouseState state)
        {
            MouseMoveEventArgs move = new MouseMoveEventArgs(
                state.AbsolutePosition,
                LastMouseState.AbsolutePosition);
            MouseButtonEventArgs up = new MouseButtonEventArgs(
                state.AbsolutePosition,
                LastMouseState.ButtonsDown & ~state.ButtonsDown);
            MouseButtonEventArgs down = new MouseButtonEventArgs(
                state.AbsolutePosition,
                ~LastMouseState.ButtonsDown & state.ButtonsDown);

            if (move.Motion.Magnitude > 0)
                NotifyMouseMove(move);

            if (up.Buttons != 0)
                NotifyMouseUp(up);

            if (down.Buttons != 0)
                NotifyMouseDown(down);

            LastMouseState = state;
        }

        public override void Add(Control item)
        {
            base.Add(item);
            item.NotifyRootChanged(new RootChangedEventArgs(this));
        }

        public override void Clear()
        {
            foreach (Control child in this)
            {
                child.NotifyRootChanged(RootChangedEventArgs.Disowned);
            }
            base.Clear();
        }

        public override void Insert(int index, Control item)
        {
            base.Insert(index, item);
            item.NotifyRootChanged(new RootChangedEventArgs(this));
        }

        public override bool Remove(Control item)
        {
            if(base.Remove(item))
            {
                item.NotifyRootChanged(RootChangedEventArgs.Disowned);
                return true;
            }
            else
            {
                return false;
            }
        }

        public override void RemoveAt(int index)
        {
            this[index].NotifyRootChanged(RootChangedEventArgs.Disowned);
            base.RemoveAt(index);
        }

        public override Control this[int index]
        {
            get => base[index];
            set
            {
                base[index].NotifyRootChanged(RootChangedEventArgs.Disowned);
                base[index] = value;
                value.NotifyRootChanged(new RootChangedEventArgs(this));
            }
        }
    }
}