using System;
using System.Collections;
using System.Collections.Generic;
using Quik.CommandMachine;

namespace Quik.Controls
{
    public class Container : Control, IList<Control>
    {
        private List<Control> _children = new List<Control>();
        public IEnumerator<Control> GetEnumerator() => _children.GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        public virtual void Add(Control item)
        {
            _children.Add(item);
            item.NotifyParentChanged(new ParentChangedEventArgs(this));
        }

        public virtual void Clear()
        {
            foreach (Control child in _children)
            {
                child.NotifyParentChanged(ParentChangedEventArgs.Disowned);
            }
            _children.Clear();
        }

        public bool Contains(Control item) => _children.Contains(item);

        public void CopyTo(Control[] array, int arrayIndex) => _children.CopyTo(array, arrayIndex);

        public virtual bool Remove(Control item)
        {
            if (_children.Remove(item))
            {
                item.NotifyParentChanged(ParentChangedEventArgs.Disowned);

                return true;
            }
            else
            {
                return false;
            }
        }

        public int Count => _children.Count;
        public bool IsReadOnly => false;

        public int IndexOf(Control item) =>_children.IndexOf(item);

        public virtual void Insert(int index, Control item)
        {
            _children.Insert(index, item);
            NotifyParentChanged(new ParentChangedEventArgs(this));
        }

        public virtual void RemoveAt(int index)
        {
            _children.RemoveAt(index);
            _children[index].NotifyParentChanged(ParentChangedEventArgs.Disowned);
        }

        public virtual Control this[int index]
        {
            get => _children[index];
            set
            {
                _children[index].NotifyParentChanged(ParentChangedEventArgs.Disowned);
                _children[index] = value;
                value.NotifyParentChanged(new ParentChangedEventArgs(this));
            }
        }

        public Control this[string name] => _children.Find(x => x.Name == name);

        internal override void NotifyUpdate()
        {
            base.NotifyUpdate();

            foreach (Control child in _children)
            {
                child.NotifyUpdate();
            }
        }

        internal override void NotifyPaint(CommandQueue draw)
        {
            base.NotifyPaint(draw);

            foreach (Control child in _children)
            {
                child.NotifyPaint(draw);
            }
        }

        internal override void NotifyRootChanged(RootChangedEventArgs args)
        {
            base.NotifyRootChanged(args);

            foreach (Control child in _children)
            {
                child.NotifyRootChanged(args);
            }
        }

        internal override void NotifyMouseMove(MouseMoveEventArgs args)
        {
            base.NotifyMouseMove(args);

            foreach (Control child in _children)
            {
                child.NotifyMouseMove(args);
            }
        }

        internal override void NotifyMouseDown(MouseButtonEventArgs args)
        {
            base.NotifyMouseDown(args);

            foreach (Control child in _children)
            {
                child.NotifyMouseDown(args);
            }
        }

        internal override void NotifyMouseUp(MouseButtonEventArgs args)
        {
            base.NotifyMouseUp(args);

            foreach (Control child in _children)
            {
                child.NotifyMouseUp(args);
            }
        }
    }
}