using System;
using System.Collections;
using System.ComponentModel;
using System.Collections.Generic;
using System.Windows.Forms;
namespace DevComponents.DotNetBar.Layout
{
    /// 
    /// Represents collection for LayoutItemBase objects.
    /// 
    public class LayoutItemCollection : CollectionBase
    {
        #region Private Variables
        private LayoutItemBase _ParentItem = null;
        #endregion
        #region Internal Implementation
        public LayoutItemCollection()
        {
        }
        /// 
        /// Gets or sets the item this collection is associated with.
        /// 
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public LayoutItemBase ParentItem
        {
            get { return _ParentItem; }
        }
        /// 
        /// Sets the item collection belongs to.
        /// 
        /// Item that is parent of this collection.
        internal void SetParentItem(LayoutItemBase parent)
        {
            _ParentItem = parent;
        }
        /// 
        /// Adds new object to the collection.
        /// 
        /// Object to add.
        /// Index of newly added object.
        public virtual int Add(LayoutItemBase item)
        {
            if (this.List.Contains(item))
                return IndexOf(item); // throw new InvalidOperationException("Item already contained in collection");
            return List.Add(item);
        }
        /// 
        /// Adds an array of objects to the collection. 
        /// 
        /// Array of item objects.
        public virtual void AddRange(LayoutItemBase[] items)
        {
            foreach (LayoutItemBase item in items)
                this.Add(item);
        }
        /// 
        /// Returns reference to the object in collection based on it's index.
        /// 
        public LayoutItemBase this[int index]
        {
            get { return (LayoutItemBase)(List[index]); }
            set { List[index] = value; }
        }
        /// 
        /// Inserts new object into the collection.
        /// 
        /// Position of the object.
        /// Object to insert.
        public virtual void Insert(int index, LayoutItemBase value)
        {
            List.Insert(index, value);
        }
        /// 
        /// Returns index of the object inside of the collection.
        /// 
        /// Reference to the object.
        /// Index of the object.
        public int IndexOf(LayoutItemBase value)
        {
            return List.IndexOf(value);
        }
        /// 
        /// Returns whether collection contains specified object.
        /// 
        /// Object to look for.
        /// true if object is part of the collection, otherwise false.
        public bool Contains(LayoutItemBase value)
        {
            return List.Contains(value);
        }
        /// 
        /// Removes specified object from the collection.
        /// 
        /// 
        public virtual void Remove(LayoutItemBase value)
        {
            List.Remove(value);
        }
        protected override void OnRemove(int index, object value)
        {
            //if (!_PassiveCollection)
            //{
            //    AdvTree tree = GetTreeControl();
            //    if (tree != null)
            //        tree.InvokeBeforeNodeRemove(m_SourceAction, value as Node, m_ParentNode);
            //}
            base.OnRemove(index, value);
        }
        protected override void OnRemoveComplete(int index, object value)
        {
            base.OnRemoveComplete(index, value);
            if(!_MovingItem)
                ItemRemoveComplete(index, value);
        }
        private void ItemRemoveComplete(int index, object value)
        {
            LayoutItemBase item = value as LayoutItemBase;
            item.Parent = null;
        }
        protected override void OnSetComplete(int index, object oldValue, object newValue)
        {
            base.OnSetComplete(index, oldValue, newValue);
            if (!_MovingItem)
            {
                ItemRemoveComplete(index, oldValue);
                ItemInsertComplete(newValue);
            }
        }
        protected override void OnSet(int index, object oldValue, object newValue)
        {
            //if (!_PassiveCollection)
            //{
            //    AdvTree tree = GetTreeControl();
            //    if (tree != null)
            //        tree.InvokeBeforeNodeRemove(m_SourceAction, oldValue as Node, m_ParentNode);
            //    if (tree != null)
            //        tree.InvokeBeforeNodeInsert(m_SourceAction, newValue as Node, m_ParentNode);
            //}
            base.OnSet(index, oldValue, newValue);
        }
        private bool _MovingItem = false;
        /// 
        /// Moves an item in collection from its current location to new location.
        /// 
        /// 
        /// 
        public void Move(DevComponents.DotNetBar.Layout.LayoutItemBase item, int moveToIndex)
        {
            _MovingItem = true;
            try
            {
                if (moveToIndex > this.Count - 1) moveToIndex = this.Count - 1;
                if (moveToIndex < 0) moveToIndex = 0;
                List.Remove(item);
                List.Insert(moveToIndex, item);
                //LayoutItemBase temp = this[moveToIndex];
                //int index = List.IndexOf(item);
                //List[moveToIndex] = item;
                //List[index] = temp;
            }
            finally
            {
                _MovingItem = false;
            }
        }
        protected override void OnInsert(int index, object value)
        {
            //if (!_PassiveCollection)
            //{
            //    AdvTree tree = GetTreeControl();
            //    if (tree != null)
            //        tree.InvokeBeforeNodeInsert(m_SourceAction, value as Node, m_ParentNode);
            //}
            base.OnInsert(index, value);
        }
        protected override void OnInsertComplete(int index, object value)
        {
            base.OnInsertComplete(index, value);
            if(!_MovingItem)
                ItemInsertComplete(value);
        }
        private void ItemInsertComplete(object value)
        {
            LayoutItemBase item = value as LayoutItemBase;
            item.Parent = _ParentItem;
            //if (!_PassiveCollection)
            //{
            //    Node node = value as Node;
            //    if (m_ParentNode != null)
            //    {
            //        if (node.Parent != null && node.Parent != m_ParentNode)
            //            node.Remove();
            //        node.SetParent(m_ParentNode);
            //        if (m_ParentNode.NodesColumns.IsSorted)
            //        {
            //            AdvTree parentTree = m_TreeControl;
            //            if (parentTree == null) parentTree = m_ParentNode.TreeControl;
            //            if (parentTree != null)
            //                parentTree.PushSortRequest(m_ParentNode);
            //        }
            //    }
            //    else
            //    {
            //        if (node.Parent != null)
            //            node.Remove();
            //        else
            //            node.InvokeOnParentChanged();
            //        if (m_TreeControl != null && m_TreeControl.Columns.IsSorted)
            //        {
            //            m_TreeControl.PushSortRequest();
            //        }
            //    }
            //    node.internalTreeControl = m_TreeControl;
            //    if (m_ParentNode != null)
            //        m_ParentNode.OnChildNodeInserted(node);
            //    else
            //        node.SizeChanged = true;
            //    AdvTree tree = GetTreeControl();
            //    if (tree != null)
            //        tree.InvokeAfterNodeInsert(m_SourceAction, value as Node, m_ParentNode);
            //}
            //m_SourceAction = eTreeAction.Code;
        }
        /// 
        /// Copies collection into the specified array.
        /// 
        /// Array to copy collection to.
        /// Starting index.
        public void CopyTo(LayoutItemBase[] array, int index)
        {
            List.CopyTo(array, index);
        }
        /// 
        /// Copies contained items to the item array.
        /// 
        /// Array to copy to.
        public void CopyTo(LayoutItemBase[] array)
        {
            List.CopyTo(array, 0);
        }
        /// 
        /// Copies contained items to the item array.
        /// 
        /// Array to copy to.
        public void CopyTo(List list)
        {
            foreach (LayoutItemBase item in this.List)
            {
                list.Add(item);
            }
        }
        protected override void OnClear()
        {
            foreach (LayoutItemBase item in this.List)
            {
                item.Parent = null;
            }
            base.OnClear();
        }
        protected override void OnClearComplete()
        {
            if (_ParentItem is LayoutGroup && ((LayoutGroup)_ParentItem).IsRootGroup)
            {
                // Remove all the controls as well from layout control
                List controlsToRemove = new List();
                LayoutControl lc = ((LayoutGroup)_ParentItem).LayoutControl;
                if (lc != null)
                {
                    lc.SuspendLayout();
                    foreach (Control c in lc.Controls)
                    {
                        if (!lc.IsSystemControl(c))
                            controlsToRemove.Add(c);
                    }
                    foreach (Control c in controlsToRemove)
                    {
                        lc.Controls.Remove(c);
                        if (lc.DisposeControlsOnRootGroupClear)
                            c.Dispose();
                    }
                    lc.ResumeLayout();
                }
            }
            base.OnClearComplete();
        }
        /// 
        /// Sorts the elements in the entire collection using the IComparable implementation of each element.
        /// 
        public virtual void Sort()
        {
            this.Sort(0, this.Count, Comparer.Default);
        }
        /// 
        /// Sorts the elements in the entire collection using the specified comparer.
        /// 
        /// The IComparer implementation to use when comparing elements.-or- null to use the IComparable implementation of each element.
        public virtual void Sort(IComparer comparer)
        {
            this.Sort(0, this.Count, comparer);
        }
        /// 
        /// Sorts the elements in a range of elements in collection using the specified comparer.
        /// 
        /// 
        /// 
        /// 
        public virtual void Sort(int index, int count, IComparer comparer)
        {
            //AdvTree tree = GetTreeControl();
            //if (!_PassiveCollection && tree != null)
            //    tree.BeginUpdate();
            this.InnerList.Sort(index, count, comparer);
            //if (tree != null && tree.DeepSort)
            //{
            //    foreach (Node node in this.InnerList)
            //    {
            //        node.Nodes.Sort(0, node.Nodes.Count, comparer);
            //    }
            //}
            //if (!_PassiveCollection && tree != null)
            //    tree.EndUpdate();
        }
        /// 
        /// Finds the items with specified key, optionally searching sub-nodes.
        /// 
        /// The name of the tree node to search for.
        /// true to search child nodes of tree nodes; otherwise, false. 
        /// An array of Node objects whose Name property matches the specified key.
        //public LayoutItemBase[] Find(string name, bool searchAllChildren)
        //{
        //    ArrayList list = new ArrayList();
        //    NodeOperations.FindNodesByName(this, name, searchAllChildren, list);
        //    Node[] nodes = new Node[list.Count];
        //    if (list.Count > 0) list.CopyTo(nodes);
        //    return nodes;
        //}
        #endregion
    }
}