using System;
using System.Collections;
using System.ComponentModel;
namespace DevComponents.AdvTree
{
	///
	/// A strongly-typed collection of  objects.
	///
	public class CellCollection:CollectionBase 
	{
		#region Private Variables
		private Node m_ParentNode=null;
		#endregion
		#region Internal Implementation
		/// Creates new instance of the class.
		public CellCollection()
		{
		}
		/// 
		/// Adds new object to the collection.
		/// 
		/// Object to add.
		/// Index of newly added object.
		public int Add(Cell cell)
		{
			return List.Add(cell);
		}
		/// 
		/// Returns reference to the object in collection based on it's index.
		/// 
		public Cell this[int index]
		{
			get {return (Cell)(List[index]);}
			set {List[index] = value;}
		}
        /// 
        /// Returns reference to the object in collection based on it's name. Returns null/nothing if cell with given name is not found.
        /// 
        public Cell this[string name]
        {
            get 
            {
                foreach (Cell item in List)
                {
                    if (item.Name == name) return item;
                }
                return null;
            }
        }
        /// 
        /// Gets the cell based on the column name. Node must be able to reach AdvTree control for this method to work.
        /// 
        /// Column name.
        /// Cell object or null.
        public Cell GetByColumnName(string columnName)
        {
            if (string.IsNullOrEmpty(columnName))
                throw new ArgumentException("columnName argument must be non-empty non-null string with column name");
            Node parentNode = this.ParentNode;
            AdvTree tree = parentNode.TreeControl;
            if (tree == null)
                throw new NullReferenceException("AdvTree control cannot be reached. Node is not added to a tree.");
            Cell cell = null;
            if (parentNode.Parent != null && parentNode.Parent.NodesColumns.Count > 0)
            {
                int index= parentNode.Parent.NodesColumns.IndexOf(columnName);
                if (index >= 0) cell = this[index];
            }
            else
            {
                int index = tree.Columns.IndexOf(columnName);
                if (index >= 0) cell = this[index];
            }
            return cell;
        }
		/// 
		/// Inserts new object into the collection.
		/// 
		/// Position of the object.
		/// Object to insert.
		public void Insert(int index, Cell 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(Cell 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(Cell value) 
		{
			return List.Contains(value);
		}
		/// 
		/// Removes specified object from the collection.
		/// 
		/// 
		public void Remove(Cell value) 
		{
			List.Remove(value);
		}
		protected override void OnRemoveComplete(int index,object value)
		{
			base.OnRemoveComplete(index,value);
			Cell cell=value as Cell;
			cell.SetParent(null);
			if(m_ParentNode!=null)
				m_ParentNode.OnCellRemoved(cell);
		}
		protected override void OnInsertComplete(int index,object value)
		{
			base.OnInsertComplete(index,value);
			Cell cell=value as Cell;
			if(cell.Parent!=null && cell.Parent!=m_ParentNode)
				cell.Parent.Cells.Remove(cell);
			cell.SetParent(m_ParentNode);
			if(m_ParentNode!=null)
				m_ParentNode.OnCellInserted(cell);
		}
        protected override void OnInsert(int index, object value)
        {
            if (m_ParentNode != null && m_ParentNode.Site != null && m_ParentNode.Site.DesignMode && this.List.Count > 0)
            {
                Cell cell = value as Cell;
                if (cell.Site == null && this.List.Contains(cell)) this.List.Remove(cell);
            }
            base.OnInsert(index, value);
        }
		/// 
		/// Copies collection into the specified array.
		/// 
		/// Array to copy collection to.
		/// Starting index.
		public void CopyTo(Cell[] array, int index) 
		{
			List.CopyTo(array, index);
		}
		/// 
		/// Copies contained items to the Cell array.
		/// 
		/// Array to copy to.
		internal void CopyTo(Cell[] array)
		{
			List.CopyTo(array,0);
		}
        private Cell _RootCell = null;
		protected override void OnClear()
		{
            if (m_ParentNode != null && m_ParentNode.Site != null && m_ParentNode.Site.DesignMode && this.List.Count>0)
            {
                if (this[0].Site == null)
                    _RootCell = this[0];
            }
			base.OnClear();
		}
        protected override void OnClearComplete()
        {
            base.OnClearComplete();
            if (_RootCell != null)
            {
                this.Add(_RootCell);
                _RootCell = null;
            }
        }
        protected override void OnSet(int index, object oldValue, object newValue)
        {
            base.OnSet(index, oldValue, newValue);
        }
		/// 
		/// Gets or sets the node this collection is associated with.
		/// 
		[Browsable(false),DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public Node ParentNode
		{
			get {return m_ParentNode;}
		}
		/// 
		/// Sets the node collection belongs to.
		/// 
		/// Cell that is parent of this collection.
		internal void SetParentNode(Node parent)
		{
			m_ParentNode=parent;
		}
		#endregion
	}
}