//===============================================================================
// Microsoft patterns & practices
// Web Service Software Factory
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using Microsoft.VisualStudio.Shell.Design;
using Microsoft.VisualStudio.Shell.Interop;
using System.ComponentModel.Design;
using Microsoft.Practices.RecipeFramework.Library;

namespace Microsoft.Practices.SoftwareFactories.ServiceFactory.Editors.Grid.Design
{
	/// <summary>
	/// DataGridView column to collect types supporting autocomplete
	/// </summary>
	public class TypeColumn : DesignerColumn
	{
		private AutoCompleteStringCollection autoCompleteSource;

		public TypeColumn()
			: base(new TypeColumnCell())
		{
		}

		protected TypeColumn(DataGridViewCell template)
			: base(template)
		{
		}

		/// <summary>
		/// Overriding this method can filter the types shown for autocomplete
		/// </summary>
		/// <param name="type">The type to accept or reject</param>
		/// <returns>The default value is true</returns>
		protected virtual bool AcceptType(Type type)
		{
			return true;
		}

		/// <summary>
		/// Returns the discovered types for autocomplete
		/// </summary>
		protected virtual IEnumerable<Type> DiscoverTypes()
		{
			DynamicTypeService typeService = (DynamicTypeService)DataGridView.Site.GetService(typeof(DynamicTypeService));
			IVsHierarchy hier = DteHelper.GetCurrentSelection(DataGridView.Site);
			ITypeDiscoveryService typeDiscoveryService = typeService.GetTypeDiscoveryService(hier);

			return (IEnumerable<Type>)typeDiscoveryService.GetTypes(typeof(object), false);
		}

		/// <summary>
		/// Creates the <see cref="AutoCompleteStringCollection"/> with all the types
		/// </summary>
		private AutoCompleteStringCollection GetAutocompleteSource()
		{
			if (autoCompleteSource == null)
			{
				List<string> types = new List<string>();

				foreach (Type type in DiscoverTypes())
				{
					if (AcceptType(type))
						types.Add(type.FullName);
				}

				autoCompleteSource = new AutoCompleteStringCollection();
				autoCompleteSource.AddRange(types.ToArray());
			}

			return autoCompleteSource;
		}

		public class TypeColumnCell : DesignerColumn.DesignerCell
		{
			public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
			{
				base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);

				TextBox textBox = DataGridView.EditingControl as TextBox;
				if (textBox != null)
				{
					// Setup textbox autocomplete
					textBox.AutoCompleteCustomSource = ((TypeColumn)OwningColumn).GetAutocompleteSource();
					textBox.AutoCompleteMode = AutoCompleteMode.Suggest;
					textBox.AutoCompleteSource = AutoCompleteSource.CustomSource;
				}
			}

			public override void DetachEditingControl()
			{
				TextBox textBox = DataGridView.EditingControl as TextBox;
				if (textBox != null)
				{
					textBox.AutoCompleteCustomSource = null;
					textBox.AutoCompleteMode = AutoCompleteMode.None;
					textBox.AutoCompleteSource = AutoCompleteSource.None;
				}
				base.DetachEditingControl();
			}
		}
	}
}
