moel@345: using System;
moel@345: using System.Collections.Generic;
moel@345: using System.Text;
moel@345: using System.Collections.ObjectModel;
moel@345: using System.Windows.Forms;
moel@345: using System.Drawing;
moel@345: 
moel@345: namespace Aga.Controls.Tree
moel@345: {
moel@345: 	public class Node
moel@345: 	{
moel@345: 		#region NodeCollection
moel@345: 
moel@345: 		private class NodeCollection : Collection<Node>
moel@345: 		{
moel@345: 			private Node _owner;
moel@345: 
moel@345: 			public NodeCollection(Node owner)
moel@345: 			{
moel@345: 				_owner = owner;
moel@345: 			}
moel@345: 
moel@345: 			protected override void ClearItems()
moel@345: 			{
moel@345: 				while (this.Count != 0)
moel@345: 					this.RemoveAt(this.Count - 1);
moel@345: 			}
moel@345: 
moel@345: 			protected override void InsertItem(int index, Node item)
moel@345: 			{
moel@345: 				if (item == null)
moel@345: 					throw new ArgumentNullException("item");
moel@345: 
moel@345: 				if (item.Parent != _owner)
moel@345: 				{
moel@345: 					if (item.Parent != null)
moel@345: 						item.Parent.Nodes.Remove(item);
moel@345: 					item._parent = _owner;
moel@345: 					item._index = index;
moel@345: 					for (int i = index; i < Count; i++)
moel@345: 						this[i]._index++;
moel@345: 					base.InsertItem(index, item);
moel@345: 
moel@345: 					TreeModel model = _owner.FindModel();
moel@345: 					if (model != null)
moel@345: 						model.OnNodeInserted(_owner, index, item);
moel@345: 				}
moel@345: 			}
moel@345: 
moel@345: 			protected override void RemoveItem(int index)
moel@345: 			{
moel@345: 				Node item = this[index];
moel@345: 				item._parent = null;
moel@345: 				item._index = -1;
moel@345: 				for (int i = index + 1; i < Count; i++)
moel@345: 					this[i]._index--;
moel@345: 				base.RemoveItem(index);
moel@345: 
moel@345: 				TreeModel model = _owner.FindModel();
moel@345: 				if (model != null)
moel@345: 					model.OnNodeRemoved(_owner, index, item);
moel@345: 			}
moel@345: 
moel@345: 			protected override void SetItem(int index, Node item)
moel@345: 			{
moel@345: 				if (item == null)
moel@345: 					throw new ArgumentNullException("item");
moel@345: 
moel@345: 				RemoveAt(index);
moel@345: 				InsertItem(index, item);
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		#endregion
moel@345: 
moel@345: 		#region Properties
moel@345: 
moel@345: 		private TreeModel _model;
moel@345: 		internal TreeModel Model
moel@345: 		{
moel@345: 			get { return _model; }
moel@345: 			set { _model = value; }
moel@345: 		}
moel@345: 
moel@345: 		private NodeCollection _nodes;
moel@345: 		public Collection<Node> Nodes
moel@345: 		{
moel@345: 			get { return _nodes; }
moel@345: 		}
moel@345: 
moel@345: 		private Node _parent;
moel@345: 		public Node Parent
moel@345: 		{
moel@345: 			get { return _parent; }
moel@345: 			set 
moel@345: 			{
moel@345: 				if (value != _parent)
moel@345: 				{
moel@345: 					if (_parent != null)
moel@345: 						_parent.Nodes.Remove(this);
moel@345: 
moel@345: 					if (value != null)
moel@345: 						value.Nodes.Add(this);
moel@345: 				}
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		private int _index = -1;
moel@345: 		public int Index
moel@345: 		{
moel@345: 			get
moel@345: 			{
moel@345: 				return _index;
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		public Node PreviousNode
moel@345: 		{
moel@345: 			get
moel@345: 			{
moel@345: 				int index = Index;
moel@345: 				if (index > 0)
moel@345: 					return _parent.Nodes[index - 1];
moel@345: 				else
moel@345: 					return null;
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		public Node NextNode
moel@345: 		{
moel@345: 			get
moel@345: 			{
moel@345: 				int index = Index;
moel@345: 				if (index >= 0 && index < _parent.Nodes.Count - 1)
moel@345: 					return _parent.Nodes[index + 1];
moel@345: 				else
moel@345: 					return null;
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		private string _text;
moel@345: 		public virtual string Text
moel@345: 		{
moel@345: 			get { return _text; }
moel@345: 			set 
moel@345: 			{
moel@345: 				if (_text != value)
moel@345: 				{
moel@345: 					_text = value;
moel@345: 					NotifyModel();
moel@345: 				}
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		private CheckState _checkState;
moel@345: 		public virtual CheckState CheckState
moel@345: 		{
moel@345: 			get { return _checkState; }
moel@345: 			set 
moel@345: 			{
moel@345: 				if (_checkState != value)
moel@345: 				{
moel@345: 					_checkState = value;
moel@345: 					NotifyModel();
moel@345: 				}
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		private Image _image;
moel@345: 		public Image Image
moel@345: 		{
moel@345: 			get { return _image; }
moel@345: 			set 
moel@345: 			{
moel@345: 				if (_image != value)
moel@345: 				{
moel@345: 					_image = value;
moel@345: 					NotifyModel();
moel@345: 				}
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		private object _tag;
moel@345: 		public object Tag
moel@345: 		{
moel@345: 			get { return _tag; }
moel@345: 			set { _tag = value; }
moel@345: 		}
moel@345: 
moel@345: 		public bool IsChecked
moel@345: 		{
moel@345: 			get 
moel@345: 			{ 
moel@345: 				return CheckState != CheckState.Unchecked;
moel@345: 			}
moel@345: 			set 
moel@345: 			{
moel@345: 				if (value)
moel@345: 					CheckState = CheckState.Checked;
moel@345: 				else
moel@345: 					CheckState = CheckState.Unchecked;
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		public virtual bool IsLeaf
moel@345: 		{
moel@345: 			get
moel@345: 			{
moel@345: 				return false;
moel@345: 			}
moel@345: 		}
moel@345: 
moel@345: 		#endregion
moel@345: 
moel@345: 		public Node()
moel@345: 			: this(string.Empty)
moel@345: 		{
moel@345: 		}
moel@345: 
moel@345: 		public Node(string text)
moel@345: 		{
moel@345: 			_text = text;
moel@345: 			_nodes = new NodeCollection(this);
moel@345: 		}
moel@345: 
moel@345: 		public override string ToString()
moel@345: 		{
moel@345: 			return Text;
moel@345: 		}
moel@345: 
moel@345: 		private TreeModel FindModel()
moel@345: 		{
moel@345: 			Node node = this;
moel@345: 			while (node != null)
moel@345: 			{
moel@345: 				if (node.Model != null)
moel@345: 					return node.Model;
moel@345: 				node = node.Parent;
moel@345: 			}
moel@345: 			return null;
moel@345: 		}
moel@345: 
moel@345: 		protected void NotifyModel()
moel@345: 		{
moel@345: 			TreeModel model = FindModel();
moel@345: 			if (model != null && Parent != null)
moel@345: 			{
moel@345: 				TreePath path = model.GetPath(Parent);
moel@345: 				if (path != null)
moel@345: 				{
moel@345: 					TreeModelEventArgs args = new TreeModelEventArgs(path, new int[] { Index }, new object[] { this });
moel@345: 					model.OnNodesChanged(args);
moel@345: 				}
moel@345: 			}
moel@345: 		}
moel@345: 	}
moel@345: }