//===========================================================================
// 引用到FPMS项目中，只是做了界面的汉化处理和格局的部分调整
// 版权信息参考下面的信息。
//
//=============================================================================
//============================================================================================================
// Microsoft Updater Application Block for .NET
//  http://msdn.microsoft.com/library/en-us/dnbda/html/updater.asp
//	
// ManifestUtilityMainForm.cs
// 
//============================================================================================================
// Copyright (C) 2000-2001 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/OR
// FITNESS FOR A PARTICULAR PURPOSE.
//============================================================================================================



//  define this compiler directive IF YOU ARE USING FRAMEWORK VERSION 1.1:
//  FX 1.0 does not support the FolderBrowserDialog component, so we must manually enter the 
//  physical folder path to look for updates.  By defining this directive, we tell compiler
//  OK to use folder-browser component in 1.1

//  ****  IF YOU ARE USING FRAMEWORK 1.0 ONLY, then comment the following line:
#define FRAMEWORK_1_1


using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Reflection;
using System.IO;
using System.Xml;
using System.Threading;
using System.Text;
using Microsoft.ApplicationBlocks.ApplicationUpdater.Interfaces;




namespace ManifestUtility
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class ManifestUtilityMainForm : System.Windows.Forms.Form
	{

		#region declarations

		private System.Windows.Forms.Label folderLbl;
		private System.Windows.Forms.TextBox folderPath;
		private System.Windows.Forms.Button browseForFolder;
		private System.Windows.Forms.Label updateLocationLbl;
		private System.Windows.Forms.TextBox updateLocation;
		private System.Windows.Forms.Label versionLbl;
		private System.Windows.Forms.TextBox version;
		private System.Windows.Forms.TextBox key;
		private System.Windows.Forms.Label keyLbl;
		private System.Windows.Forms.Button browseForKey;
		private System.Windows.Forms.Label validatorAssemblyLbl;
		private System.Windows.Forms.TextBox validatorAssembly;
		private System.Windows.Forms.Button browseForValidatorAssembly;
		private System.Windows.Forms.Label validatorClassLbl;
		private System.Windows.Forms.ComboBox validatorClass;
		private System.Windows.Forms.Label postProcessorAssemblyLbl;
		private System.Windows.Forms.CheckBox usePostProcessor;
		private System.Windows.Forms.TextBox postProcessorAssembly;
		private System.Windows.Forms.Button browseForPostProcessor;
		private System.Windows.Forms.ComboBox postProcessorClass;
		private System.Windows.Forms.Label postProcessorClassLbl;
		private System.Windows.Forms.Button createManifest;
//  can only use this object w/ FX1.1
#if FRAMEWORK_1_1
		private System.Windows.Forms.FolderBrowserDialog folderDialog;
#endif
		private System.Windows.Forms.OpenFileDialog validatorDialog;
		private System.Windows.Forms.OpenFileDialog postProcessorDialog;
		private System.Windows.Forms.SaveFileDialog manifestDialog;
		private System.Windows.Forms.OpenFileDialog keyDialog;
		private System.Windows.Forms.MainMenu mainMenu1;
		private System.Windows.Forms.SaveFileDialog newKeyDialog;
		private System.Windows.Forms.MenuItem fileMenu;
		private System.Windows.Forms.MenuItem fileCreateManifestMenu;
		private System.Windows.Forms.MenuItem fileGenerateKeysMenu;
		private System.Windows.Forms.MenuItem fileExitMenu;

		private System.Windows.Forms.ToolTip toolTip1;
		private System.ComponentModel.IContainer components;
		#endregion

		#region Standard Form Stuff
		public ManifestUtilityMainForm()
		{
			InitializeComponent();
			SetToolTips();
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.components = new System.ComponentModel.Container();
			this.folderLbl = new System.Windows.Forms.Label();
			this.folderPath = new System.Windows.Forms.TextBox();
			this.browseForFolder = new System.Windows.Forms.Button();
			this.updateLocationLbl = new System.Windows.Forms.Label();
			this.updateLocation = new System.Windows.Forms.TextBox();
			this.versionLbl = new System.Windows.Forms.Label();
			this.version = new System.Windows.Forms.TextBox();
			this.key = new System.Windows.Forms.TextBox();
			this.keyLbl = new System.Windows.Forms.Label();
			this.browseForKey = new System.Windows.Forms.Button();
			this.validatorAssemblyLbl = new System.Windows.Forms.Label();
			this.validatorAssembly = new System.Windows.Forms.TextBox();
			this.browseForValidatorAssembly = new System.Windows.Forms.Button();
			this.validatorClassLbl = new System.Windows.Forms.Label();
			this.validatorClass = new System.Windows.Forms.ComboBox();
			this.postProcessorAssemblyLbl = new System.Windows.Forms.Label();
			this.usePostProcessor = new System.Windows.Forms.CheckBox();
			this.postProcessorAssembly = new System.Windows.Forms.TextBox();
			this.browseForPostProcessor = new System.Windows.Forms.Button();
			this.postProcessorClass = new System.Windows.Forms.ComboBox();
			this.postProcessorClassLbl = new System.Windows.Forms.Label();
			this.createManifest = new System.Windows.Forms.Button();
			this.folderDialog = new System.Windows.Forms.FolderBrowserDialog();
			this.validatorDialog = new System.Windows.Forms.OpenFileDialog();
			this.postProcessorDialog = new System.Windows.Forms.OpenFileDialog();
			this.manifestDialog = new System.Windows.Forms.SaveFileDialog();
			this.keyDialog = new System.Windows.Forms.OpenFileDialog();
			this.mainMenu1 = new System.Windows.Forms.MainMenu();
			this.fileMenu = new System.Windows.Forms.MenuItem();
			this.fileCreateManifestMenu = new System.Windows.Forms.MenuItem();
			this.fileGenerateKeysMenu = new System.Windows.Forms.MenuItem();
			this.fileExitMenu = new System.Windows.Forms.MenuItem();
			this.newKeyDialog = new System.Windows.Forms.SaveFileDialog();
			this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
			this.SuspendLayout();
			// 
			// folderLbl
			// 
			this.folderLbl.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.folderLbl.Location = new System.Drawing.Point(19, 16);
			this.folderLbl.Name = "folderLbl";
			this.folderLbl.Size = new System.Drawing.Size(135, 17);
			this.folderLbl.TabIndex = 0;
			this.folderLbl.Text = "更新文件路径：";
			// 
			// folderPath
			// 
			this.folderPath.Font = new System.Drawing.Font("Century Gothic", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.folderPath.Location = new System.Drawing.Point(163, 17);
			this.folderPath.Name = "folderPath";
			this.folderPath.ReadOnly = true;
			this.folderPath.Size = new System.Drawing.Size(538, 21);
			this.folderPath.TabIndex = 1;
			this.folderPath.Text = "C:\\";
			// 
			// browseForFolder
			// 
			this.browseForFolder.BackColor = System.Drawing.Color.Gold;
			this.browseForFolder.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.browseForFolder.Location = new System.Drawing.Point(710, 17);
			this.browseForFolder.Name = "browseForFolder";
			this.browseForFolder.Size = new System.Drawing.Size(29, 25);
			this.browseForFolder.TabIndex = 2;
			this.browseForFolder.Text = "...";
			this.browseForFolder.Click += new System.EventHandler(this.browseForFolder_Click);
			// 
			// updateLocationLbl
			// 
			this.updateLocationLbl.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.updateLocationLbl.Location = new System.Drawing.Point(19, 48);
			this.updateLocationLbl.Name = "updateLocationLbl";
			this.updateLocationLbl.Size = new System.Drawing.Size(135, 25);
			this.updateLocationLbl.TabIndex = 3;
			this.updateLocationLbl.Text = "服务器虚拟路径：";
			// 
			// updateLocation
			// 
			this.updateLocation.Font = new System.Drawing.Font("Century Gothic", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.updateLocation.Location = new System.Drawing.Point(163, 52);
			this.updateLocation.Name = "updateLocation";
			this.updateLocation.Size = new System.Drawing.Size(538, 21);
			this.updateLocation.TabIndex = 4;
			this.updateLocation.Text = "http://localhost/appupdater";
			// 
			// versionLbl
			// 
			this.versionLbl.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.versionLbl.Location = new System.Drawing.Point(19, 88);
			this.versionLbl.Name = "versionLbl";
			this.versionLbl.Size = new System.Drawing.Size(135, 25);
			this.versionLbl.TabIndex = 5;
			this.versionLbl.Text = "版本号：";
			// 
			// version
			// 
			this.version.Font = new System.Drawing.Font("Century Gothic", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.version.Location = new System.Drawing.Point(163, 86);
			this.version.Name = "version";
			this.version.Size = new System.Drawing.Size(538, 21);
			this.version.TabIndex = 6;
			this.version.Text = "2.0.0.0";
			// 
			// key
			// 
			this.key.Font = new System.Drawing.Font("Century Gothic", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.key.Location = new System.Drawing.Point(163, 121);
			this.key.Multiline = true;
			this.key.Name = "key";
			this.key.Size = new System.Drawing.Size(538, 103);
			this.key.TabIndex = 7;
			this.key.Text = "";
			// 
			// keyLbl
			// 
			this.keyLbl.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.keyLbl.Location = new System.Drawing.Point(19, 121);
			this.keyLbl.Name = "keyLbl";
			this.keyLbl.Size = new System.Drawing.Size(125, 24);
			this.keyLbl.TabIndex = 8;
			this.keyLbl.Text = "密匙：";
			// 
			// browseForKey
			// 
			this.browseForKey.BackColor = System.Drawing.Color.Gold;
			this.browseForKey.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.browseForKey.Location = new System.Drawing.Point(710, 198);
			this.browseForKey.Name = "browseForKey";
			this.browseForKey.Size = new System.Drawing.Size(29, 25);
			this.browseForKey.TabIndex = 9;
			this.browseForKey.Text = "...";
			this.browseForKey.Click += new System.EventHandler(this.browseForKey_Click);
			// 
			// validatorAssemblyLbl
			// 
			this.validatorAssemblyLbl.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.validatorAssemblyLbl.Location = new System.Drawing.Point(19, 240);
			this.validatorAssemblyLbl.Name = "validatorAssemblyLbl";
			this.validatorAssemblyLbl.Size = new System.Drawing.Size(154, 25);
			this.validatorAssemblyLbl.TabIndex = 10;
			this.validatorAssemblyLbl.Text = "校验器组件名：";
			// 
			// validatorAssembly
			// 
			this.validatorAssembly.Font = new System.Drawing.Font("Century Gothic", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.validatorAssembly.Location = new System.Drawing.Point(163, 241);
			this.validatorAssembly.Name = "validatorAssembly";
			this.validatorAssembly.ReadOnly = true;
			this.validatorAssembly.Size = new System.Drawing.Size(538, 21);
			this.validatorAssembly.TabIndex = 11;
			this.validatorAssembly.Text = "";
			this.validatorAssembly.TextChanged += new System.EventHandler(this.validatorAssembly_TextChanged);
			// 
			// browseForValidatorAssembly
			// 
			this.browseForValidatorAssembly.BackColor = System.Drawing.Color.Gold;
			this.browseForValidatorAssembly.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.browseForValidatorAssembly.Location = new System.Drawing.Point(710, 241);
			this.browseForValidatorAssembly.Name = "browseForValidatorAssembly";
			this.browseForValidatorAssembly.Size = new System.Drawing.Size(29, 25);
			this.browseForValidatorAssembly.TabIndex = 12;
			this.browseForValidatorAssembly.Text = "...";
			this.browseForValidatorAssembly.Click += new System.EventHandler(this.browseForValidatorAssembly_Click);
			// 
			// validatorClassLbl
			// 
			this.validatorClassLbl.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.validatorClassLbl.Location = new System.Drawing.Point(19, 280);
			this.validatorClassLbl.Name = "validatorClassLbl";
			this.validatorClassLbl.Size = new System.Drawing.Size(135, 25);
			this.validatorClassLbl.TabIndex = 13;
			this.validatorClassLbl.Text = "校验器类名：";
			// 
			// validatorClass
			// 
			this.validatorClass.Font = new System.Drawing.Font("Century Gothic", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.validatorClass.Location = new System.Drawing.Point(163, 276);
			this.validatorClass.Name = "validatorClass";
			this.validatorClass.Size = new System.Drawing.Size(538, 24);
			this.validatorClass.TabIndex = 14;
			// 
			// postProcessorAssemblyLbl
			// 
			this.postProcessorAssemblyLbl.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.postProcessorAssemblyLbl.Location = new System.Drawing.Point(144, 360);
			this.postProcessorAssemblyLbl.Name = "postProcessorAssemblyLbl";
			this.postProcessorAssemblyLbl.Size = new System.Drawing.Size(182, 25);
			this.postProcessorAssemblyLbl.TabIndex = 15;
			this.postProcessorAssemblyLbl.Text = "传递处理器组件名：";
			// 
			// usePostProcessor
			// 
			this.usePostProcessor.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.usePostProcessor.Location = new System.Drawing.Point(163, 327);
			this.usePostProcessor.Name = "usePostProcessor";
			this.usePostProcessor.Size = new System.Drawing.Size(125, 26);
			this.usePostProcessor.TabIndex = 16;
			this.usePostProcessor.Text = "是否需要传递校验";
			this.usePostProcessor.CheckedChanged += new System.EventHandler(this.usePostProcessor_CheckedChanged);
			// 
			// postProcessorAssembly
			// 
			this.postProcessorAssembly.Enabled = false;
			this.postProcessorAssembly.Font = new System.Drawing.Font("Century Gothic", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.postProcessorAssembly.Location = new System.Drawing.Point(326, 362);
			this.postProcessorAssembly.Name = "postProcessorAssembly";
			this.postProcessorAssembly.ReadOnly = true;
			this.postProcessorAssembly.Size = new System.Drawing.Size(375, 21);
			this.postProcessorAssembly.TabIndex = 17;
			this.postProcessorAssembly.Text = "";
			this.postProcessorAssembly.TextChanged += new System.EventHandler(this.postProcessorAssembly_TextChanged);
			// 
			// browseForPostProcessor
			// 
			this.browseForPostProcessor.BackColor = System.Drawing.Color.Gold;
			this.browseForPostProcessor.Enabled = false;
			this.browseForPostProcessor.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.browseForPostProcessor.Location = new System.Drawing.Point(710, 362);
			this.browseForPostProcessor.Name = "browseForPostProcessor";
			this.browseForPostProcessor.Size = new System.Drawing.Size(29, 25);
			this.browseForPostProcessor.TabIndex = 18;
			this.browseForPostProcessor.Text = "...";
			this.browseForPostProcessor.Click += new System.EventHandler(this.browseForPostProcessor_Click);
			// 
			// postProcessorClass
			// 
			this.postProcessorClass.Enabled = false;
			this.postProcessorClass.Font = new System.Drawing.Font("Century Gothic", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.postProcessorClass.Location = new System.Drawing.Point(326, 396);
			this.postProcessorClass.Name = "postProcessorClass";
			this.postProcessorClass.Size = new System.Drawing.Size(375, 24);
			this.postProcessorClass.TabIndex = 19;
			// 
			// postProcessorClassLbl
			// 
			this.postProcessorClassLbl.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.postProcessorClassLbl.Location = new System.Drawing.Point(144, 396);
			this.postProcessorClassLbl.Name = "postProcessorClassLbl";
			this.postProcessorClassLbl.Size = new System.Drawing.Size(163, 25);
			this.postProcessorClassLbl.TabIndex = 20;
			this.postProcessorClassLbl.Text = "传递处理器类名：";
			// 
			// createManifest
			// 
			this.createManifest.BackColor = System.Drawing.Color.Gold;
			this.createManifest.Font = new System.Drawing.Font("Lucida Sans Unicode", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			this.createManifest.Location = new System.Drawing.Point(614, 465);
			this.createManifest.Name = "createManifest";
			this.createManifest.Size = new System.Drawing.Size(135, 25);
			this.createManifest.TabIndex = 21;
			this.createManifest.Text = "生成配置文件";
			this.createManifest.Click += new System.EventHandler(this.createManifest_Click);
			// 
			// folderDialog
			// 
			this.folderDialog.SelectedPath = "C:\\Documents and Settings\\Graeme.LUGG4GE\\My Documents";
			// 
			// validatorDialog
			// 
			this.validatorDialog.Filter = "DLL Files (*.dll)|*.dll|Executables (*.exe)|*.exe";
			// 
			// postProcessorDialog
			// 
			this.postProcessorDialog.Filter = "DLL Files (*.dll)|*.dll|Executables (*.exe)|*.exe";
			// 
			// manifestDialog
			// 
			this.manifestDialog.FileName = "Manifest.xml";
			this.manifestDialog.Filter = "xml files|*.xml|All Files *.*|*.**";
			// 
			// keyDialog
			// 
			this.keyDialog.Filter = "xml files|*.xml|All Files *.*|*.*";
			// 
			// mainMenu1
			// 
			this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					  this.fileMenu});
			// 
			// fileMenu
			// 
			this.fileMenu.Index = 0;
			this.fileMenu.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
																					 this.fileCreateManifestMenu,
																					 this.fileGenerateKeysMenu,
																					 this.fileExitMenu});
			this.fileMenu.Text = "文件操作(&F)";
			// 
			// fileCreateManifestMenu
			// 
			this.fileCreateManifestMenu.Index = 0;
			this.fileCreateManifestMenu.Text = "生成配置文件( &M)";
			this.fileCreateManifestMenu.Click += new System.EventHandler(this.fileCreateManifestMenu_Click);
			// 
			// fileGenerateKeysMenu
			// 
			this.fileGenerateKeysMenu.Index = 1;
			this.fileGenerateKeysMenu.Text = "生成密匙 (&K)";
			this.fileGenerateKeysMenu.Click += new System.EventHandler(this.fileGenerateKeysMenu_Click);
			// 
			// fileExitMenu
			// 
			this.fileExitMenu.Index = 2;
			this.fileExitMenu.Text = "退出(&E)";
			this.fileExitMenu.Click += new System.EventHandler(this.fileExitMenu_Click);
			// 
			// ManifestUtilityMainForm
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
			this.BackColor = System.Drawing.Color.Tan;
			this.ClientSize = new System.Drawing.Size(768, 497);
			this.Controls.Add(this.createManifest);
			this.Controls.Add(this.postProcessorClassLbl);
			this.Controls.Add(this.postProcessorClass);
			this.Controls.Add(this.browseForPostProcessor);
			this.Controls.Add(this.postProcessorAssembly);
			this.Controls.Add(this.usePostProcessor);
			this.Controls.Add(this.postProcessorAssemblyLbl);
			this.Controls.Add(this.validatorClass);
			this.Controls.Add(this.validatorClassLbl);
			this.Controls.Add(this.browseForValidatorAssembly);
			this.Controls.Add(this.validatorAssembly);
			this.Controls.Add(this.validatorAssemblyLbl);
			this.Controls.Add(this.browseForKey);
			this.Controls.Add(this.keyLbl);
			this.Controls.Add(this.key);
			this.Controls.Add(this.version);
			this.Controls.Add(this.versionLbl);
			this.Controls.Add(this.updateLocation);
			this.Controls.Add(this.updateLocationLbl);
			this.Controls.Add(this.browseForFolder);
			this.Controls.Add(this.folderPath);
			this.Controls.Add(this.folderLbl);
			this.MaximumSize = new System.Drawing.Size(776, 544);
			this.Menu = this.mainMenu1;
			this.MinimumSize = new System.Drawing.Size(776, 544);
			this.Name = "ManifestUtilityMainForm";
			this.Text = "发布程序配置文件生成工具(Copyright to Microsoft)";
			this.Load += new System.EventHandler(this.ManifestUtilityMainForm_Load);
			this.ResumeLayout(false);

		}
		#endregion
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new ManifestUtilityMainForm());
		}

		#endregion

		#region control event handlers
		private void browseForFolder_Click(object sender, System.EventArgs e)
		{
//  can only use FolderBrowserDialog in FX1.1
#if FRAMEWORK_1_1
			//  set path to what's in text box
			folderDialog.SelectedPath = folderPath.Text;
			DialogResult dR = folderDialog.ShowDialog();
			if( DialogResult.OK == dR )
			{
				folderPath.Text = folderDialog.SelectedPath + @"\";
			}
#endif
		}

		
		private void ManifestUtilityMainForm_Load(object sender, System.EventArgs e)
		{
			initializeDialogs();
		}

		
		private void validatorAssembly_TextChanged(object sender, System.EventArgs e)
		{
			ListClasses(validatorAssembly.Text, "IValidator", validatorClass);
		}

		
		private void browseForValidatorAssembly_Click(object sender, System.EventArgs e)
		{
			if(validatorDialog.ShowDialog() == DialogResult.OK)
			{
				validatorAssembly.Text = validatorDialog.FileName;
			}

		}

		
		private void browseForKey_Click(object sender, System.EventArgs e)
		{
			//  set path to same as where updates located, possible starting point for where private key might be temporarily stored.
			//  NOTE:  ****  DO NOT KEEP PRIVATE KEY ANYWHERE NEAR WEB FOLDERS, PRIVATE KEY MUST BE KEPT __VERY__ SECURE!
			keyDialog.InitialDirectory = Directory.GetParent( folderPath.Text ).FullName;

			if(keyDialog.ShowDialog() == DialogResult.OK)
			{
				System.IO.StreamReader sr = new 
					System.IO.StreamReader(keyDialog.FileName);
				key.Text = sr.ReadToEnd();
				sr.Close();
			}

		}

		
		private void browseForPostProcessor_Click(object sender, System.EventArgs e)
		{
			postProcessorDialog.InitialDirectory = folderPath.Text;
			if(postProcessorDialog.ShowDialog() == DialogResult.OK)
			{
				postProcessorAssembly.Text = postProcessorDialog.FileName;
			}

		}

		
		private void postProcessorAssembly_TextChanged(object sender, System.EventArgs e)
		{
			ListClasses(postProcessorAssembly.Text, "IPostProcessor", postProcessorClass);
		}

		
		private void usePostProcessor_CheckedChanged(object sender, System.EventArgs e)
		{
			postProcessorAssembly.Enabled = usePostProcessor.Checked;
			postProcessorClass.Enabled = usePostProcessor.Checked;
			browseForPostProcessor.Enabled = usePostProcessor.Checked;
		}

		
		private void fileGenerateKeysMenu_Click(object sender, System.EventArgs e)
		{
			createNewKeys();
		}

		
		private void createManifest_Click(object sender, System.EventArgs e)
		{
			generateManifestFile();
		}


		private void fileCreateManifestMenu_Click(object sender, System.EventArgs e)
		{
			generateManifestFile();
		}

		
		private void fileExitMenu_Click(object sender, System.EventArgs e)
		{
			this.Close();
		}

		
		#endregion

		#region utility functions

		private void initializeDialogs()
		{
			//folderPath.Text = folderDialog.SelectedPath + @"\";
			folderPath.Text = AppDomain.CurrentDomain.BaseDirectory;
			validatorAssembly.Text = System.AppDomain.CurrentDomain.BaseDirectory + "Microsoft.ApplicationBlocks.ApplicationUpdater.dll";
			validatorDialog.InitialDirectory = System.AppDomain.CurrentDomain.BaseDirectory;
			
//  can only use FolderBrowserDialog in FX1.1
#if FRAMEWORK_1_1
			keyDialog.InitialDirectory = folderDialog.SelectedPath;
			newKeyDialog.InitialDirectory = folderDialog.SelectedPath;
#else
			
			keyDialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
			newKeyDialog.InitialDirectory = AppDomain.CurrentDomain.BaseDirectory;
#endif
		}

		
		private void generateManifestFile()
		{
			try
			{
				ManifestSettings manifest = new ManifestSettings();
				manifest.FolderPath = folderPath.Text;
				manifest.UpdateLocation = updateLocation.Text;
				manifest.Version = version.Text;
				manifest.Key = key.Text;
				manifest.ValidatorAssembly = validatorAssembly.Text;
				manifest.ValidatorClass = validatorClass.Text;
				manifest.UsePostProcessor = usePostProcessor.Checked;
				manifest.PostProcessorAssembly = postProcessorAssembly.Text;
				manifest.PostProcessorClass = postProcessorClass.Text;
				XmlDocument manifestDoc = manifest.Create();
				if ( DialogResult.OK == manifestDialog.ShowDialog() )
				{
					manifestDoc.Save(manifestDialog.FileName);
					MessageBox.Show("Manifest Saved");
				}
				else
				{
					MessageBox.Show( "Manifest save cancelled." );
				}
			}
			catch( Exception e )
			{
				HandleTerminalError( e );
			}
		}

		
		private void ListClasses(string assembly, string interfaceType, ComboBox listControl)
		{
			Assembly asm;
			Type[] types;
			Type typeInstance;

			// clear the existing list
			listControl.Items.Clear();
			listControl.Text = "";

			try
			{
			
				asm = Assembly.LoadFrom(  assembly );
				types = asm.GetTypes();
				foreach( Type type in types )
				{
					typeInstance = type.GetInterface( interfaceType, false );
					if( null != typeInstance )
					{
						listControl.Items.Add( type.FullName );
					}
				}
				listControl.SelectedIndex = 0;
			}
			catch(FileNotFoundException f)
			{
				HandleTerminalError( f );
			}
			catch (Exception e)
			{
				HandleTerminalError( e );
			}
			
		}

		
		private void createNewKeys()
		{
			try
			{
				// Instantiate the key generator
				KeyGenerator keyGen = new KeyGenerator();

				// Get the public and private keys
				XmlDocument privateKey = keyGen.PrivateKey;
				XmlDocument publicKey = keyGen.PublicKey;

				// save the private key
				newKeyDialog.FileName = "PrivateKey.xml";
				newKeyDialog.Title = "Save Private Key";
				if(newKeyDialog.ShowDialog() == DialogResult.OK)
				{
					privateKey.Save(newKeyDialog.FileName);
				}

				// save the public key
				newKeyDialog.FileName = "PublicKey.xml";
				newKeyDialog.Title = "Save Public Key";
				if(newKeyDialog.ShowDialog() == DialogResult.OK)
				{
					publicKey.Save(newKeyDialog.FileName);
				}

				keyGen = null;
			}
			catch( Exception e )
			{
				HandleTerminalError( e );
			}
		}


		private void HandleTerminalError( Exception e )
		{
			StringBuilder sb = new StringBuilder( 5000 );
			//  pass off to recursive fn
			RecurseErrorStack( e, sb );
			//  show error
			MessageBox.Show( sb.ToString() );		
		}

		
		private void RecurseErrorStack( Exception e , StringBuilder sb )
		{
			if( null != e )
			{
				sb.Append( String.Format( "ERROR: '{0}'{1}STACK: {2}{3}", e.Message, Environment.NewLine, e.StackTrace, Environment.NewLine ) );
				//  now recurse to roll up inner exceptions
				RecurseErrorStack( e.InnerException, sb );
			}
		}

		
		#endregion

		#region Tooltips

		private void SetToolTips()
		{
		
			this.toolTip1.SetToolTip(this.folderPath, "Enter the PHYSICAL path on the server where the actual update files are located; " +
				"this is not a URL, this is the path that the manifest utility will use to find these files and generate the manifest.");
			


			//  can only use this object w/ FX1.1
#if FRAMEWORK_1_1
			this.toolTip1.SetToolTip(this.browseForFolder, "Click here to browse to the folder on the server where the new update files are l" +
				"ocated.");
#else
			this.toolTip1.SetToolTip(this.browseForFolder, "You are using FRAMEWORK 1.0, enter the folder path manually in the text box to the left.");
#endif
			this.toolTip1.SetToolTip(this.updateLocation, @"Enter the URL (or UNC if using alternate downloaders) where the CLIENTS will look to find the updated files.  Usually this is a URL of the form ""http://myServer/Updater/2.0.0.0/"" where the last part of the URL is the versioned folder number...not necessary but will help keep things organized.");
			
			this.toolTip1.SetToolTip(this.version, "The version number of the new update.  It is HIGHLY RECOMMENDED that you use stan" +
				"dard versioning conventions as shown--\"2.0.0.0\", or \"3.1.75.298\" for instance.");
			
			this.toolTip1.SetToolTip(this.browseForKey, "Click on this button to select the private key, or symmetric key, in an xml file;" +
				" this key will be used to sign the files and manifest.");
			
			this.toolTip1.SetToolTip(this.browseForValidatorAssembly, @"Click on this button to find the ASSEMBLY (DLL or EXE) that contains an implementation of IValidator you wish to use to sign the files.  NOTE that the assembly MUST contain an IValidator implementation.  Also note that this must be the same IValidator that is used by the clients (according to their configuration files) to verify the files.");
			
			this.toolTip1.SetToolTip(this.validatorClass, "Once you have selected a Validator assembly above, all the public classes which i" +
				"mplement IValidator will appear here.  Select the one you wish to use.  NOTE tha" +
				"t you must sign the files/manifest with the SAME validator as the clients use to" +
				" verify them.");
			
			this.toolTip1.SetToolTip(this.usePostProcessor, "Check this box if you wish to run a Post Processor on the clients when you have c" +
				"ompleted an update.  See the documentation for more help on the enormously power" +
				"ful Post Processor concept.");

			this.toolTip1.SetToolTip(this.browseForPostProcessor, "Click this button to select an ASSEMBLY (EXE or DLL) that contains at least one p" +
				"ublic member which implements IPostProcessor.");
			
			this.toolTip1.SetToolTip(this.postProcessorClass, "When you have selected an IPostProcessor implementation above, the list of availa" +
				"ble PostProcessors will appear here.  Select the one you wish the clients to use" +
				" when they complete an update.");
			
		}

		#endregion
	}
}
