namespace FormLayout
{
	using System;
	using Microsoft.VisualStudio.CommandBars;
	using Extensibility;
	using EnvDTE;
	using EnvDTE80;

	/// <summary>The object for implementing an Add-in.</summary>
	/// <seealso class='IDTExtensibility2' />
	public class Connect : Object, IDTExtensibility2, IDTCommandTarget
	{
		/// <summary>Implements the constructor for the Add-in object. Place your initialization code within this method.</summary>
		public Connect()
		{
		}

		/// <summary>Implements the OnConnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being loaded.</summary>
		/// <param term='application'>Root object of the host application.</param>
		/// <param term='connectMode'>Describes how the Add-in is being loaded.</param>
		/// <param term='addInInst'>Object representing this Add-in.</param>
		/// <seealso class='IDTExtensibility2' />
		public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
		{
			_applicationObject = (DTE2)application;
			_addInInstance = (AddIn)addInInst;
			if(connectMode == ext_ConnectMode.ext_cm_UISetup)
			{
				object []contextGUIDS = new object[] { };
				Commands2 commands = (Commands2)_applicationObject.Commands;

				try
				{					
					CommandBar menuBarCommandBar;
					CommandBarControl toolsControl;
					CommandBarPopup toolsPopup;
					CommandBarControl commandBarControl;
					
					//Add a command to the Commands collection:
					Command command = commands.AddNamedCommand2(_addInInstance, "FormLayout", "Form Layout Window", "Shows the Form Layout window.", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);

					String toolsMenuName;
					try
					{
						//If you would like to move the command to a different menu, change the word "Tools" to the 
						//  English version of the menu. This code will take the culture, append on the name of the menu
						//  then add the command to that menu. You can find a list of all the top-level menus in the file
						//  CommandBar.resx.
						System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager("FormLayout.CommandBar", System.Reflection.Assembly.GetExecutingAssembly());
						System.Threading.Thread thread = System.Threading.Thread.CurrentThread;
						System.Globalization.CultureInfo cultureInfo = thread.CurrentCulture;
						toolsMenuName = resourceManager.GetString(String.Concat(cultureInfo.TwoLetterISOLanguageName, "Tools"));
					}
					catch(Exception)
					{
						//We tried to find a localized version of the word Tools, but one was not found.
						//  Default to the en-US word, which may work for the current culture.
						toolsMenuName = "Tools";
					}

					//Place the command on the tools menu.
					//Find the MenuBar command bar, which is the top-level command bar holding all the main menu items:
					menuBarCommandBar = ((CommandBars)_applicationObject.CommandBars)["MenuBar"];

					//Find the Tools command bar on the MenuBar command bar:
					toolsControl = menuBarCommandBar.Controls[toolsMenuName];
					toolsPopup = (CommandBarPopup)toolsControl;

					//Find the appropriate command bar on the MenuBar command bar:
					commandBarControl = (CommandBarControl)command.AddControl(toolsPopup.CommandBar, 1);
				}
				catch(Exception)
				{
				}
			}
		}

		/// <summary>Implements the OnDisconnection method of the IDTExtensibility2 interface. Receives notification that the Add-in is being unloaded.</summary>
		/// <param term='disconnectMode'>Describes how the Add-in is being unloaded.</param>
		/// <param term='custom'>Array of parameters that are host application specific.</param>
		/// <seealso class='IDTExtensibility2' />
		public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
		{
		}

		/// <summary>Implements the OnAddInsUpdate method of the IDTExtensibility2 interface. Receives notification when the collection of Add-ins has changed.</summary>
		/// <param term='custom'>Array of parameters that are host application specific.</param>
		/// <seealso class='IDTExtensibility2' />		
		public void OnAddInsUpdate(ref Array custom)
		{
		}

		/// <summary>Implements the OnStartupComplete method of the IDTExtensibility2 interface. Receives notification that the host application has completed loading.</summary>
		/// <param term='custom'>Array of parameters that are host application specific.</param>
		/// <seealso class='IDTExtensibility2' />
		public void OnStartupComplete(ref Array custom)
		{
		}

		/// <summary>Implements the OnBeginShutdown method of the IDTExtensibility2 interface. Receives notification that the host application is being unloaded.</summary>
		/// <param term='custom'>Array of parameters that are host application specific.</param>
		/// <seealso class='IDTExtensibility2' />
		public void OnBeginShutdown(ref Array custom)
		{
		}
		
		/// <summary>Implements the QueryStatus method of the IDTCommandTarget interface. This is called when the command's availability is updated</summary>
		/// <param term='commandName'>The name of the command to determine state for.</param>
		/// <param term='neededText'>Text that is needed for the command.</param>
		/// <param term='status'>The state of the command in the user interface.</param>
		/// <param term='commandText'>Text requested by the neededText parameter.</param>
		/// <seealso class='Exec' />
		public void QueryStatus(string commandName, vsCommandStatusTextWanted neededText, ref vsCommandStatus status, ref object commandText)
		{
			if(neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
			{
				if(commandName == "FormLayout.Connect.FormLayout")
				{
					status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported|vsCommandStatus.vsCommandStatusEnabled;
					return;
				}
			}
		}

		/// <summary>Implements the Exec method of the IDTCommandTarget interface. This is called when the command is invoked.</summary>
		/// <param term='commandName'>The name of the command to execute.</param>
		/// <param term='executeOption'>Describes how the command should be run.</param>
		/// <param term='varIn'>Parameters passed from the caller to the command handler.</param>
		/// <param term='varOut'>Parameters passed from the command handler to the caller.</param>
		/// <param term='handled'>Informs the caller if the command was handled or not.</param>
		/// <seealso class='Exec' />
		public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
		{
			handled = false;
			if(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
			{
				if(commandName == "FormLayout.Connect.FormLayout")
				{
					if (_toolWindow == null)
					{
						object controlObject = null;
						FormLayoutCtl formLayoutCtl;

						//Find this assembly, the assembly implementing our control.
						string codeBase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;

						//Create a tool window based upon the user control in our project
						_toolWindow = ((EnvDTE80.Windows2)_applicationObject.Windows).CreateToolWindow2(_addInInstance, codeBase, "FormLayout.FormLayoutCtl", "Form Layout", "{FC718A2D-EEE9-435b-AD82-C10A97F6B380}", ref controlObject);

						//Retrieve the FormLayoutCtl instance, and hand off a DTE object
						formLayoutCtl = (FormLayoutCtl)controlObject;
						formLayoutCtl.SetDTE(_applicationObject);
					}

					//Show the tool window
					_toolWindow.Visible = true;
					handled = true;
					return;
				}
			}
		}
		private DTE2 _applicationObject;
		private AddIn _addInInstance;
		private EnvDTE.Window _toolWindow;
	}
}