using System;
using System.Collections.Generic;
using System.Drawing.Design;
using System.Text;
using System.Windows.Forms.Design;
using System.Windows.Forms;
using Microsoft.Data.ConnectionUI;
using Microsoft.Practices.Common;
using System.Collections.Specialized;
using System.ComponentModel.Design;
using System.Configuration;
using System.Reflection;
using System.IO;
using Howest.Guidance.Extensions.Common.Data;
using Howest.Guidance.Extensions.Common.Configuration;
using System.Globalization;


namespace Howest.Guidance.Extensions.Editors
{
	public class ConnectionStringEditor : UITypeEditor, IAttributesConfigurable
	{
		public const string PROVIDERARGUMENT = "ProviderArgument";

		private string _providerArgument;

		public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
		{
			return UITypeEditorEditStyle.Modal;
		}

		public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
		{
			DataConnectionDialog dlg = new DataConnectionDialog();

			
			// Add DataSources from config
			//string exePath = Path.GetFileName(this.GetType().Assembly.Location);

			AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

			Configuration config = ConfigurationManager.OpenExeConfiguration(this.GetType().Assembly.Location);
			try
			{
				ExtensionsSectionGroup grp = ExtensionsSectionGroup.GetSectionGroup(config);
				if (grp != null)
				{
					DataProvidersSection providerSection = grp.DataProviders;

					foreach (DataProviderElement prov in providerSection.DataProviders)
					{
						try
						{
							DataSource source = new DataSource(prov.Name, prov.DataSourceDisplayName);
							Type connectionType = ReflectionHelper.LoadType(prov.ConnectionType);
							Type providerObjectFactoryType = ReflectionHelper.LoadType(prov.ProviderObjectFactoryType);
							ExtensionsDataProvider dataProvider = new ExtensionsDataProvider(
								connectionType.Namespace,
								prov.DisplayName,
								prov.ShortDisplayName,
								prov.Description,
								connectionType,
								providerObjectFactoryType);
							source.Providers.Add(dataProvider);
							dlg.DataSources.Add(source);
						}
						catch(Exception ex)
						{
							System.Diagnostics.Debug.WriteLine("Message: " + ex.Message);
							System.Diagnostics.Debug.WriteLine("StackTrace: " + ex.StackTrace);
						}
					}
				}

				// Display the editor
				IUIService uisvc = (IUIService)provider.GetService(typeof(IUIService));
				IWin32Window owner = uisvc != null ? uisvc.GetDialogOwnerWindow() : null;

				if (DataConnectionDialog.Show(dlg, owner) == DialogResult.OK)
				{
					if (_providerArgument != null)
					{
						IDictionaryService dictionary = (IDictionaryService)provider.GetService(typeof(IDictionaryService));
						if (dictionary != null)
						{
							try
							{
								dictionary.SetValue(_providerArgument, dlg.SelectedDataProvider.Name);
							}
							catch
							{
							}
						}
					}
					return dlg.ConnectionString;
				}
				else
				{
					return value;
				}
			}
			finally
			{
				AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
			}

			//return base.EditValue(context, provider, value);
		}

		Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
		{
			//AssemblyName name = ReflectionHelper.ParseAssemblyName(args.Name);
			AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);
			Assembly asm;
			try
			{
				 asm = Assembly.Load(args.Name);
			}
			finally
			{
				AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
			}
			return asm;
		}

		#region IAttributesConfigurable Members

		public void Configure(StringDictionary attributes)
		{
			if (attributes.ContainsKey(PROVIDERARGUMENT))
				_providerArgument = attributes[PROVIDERARGUMENT];
		}

		#endregion
	}
}
