context: using System;
  using System.Collections.Generic;
  using System.ComponentModel;
  using System.Drawing;
  using System.Drawing.Design;
  using System.Text;
  using System.Windows.Forms;
  
  namespace Aga.Controls.Tree.NodeControls
  {
  	public class NodeComboBox : BaseTextControl
  	{
  		#region Properties
  
  		private int _editorWidth = 100;
  		[DefaultValue(100)]
  		public int EditorWidth
  		{
  			get { return _editorWidth; }
  			set { _editorWidth = value; }
  		}
  
  		private int _editorHeight = 100;
  		[DefaultValue(100)]
  		public int EditorHeight
  		{
  			get { return _editorHeight; }
  			set { _editorHeight = value; }
  		}
  
  		private List<object> _dropDownItems;
  		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists")]
  		[Editor(typeof(StringCollectionEditor), typeof(UITypeEditor)), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
  		public List<object> DropDownItems
  		{
  			get { return _dropDownItems; }
  		}
  
  		#endregion
  
  		public event EventHandler<EditEventArgs> CreatingEditor;
  
  		public NodeComboBox()
  		{
  			_dropDownItems = new List<object>();
  		}
  
  		protected override Size CalculateEditorSize(EditorContext context)
  		{
  			if (Parent.UseColumns)
  			{
  				if (context.Editor is CheckedListBox)
  					return new Size(context.Bounds.Size.Width, EditorHeight);
  				else
  					return context.Bounds.Size;
  			}
  			else
  			{
  				if (context.Editor is CheckedListBox)
  					return new Size(EditorWidth, EditorHeight);
  				else
  					return new Size(EditorWidth, context.Bounds.Height);
  			}
  		}
  
  		protected override Control CreateEditor(TreeNodeAdv node)
  		{
  			Control c;
  			object value = GetValue(node);
  			if (IsCheckedListBoxRequired(node))
  				c = CreateCheckedListBox(node);
  			else
  				c = CreateCombo(node);
  			OnCreatingEditor(new EditEventArgs(node, c));
  			return c;
  		}
  
  		protected override void DisposeEditor(Control editor)
  		{
  		}
  
  		protected virtual void OnCreatingEditor(EditEventArgs args)
  		{
  			if (CreatingEditor != null)
  				CreatingEditor(this, args);
  		}
  
  		protected virtual bool IsCheckedListBoxRequired(TreeNodeAdv node)
  		{
  			object value = GetValue(node);
  			if (value != null)
  			{
  				Type t = value.GetType();
  				object[] arr = t.GetCustomAttributes(typeof(FlagsAttribute), false);
  				return (t.IsEnum && arr.Length == 1);
  			}
  			return false;
  		}
  
  		private Control CreateCombo(TreeNodeAdv node)
  		{
  			ComboBox comboBox = new ComboBox();
  			if (DropDownItems != null)
  				comboBox.Items.AddRange(DropDownItems.ToArray());
  			comboBox.SelectedItem = GetValue(node);
  			comboBox.DropDownStyle = ComboBoxStyle.DropDownList;
  			comboBox.DropDownClosed += new EventHandler(EditorDropDownClosed);
  			SetEditControlProperties(comboBox, node);
  			return comboBox;
  		}
  
  		private Control CreateCheckedListBox(TreeNodeAdv node)
  		{
  			CheckedListBox listBox = new CheckedListBox();
  			listBox.CheckOnClick = true;
  
  			object value = GetValue(node);
  			Type enumType = GetEnumType(node);
  			foreach (object obj in Enum.GetValues(enumType))
  			{
  				object[] attributes = enumType.GetField(obj.ToString()).GetCustomAttributes(typeof(BrowsableAttribute), false);
  				if (attributes.Length == 0 || ((BrowsableAttribute)attributes[0]).Browsable)
  					listBox.Items.Add(obj, IsContain(value, obj));
  			}
  
  			SetEditControlProperties(listBox, node);
  			if (CreatingEditor != null)
  				CreatingEditor(this, new EditEventArgs(node, listBox));
  			return listBox;
  		}
  
  		protected virtual Type GetEnumType(TreeNodeAdv node)
  		{
  			object value = GetValue(node);
  			return value.GetType();
  		}
  
  		private bool IsContain(object value, object enumElement)
  		{
  			if (value == null || enumElement == null)
  				return false;
  			if (value.GetType().IsEnum)
  			{
  				int i1 = (int)value;
  				int i2 = (int)enumElement;
  				return (i1 & i2) == i2;
  			}
  			else
  			{
  				var arr = value as object[];
  				foreach (object obj in arr)
  					if ((int)obj == (int)enumElement)
  						return true;
  				return false;
  			}
  		}
  
  		protected override string FormatLabel(object obj)
  		{
  			var arr = obj as object[];
  			if (arr != null)
  			{
  				StringBuilder sb = new StringBuilder();
  				foreach (object t in arr)
  				{
  					if (sb.Length > 0)
  						sb.Append(", ");
  					sb.Append(t);
  				}
  				return sb.ToString();
  			}
  			else
  				return base.FormatLabel(obj);
  		}
  
  		void EditorDropDownClosed(object sender, EventArgs e)
  		{
  			EndEdit(true);
  		}
  
  		public override void UpdateEditor(Control control)
  		{
  			if (control is ComboBox)
  				(control as ComboBox).DroppedDown = true;
  		}
  
  		protected override void DoApplyChanges(TreeNodeAdv node, Control editor)
  		{
  			var combo = editor as ComboBox;
  			if (combo != null)
  			{
  				if (combo.DropDownStyle == ComboBoxStyle.DropDown)
  					SetValue(node, combo.Text);
  				else
  					SetValue(node, combo.SelectedItem);
  			}
  			else
  			{
  				var listBox = editor as CheckedListBox;
  				Type type = GetEnumType(node);
  				if (IsFlags(type))
  				{
  					int res = 0;
  					foreach (object obj in listBox.CheckedItems)
  						res |= (int)obj;
  					object val = Enum.ToObject(type, res);
  					SetValue(node, val);
  				}
  				else
  				{
  
gt: 					List<object> list = new List<object>();