using System;
using System.Windows.Forms;

namespace ExtensionMethods
{
	/// <summary>
	/// <para>Add extensions to <c><see cref="ComboBox"/></c></para>
	/// </summary>
	public static class ComboBoxExtensions
	{
		/// <summary>
		/// <para>Indicates whether the content of the specified <see cref="ComboBox"/> is null or an <see cref="String.Empty"/> string</para>
		/// </summary>
		/// <param name="cb"></param>
		/// <returns><see cref="bool"/>. True: ComboBox is empty. False: ComboBox is not empty</returns>
		public static bool IsEmpty(this ComboBox cb)
		{
			return String.IsNullOrEmpty(cb.Text);
		}

		/// <summary>
		/// <para>Indicates whether the content of the specified <see cref="ComboBox"/> is not null and not an <see cref="String.Empty"/> string</para>
		/// </summary>
		/// <param name="cb"><see cref="ComboBox"/></param>
		/// <returns><see cref="bool"/>. True: ComboBox is not empty. False: ComboBox is empty</returns>
		public static bool IsNotEmpty(this ComboBox cb)
		{
			return !String.IsNullOrEmpty(cb.Text);
		}

		/// <summary>
		/// <para>Creates a <see cref="TextBox"/> that mirrors this <see cref="ComboBox"/>.</para>
		/// </summary>
		/// <param name="cb"><see cref="ComboBox"/></param>
		/// <returns><see cref="TextBox"/> with same size and content as the <see cref="ComboBox"/></returns>
		public static TextBox GetMirrorTextbox(this ComboBox cb)
		{
			TextBox textBox = null;
			// Search for already existing TextBox
			if (cb.Parent != null)
			{
				Control[] x = cb.Parent.Controls.Find("txt" + cb.Name, false);
				if (x.Length > 0)
				{
					textBox = (TextBox)x[0];
					return textBox;
				}
			}

			// Generate a new TextBox
			textBox = new TextBox();
			textBox.Location = cb.Location;
			textBox.Size = cb.Size;
			textBox.Name = "txt" + cb.Name;

			/*// Copy events
			CopyEventHandlers ceh = new CopyEventHandlers();
			ceh.GetHandlersFrom(cb).CopyTo(textBox);*/

			// Copy attributes
			textBox.BackColor = cb.BackColor;
			cb.BackColorChanged += new EventHandler((object sender, EventArgs e) => { textBox.BackColor = ((ComboBox)sender).BackColor; });
			textBox.ForeColor = cb.ForeColor;
			cb.ForeColorChanged += new EventHandler((object sender, EventArgs e) => { textBox.ForeColor = ((ComboBox)sender).ForeColor; });
			textBox.Font = cb.Font;
			cb.FontChanged += new EventHandler((object sender, EventArgs e) => { textBox.Font = ((ComboBox)sender).Font; });

			// Copy text
			textBox.Text = cb.Text;
			EventHandler eventHandler = new EventHandler((object sender, EventArgs e) => { textBox.Text = ((ComboBox)sender).Text; });
			cb.TextChanged += eventHandler;
			cb.SelectedIndexChanged += eventHandler;

			if (cb.Parent != null)
				cb.Parent.Controls.Add(textBox);
			
			
			return textBox;
		}

		/// <summary>
		/// <para>Simulates a <see cref="ReadOnly"/> property for <see cref="ComboBox"/> by creating a new <see cref="TextBox"/> with same size, location and content.
		/// Then one of both is hidden and the other shown.</para>
		/// </summary>
		/// <param name="cb"><see cref="ComboBox"/></param>
		/// <param name="readOnly"><see cref="bool"/>. True: Show <see cref="TextBox"/>; False: Show <see cref="ComboBox"/></param>
		public static void ReadOnly(this ComboBox cb, bool readOnly)
		{
			TextBox textBox = cb.GetMirrorTextbox();

			textBox.ReadOnly = true;
			textBox.Cursor = Cursors.Arrow;
			textBox.Visible = readOnly;
			cb.Visible = !readOnly;
			cb.Enabled = !readOnly;
		}

		/// <summary>
		/// <para>Clears all text from the <see cref="ComboBox"/> <see cref="Control"/></para>
		/// </summary>
		/// <param name="cb"><see cref="ComboBox"/></param>
		public static void Clear(this ComboBox cb)
		{
			cb.Text = String.Empty;
		}
	}
}