//===============================================================================
// 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.
//===============================================================================

#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.RecipeFramework;
using System.ComponentModel.Design;
using System.Configuration;
using Microsoft.Practices.Common;
using System.Collections.Specialized;
using System.Globalization;
using Microsoft.Practices.SoftwareFactories.ServiceFactory.Actions; 
#endregion

namespace Microsoft.Practices.SoftwareFactories.ServiceFactory.ValueProviders
{
	/// <summary>
	/// Provider that retrieves table schema information based on the configuration attributes.
	/// </summary>
	public class TableSchemaProvider : ValueProvider, IAttributesConfigurable
	{
		/// <summary>
		/// Configuration attribute that must be specified at the value provider element 
		/// that determines the connection settings to use to retrieve the table schema.
		/// The argument must have the name "ConnectionSettingArgument" and point to an 
		/// argument defined in the containing recipe. 
		/// </summary>
		public const string ConnectionSettingsArgument = "ConnectionSettingsArgument";

		/// <summary>
		/// Configuration attribute that must be specified at the value provider element 
		/// that determines the name of the argument that contains the table name to 
		/// retrieve the schema for. 
		/// The argument must have the name "TableNameArgument" and point to an 
		/// argument defined in the containing recipe. 
		/// </summary>
		public const string TableNameArgument = "TableNameArgument";

		StringDictionary attributes;

		/// <summary>
		/// Uses the <see cref="ConnectionSettingsArgument"/> to connect to the database and 
		/// using the table name of the changed argument, retrieves the table schema.
		/// </summary>
		public override bool OnArgumentChanged(string changedArgumentName, object changedArgumentValue, object currentValue, out object newValue)
		{
			System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.WaitCursor;
			try
			{
				IDictionaryService dictionary = GetService<IDictionaryService>(true);
				using (GetTableSchemaAction action = new GetTableSchemaAction())
				{
					this.Container.Add(action);
					action.ConnectionSettings = (ConnectionStringSettings)dictionary.GetValue(this.attributes[ConnectionSettingsArgument]);
					action.TableName = (string)dictionary.GetValue(this.attributes[TableNameArgument]);

					if (action.ConnectionSettings == null || action.TableName == null)
					{
						newValue = null;
						return false;
					}
					else
					{
						action.Execute();
						newValue = action.TableSchema;
						return true;
					}
				}

			}
			finally
			{
				System.Windows.Forms.Cursor.Current = System.Windows.Forms.Cursors.Default;
			}
		}

		#region IAttributesConfigurable Members

		/// <summary>
		/// Receives the name of the configuration setting to use to retrieve the list of tables.
		/// </summary>
		public void Configure(StringDictionary attributes)
		{
            if (attributes == null)
                throw new ArgumentNullException("attributes");
            
            if (!attributes.ContainsKey(ConnectionSettingsArgument) || 
				!attributes.ContainsKey(TableNameArgument))
			{
                throw new ArgumentException(
                        string.Format(CultureInfo.CurrentCulture, Properties.Resources.TableConfigureError,
                        ConnectionSettingsArgument,
                        CultureInfo.CurrentCulture.TextInfo.ListSeparator, TableNameArgument));
			}

			this.attributes = attributes;
		}

		#endregion
	}
}
