/* autopano-win32, GUI
 * Copyright (C) 2004 -- Wei Zhen
 *
 * This program is free software released under the GNU General Public
 * License, which is included in this software package (doc/LICENSE).
 */

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;

namespace autopano_sift_winGUI
{
	/// <summary>
	/// Form1 的摘要说明。
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Button buttonAdd;
		private System.Windows.Forms.Button buttonCompute;
		private System.Windows.Forms.Button buttonRemove;
		private System.Windows.Forms.Button buttonOutputSelect;

		private System.Windows.Forms.CheckBox checkBoxUseRANSAC;
		private System.Windows.Forms.CheckBox checkBoxuseAreafilter;
		private System.Windows.Forms.CheckBox checkBoxUseSubpixel;
		private System.Windows.Forms.CheckBox checkBoxGenerateHorizon;
		private System.Windows.Forms.CheckBox checkBoxUseAlignment;
		private System.Windows.Forms.CheckBox checkBoxAbsPath;
		private System.Windows.Forms.ColumnHeader columnHeader1;
		private System.Windows.Forms.ColumnHeader columnHeader2;
		private System.Windows.Forms.ColumnHeader columnHeader3;			
		private System.Windows.Forms.ComboBox comboBoxKPMatchMax;
		private System.Windows.Forms.ComboBox comboBoxKPNumber;
		private System.Windows.Forms.ComboBox comboBoxKPSaveWhere;
		private System.Windows.Forms.ComboBox comboBoxHorizonLines;

		private System.Windows.Forms.ErrorProvider errorProvider;

		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.Label label5;
		private System.Windows.Forms.Label label6;
		private System.Windows.Forms.Label label7;
		private System.Windows.Forms.ListView listView1;

		private System.Windows.Forms.GroupBox groupBox1;
		private System.Windows.Forms.GroupBox groupBox2;
		private System.Windows.Forms.GroupBox groupBox3;
		private System.Windows.Forms.GroupBox groupBox4;
		private System.Windows.Forms.GroupBox groupBox5;
		private System.Windows.Forms.GroupBox groupBox6;
		private System.Windows.Forms.GroupBox groupBox7;
		private System.Windows.Forms.GroupBox groupBox9;
		private System.Windows.Forms.GroupBox groupBox10;		
		private System.Windows.Forms.GroupBox groupBoxPreview;

		private System.Windows.Forms.OpenFileDialog openFileDlgAddImage;
		private System.Windows.Forms.OpenFileDialog openFileDlgOutputFile;

		private System.Windows.Forms.Panel panelBottom;
		private System.Windows.Forms.Panel panelRight;
		private System.Windows.Forms.Panel panelLeft;
		private System.Windows.Forms.Panel panel3;
		private System.Windows.Forms.Panel panel5;
		private System.Windows.Forms.Panel panel9;
		private System.Windows.Forms.Panel panel10;
		private System.Windows.Forms.Panel panel11;
		private System.Windows.Forms.Panel panelAlign;
		private System.Windows.Forms.PictureBox pictureBox1;
		private System.Windows.Forms.PictureBox pictureBox2;
		private System.Windows.Forms.PictureBox pictureBoxPreview;
	
		private System.Windows.Forms.RadioButton radioButtonAutoAlign;
		private System.Windows.Forms.RadioButton radioButtonBottomLeft;
		private System.Windows.Forms.RadioButton radioButtonBottomRight;
		
		private System.Windows.Forms.Splitter splitter1;
		private System.Windows.Forms.Splitter splitter4;

		private System.Windows.Forms.TextBox textBoxKPSavePrefix;
		private System.Windows.Forms.TextBox textBoxImageCount;
		private System.Windows.Forms.TextBox textBoxOutputFilename;

		private FormProcess formProcess;	
		
		private int iDownscaleResolution;
		private int iMaxPairKeypoints;
		private int iHorizonCount;
		private int iImageDoneCount;
		private int iImageCount;
		private string strPTOFilePath;
		private string strInputDir = "";
		private string strOutputDir = Path.GetFullPath(".");
		private bool bIOSameDir = true;
		private bool bIsAllValid = true;
		private KeypointsTarget keypointsTarget;		
		private ArrayList memoryKeypointsList;
		private ArrayList keypointFilesList;
		private System.Windows.Forms.GroupBox groupBox8;
		private System.Windows.Forms.CheckBox enableRefine;
		private System.Windows.Forms.CheckBox keepUnrefinable;
		private System.Windows.Forms.RadioButton refineMethodMiddle;
		private System.Windows.Forms.RadioButton refineMethodMean;
		private System.Windows.Forms.GroupBox groupBox11;
	
		/// <summary>
		/// 必需的设计器变量。
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			//
			// Windows 窗体设计器支持所必需的
			//

			InitializeComponent();
			// 
			// pictureBox1
			// 
			this.pictureBox1.Image = Image.FromFile("icons" +
				Path.DirectorySeparatorChar +
				"image-bottom-left.png");
			this.pictureBox1.Location = new System.Drawing.Point(208, 48);
			this.pictureBox1.Name = "pictureBox1";
			this.pictureBox1.Size = new System.Drawing.Size(136, 120);
			this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
			this.pictureBox1.TabIndex = 8;
			this.pictureBox1.TabStop = false;
			// 
			// pictureBox2
			// 
			this.pictureBox2.Image = Image.FromFile("icons" +
				Path.DirectorySeparatorChar +
				"image-bottom-right.png");
			this.pictureBox2.Location = new System.Drawing.Point(368, 48);
			this.pictureBox2.Name = "pictureBox2";
			this.pictureBox2.Size = new System.Drawing.Size(136, 120);
			this.pictureBox2.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
			this.pictureBox2.TabIndex = 10;
			this.pictureBox2.TabStop = false;
			
			
			pictureBoxPreview.Paint += new PaintEventHandler(pictureBoxPreview_Paint);

			comboBoxKPNumber.Text = comboBoxKPNumber.Items[0].ToString();
			comboBoxKPSaveWhere.Text = comboBoxKPSaveWhere.Items[0].ToString();
			comboBoxKPMatchMax.Text = comboBoxKPMatchMax.Items[0].ToString();
			comboBoxHorizonLines.Text = comboBoxHorizonLines.Items[0].ToString();



			//
			// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
			//
		}

		/// <summary>
		/// 清理所有正在使用的资源。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if(formProcess != null)formProcess.Dispose();
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows 窗体设计器生成的代码
		/// <summary>
		/// 设计器支持所需的方法 - 不要使用代码编辑器修改
		/// 此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			this.buttonCompute = new System.Windows.Forms.Button();
			this.panelBottom = new System.Windows.Forms.Panel();
			this.groupBox4 = new System.Windows.Forms.GroupBox();
			this.splitter1 = new System.Windows.Forms.Splitter();
			this.panelRight = new System.Windows.Forms.Panel();
			this.panel11 = new System.Windows.Forms.Panel();
			this.panel9 = new System.Windows.Forms.Panel();
			this.groupBoxPreview = new System.Windows.Forms.GroupBox();
			this.pictureBoxPreview = new System.Windows.Forms.PictureBox();
			this.groupBox7 = new System.Windows.Forms.GroupBox();
			this.checkBoxAbsPath = new System.Windows.Forms.CheckBox();
			this.buttonOutputSelect = new System.Windows.Forms.Button();
			this.textBoxOutputFilename = new System.Windows.Forms.TextBox();
			this.checkBoxUseSubpixel = new System.Windows.Forms.CheckBox();
			this.groupBox8 = new System.Windows.Forms.GroupBox();
			this.groupBox11 = new System.Windows.Forms.GroupBox();
			this.refineMethodMean = new System.Windows.Forms.RadioButton();
			this.refineMethodMiddle = new System.Windows.Forms.RadioButton();
			this.keepUnrefinable = new System.Windows.Forms.CheckBox();
			this.enableRefine = new System.Windows.Forms.CheckBox();
			this.groupBox10 = new System.Windows.Forms.GroupBox();
			this.panelAlign = new System.Windows.Forms.Panel();
			this.comboBoxHorizonLines = new System.Windows.Forms.ComboBox();
			this.label5 = new System.Windows.Forms.Label();
			this.label4 = new System.Windows.Forms.Label();
			this.radioButtonAutoAlign = new System.Windows.Forms.RadioButton();
			this.pictureBox1 = new System.Windows.Forms.PictureBox();
			this.groupBox6 = new System.Windows.Forms.GroupBox();
			this.groupBox3 = new System.Windows.Forms.GroupBox();
			this.radioButtonBottomRight = new System.Windows.Forms.RadioButton();
			this.radioButtonBottomLeft = new System.Windows.Forms.RadioButton();
			this.pictureBox2 = new System.Windows.Forms.PictureBox();
			this.checkBoxGenerateHorizon = new System.Windows.Forms.CheckBox();
			this.label6 = new System.Windows.Forms.Label();
			this.groupBox5 = new System.Windows.Forms.GroupBox();
			this.panel5 = new System.Windows.Forms.Panel();
			this.checkBoxUseAlignment = new System.Windows.Forms.CheckBox();
			this.panel10 = new System.Windows.Forms.Panel();
			this.groupBox1 = new System.Windows.Forms.GroupBox();
			this.comboBoxKPSaveWhere = new System.Windows.Forms.ComboBox();
			this.textBoxKPSavePrefix = new System.Windows.Forms.TextBox();
			this.label2 = new System.Windows.Forms.Label();
			this.label1 = new System.Windows.Forms.Label();
			this.comboBoxKPNumber = new System.Windows.Forms.ComboBox();
			this.groupBox2 = new System.Windows.Forms.GroupBox();
			this.checkBoxUseRANSAC = new System.Windows.Forms.CheckBox();
			this.comboBoxKPMatchMax = new System.Windows.Forms.ComboBox();
			this.label3 = new System.Windows.Forms.Label();
			this.checkBoxuseAreafilter = new System.Windows.Forms.CheckBox();
			this.groupBox9 = new System.Windows.Forms.GroupBox();
			this.label7 = new System.Windows.Forms.Label();
			this.textBoxImageCount = new System.Windows.Forms.TextBox();
			this.splitter4 = new System.Windows.Forms.Splitter();
			this.panel3 = new System.Windows.Forms.Panel();
			this.buttonAdd = new System.Windows.Forms.Button();
			this.buttonRemove = new System.Windows.Forms.Button();
			this.listView1 = new System.Windows.Forms.ListView();
			this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
			this.columnHeader3 = new System.Windows.Forms.ColumnHeader();
			this.panelLeft = new System.Windows.Forms.Panel();
			this.openFileDlgAddImage = new System.Windows.Forms.OpenFileDialog();
			this.openFileDlgOutputFile = new System.Windows.Forms.OpenFileDialog();
			this.errorProvider = new System.Windows.Forms.ErrorProvider();
			this.panelBottom.SuspendLayout();
			this.panelRight.SuspendLayout();
			this.panel11.SuspendLayout();
			this.panel9.SuspendLayout();
			this.groupBoxPreview.SuspendLayout();
			this.groupBox7.SuspendLayout();
			this.groupBox8.SuspendLayout();
			this.groupBox10.SuspendLayout();
			this.panelAlign.SuspendLayout();
			this.panel5.SuspendLayout();
			this.panel10.SuspendLayout();
			this.groupBox1.SuspendLayout();
			this.groupBox2.SuspendLayout();
			this.groupBox9.SuspendLayout();
			this.panel3.SuspendLayout();
			this.panelLeft.SuspendLayout();
			this.SuspendLayout();
			// 
			// buttonCompute
			// 
			this.buttonCompute.Location = new System.Drawing.Point(300, 7);
			this.buttonCompute.Name = "buttonCompute";
			this.buttonCompute.Size = new System.Drawing.Size(62, 22);
			this.buttonCompute.TabIndex = 0;
			this.buttonCompute.Text = "Compute";
			this.buttonCompute.Click += new System.EventHandler(this.buttonCompute_Click);
			// 
			// panelBottom
			// 
			this.panelBottom.Controls.Add(this.groupBox4);
			this.panelBottom.Controls.Add(this.buttonCompute);
			this.panelBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
			this.panelBottom.Location = new System.Drawing.Point(0, 537);
			this.panelBottom.Name = "panelBottom";
			this.panelBottom.Size = new System.Drawing.Size(768, 37);
			this.panelBottom.TabIndex = 1;
			// 
			// groupBox4
			// 
			this.groupBox4.Dock = System.Windows.Forms.DockStyle.Top;
			this.groupBox4.Location = new System.Drawing.Point(0, 0);
			this.groupBox4.Name = "groupBox4";
			this.groupBox4.Size = new System.Drawing.Size(768, 5);
			this.groupBox4.TabIndex = 1;
			this.groupBox4.TabStop = false;
			// 
			// splitter1
			// 
			this.splitter1.Dock = System.Windows.Forms.DockStyle.Bottom;
			this.splitter1.Location = new System.Drawing.Point(0, 534);
			this.splitter1.Name = "splitter1";
			this.splitter1.Size = new System.Drawing.Size(768, 3);
			this.splitter1.TabIndex = 2;
			this.splitter1.TabStop = false;
			// 
			// panelRight
			// 
			this.panelRight.Controls.Add(this.panel11);
			this.panelRight.Controls.Add(this.panel10);
			this.panelRight.Dock = System.Windows.Forms.DockStyle.Right;
			this.panelRight.DockPadding.All = 3;
			this.panelRight.Location = new System.Drawing.Point(256, 0);
			this.panelRight.Name = "panelRight";
			this.panelRight.Size = new System.Drawing.Size(512, 534);
			this.panelRight.TabIndex = 3;
			// 
			// panel11
			// 
			this.panel11.Controls.Add(this.panel9);
			this.panel11.Controls.Add(this.groupBox10);
			this.panel11.Dock = System.Windows.Forms.DockStyle.Fill;
			this.panel11.DockPadding.All = 3;
			this.panel11.Location = new System.Drawing.Point(3, 103);
			this.panel11.Name = "panel11";
			this.panel11.Size = new System.Drawing.Size(506, 428);
			this.panel11.TabIndex = 6;
			// 
			// panel9
			// 
			this.panel9.Controls.Add(this.groupBoxPreview);
			this.panel9.Controls.Add(this.groupBox7);
			this.panel9.Controls.Add(this.groupBox8);
			this.panel9.Dock = System.Windows.Forms.DockStyle.Fill;
			this.panel9.Location = new System.Drawing.Point(3, 237);
			this.panel9.Name = "panel9";
			this.panel9.Size = new System.Drawing.Size(500, 188);
			this.panel9.TabIndex = 5;
			// 
			// groupBoxPreview
			// 
			this.groupBoxPreview.Controls.Add(this.pictureBoxPreview);
			this.groupBoxPreview.Dock = System.Windows.Forms.DockStyle.Fill;
			this.groupBoxPreview.Location = new System.Drawing.Point(0, 64);
			this.groupBoxPreview.Name = "groupBoxPreview";
			this.groupBoxPreview.Size = new System.Drawing.Size(307, 124);
			this.groupBoxPreview.TabIndex = 1;
			this.groupBoxPreview.TabStop = false;
			this.groupBoxPreview.Text = "Preview";
			// 
			// pictureBoxPreview
			// 
			this.pictureBoxPreview.Location = new System.Drawing.Point(80, 15);
			this.pictureBoxPreview.Name = "pictureBoxPreview";
			this.pictureBoxPreview.Size = new System.Drawing.Size(83, 67);
			this.pictureBoxPreview.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
			this.pictureBoxPreview.TabIndex = 0;
			this.pictureBoxPreview.TabStop = false;
			// 
			// groupBox7
			// 
			this.groupBox7.Controls.Add(this.checkBoxAbsPath);
			this.groupBox7.Controls.Add(this.buttonOutputSelect);
			this.groupBox7.Controls.Add(this.textBoxOutputFilename);
			this.groupBox7.Controls.Add(this.checkBoxUseSubpixel);
			this.groupBox7.Dock = System.Windows.Forms.DockStyle.Right;
			this.groupBox7.Location = new System.Drawing.Point(307, 64);
			this.groupBox7.Name = "groupBox7";
			this.groupBox7.Size = new System.Drawing.Size(193, 124);
			this.groupBox7.TabIndex = 0;
			this.groupBox7.TabStop = false;
			this.groupBox7.Text = "PTO Output";
			// 
			// checkBoxAbsPath
			// 
			this.checkBoxAbsPath.Location = new System.Drawing.Point(7, 67);
			this.checkBoxAbsPath.Name = "checkBoxAbsPath";
			this.checkBoxAbsPath.Size = new System.Drawing.Size(180, 30);
			this.checkBoxAbsPath.TabIndex = 5;
			this.checkBoxAbsPath.Text = "Save absolute image pathnames in PTO";
			// 
			// buttonOutputSelect
			// 
			this.buttonOutputSelect.Location = new System.Drawing.Point(127, 15);
			this.buttonOutputSelect.Name = "buttonOutputSelect";
			this.buttonOutputSelect.Size = new System.Drawing.Size(62, 21);
			this.buttonOutputSelect.TabIndex = 1;
			this.buttonOutputSelect.Text = "select";
			this.buttonOutputSelect.Click += new System.EventHandler(this.buttonOutput_Click);
			// 
			// textBoxOutputFilename
			// 
			this.textBoxOutputFilename.Location = new System.Drawing.Point(7, 15);
			this.textBoxOutputFilename.Name = "textBoxOutputFilename";
			this.textBoxOutputFilename.Size = new System.Drawing.Size(113, 20);
			this.textBoxOutputFilename.TabIndex = 0;
			this.textBoxOutputFilename.Text = "output.pto";
			// 
			// checkBoxUseSubpixel
			// 
			this.checkBoxUseSubpixel.Checked = true;
			this.checkBoxUseSubpixel.CheckState = System.Windows.Forms.CheckState.Checked;
			this.checkBoxUseSubpixel.Location = new System.Drawing.Point(7, 45);
			this.checkBoxUseSubpixel.Name = "checkBoxUseSubpixel";
			this.checkBoxUseSubpixel.Size = new System.Drawing.Size(173, 14);
			this.checkBoxUseSubpixel.TabIndex = 4;
			this.checkBoxUseSubpixel.Text = "Output subpixel coordinates";
			// 
			// groupBox8
			// 
			this.groupBox8.Controls.Add(this.groupBox11);
			this.groupBox8.Controls.Add(this.refineMethodMean);
			this.groupBox8.Controls.Add(this.refineMethodMiddle);
			this.groupBox8.Controls.Add(this.keepUnrefinable);
			this.groupBox8.Controls.Add(this.enableRefine);
			this.groupBox8.Dock = System.Windows.Forms.DockStyle.Top;
			this.groupBox8.Location = new System.Drawing.Point(0, 0);
			this.groupBox8.Name = "groupBox8";
			this.groupBox8.Size = new System.Drawing.Size(500, 64);
			this.groupBox8.TabIndex = 2;
			this.groupBox8.TabStop = false;
			this.groupBox8.Text = "Refining Options";
			// 
			// groupBox11
			// 
			this.groupBox11.Location = new System.Drawing.Point(112, 8);
			this.groupBox11.Name = "groupBox11";
			this.groupBox11.Size = new System.Drawing.Size(3, 40);
			this.groupBox11.TabIndex = 12;
			this.groupBox11.TabStop = false;
			// 
			// refineMethodMean
			// 
			this.refineMethodMean.Location = new System.Drawing.Point(248, 32);
			this.refineMethodMean.Name = "refineMethodMean";
			this.refineMethodMean.Size = new System.Drawing.Size(128, 24);
			this.refineMethodMean.TabIndex = 3;
			this.refineMethodMean.Text = "Refine by mean";
			// 
			// refineMethodMiddle
			// 
			this.refineMethodMiddle.Checked = true;
			this.refineMethodMiddle.Location = new System.Drawing.Point(248, 8);
			this.refineMethodMiddle.Name = "refineMethodMiddle";
			this.refineMethodMiddle.Size = new System.Drawing.Size(128, 24);
			this.refineMethodMiddle.TabIndex = 2;
			this.refineMethodMiddle.TabStop = true;
			this.refineMethodMiddle.Text = "Refine by middle";
			// 
			// keepUnrefinable
			// 
			this.keepUnrefinable.Checked = true;
			this.keepUnrefinable.CheckState = System.Windows.Forms.CheckState.Checked;
			this.keepUnrefinable.Location = new System.Drawing.Point(128, 16);
			this.keepUnrefinable.Name = "keepUnrefinable";
			this.keepUnrefinable.TabIndex = 1;
			this.keepUnrefinable.Text = "keep unrefinable keypoints";
			// 
			// enableRefine
			// 
			this.enableRefine.Location = new System.Drawing.Point(16, 16);
			this.enableRefine.Name = "enableRefine";
			this.enableRefine.Size = new System.Drawing.Size(104, 32);
			this.enableRefine.TabIndex = 0;
			this.enableRefine.Text = "Enable refinement step";
			// 
			// groupBox10
			// 
			this.groupBox10.Controls.Add(this.panelAlign);
			this.groupBox10.Controls.Add(this.groupBox5);
			this.groupBox10.Controls.Add(this.panel5);
			this.groupBox10.Dock = System.Windows.Forms.DockStyle.Top;
			this.groupBox10.Location = new System.Drawing.Point(3, 3);
			this.groupBox10.Name = "groupBox10";
			this.groupBox10.Size = new System.Drawing.Size(500, 234);
			this.groupBox10.TabIndex = 4;
			this.groupBox10.TabStop = false;
			this.groupBox10.Text = "Alignment";
			// 
			// panelAlign
			// 
			this.panelAlign.Controls.Add(this.comboBoxHorizonLines);
			this.panelAlign.Controls.Add(this.label5);
			this.panelAlign.Controls.Add(this.label4);
			this.panelAlign.Controls.Add(this.radioButtonAutoAlign);
			this.panelAlign.Controls.Add(this.pictureBox1);
			this.panelAlign.Controls.Add(this.groupBox6);
			this.panelAlign.Controls.Add(this.groupBox3);
			this.panelAlign.Controls.Add(this.radioButtonBottomRight);
			this.panelAlign.Controls.Add(this.radioButtonBottomLeft);
			this.panelAlign.Controls.Add(this.pictureBox2);
			this.panelAlign.Controls.Add(this.checkBoxGenerateHorizon);
			this.panelAlign.Controls.Add(this.label6);
			this.panelAlign.Dock = System.Windows.Forms.DockStyle.Fill;
			this.panelAlign.Enabled = false;
			this.panelAlign.Location = new System.Drawing.Point(3, 45);
			this.panelAlign.Name = "panelAlign";
			this.panelAlign.Size = new System.Drawing.Size(494, 186);
			this.panelAlign.TabIndex = 3;
			// 
			// comboBoxHorizonLines
			// 
			this.comboBoxHorizonLines.Enabled = false;
			this.comboBoxHorizonLines.Items.AddRange(new object[] {
																	  "6",
																	  "14",
																	  "unlimited"});
			this.comboBoxHorizonLines.Location = new System.Drawing.Point(153, 163);
			this.comboBoxHorizonLines.Name = "comboBoxHorizonLines";
			this.comboBoxHorizonLines.Size = new System.Drawing.Size(67, 21);
			this.comboBoxHorizonLines.TabIndex = 14;
			this.comboBoxHorizonLines.Validating += new System.ComponentModel.CancelEventHandler(this.comboBoxHorizonLines_Validating);
			// 
			// label5
			// 
			this.label5.Location = new System.Drawing.Point(13, 82);
			this.label5.Name = "label5";
			this.label5.Size = new System.Drawing.Size(74, 29);
			this.label5.TabIndex = 3;
			this.label5.Text = "Input orientation:";
			// 
			// label4
			// 
			this.label4.Location = new System.Drawing.Point(0, 15);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(87, 15);
			this.label4.TabIndex = 2;
			this.label4.Text = "Align options";
			this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
			// 
			// radioButtonAutoAlign
			// 
			this.radioButtonAutoAlign.Checked = true;
			this.radioButtonAutoAlign.Location = new System.Drawing.Point(87, 0);
			this.radioButtonAutoAlign.Name = "radioButtonAutoAlign";
			this.radioButtonAutoAlign.Size = new System.Drawing.Size(73, 45);
			this.radioButtonAutoAlign.TabIndex = 4;
			this.radioButtonAutoAlign.TabStop = true;
			this.radioButtonAutoAlign.Text = "Automatic or normal";
			// 
			// pictureBox1
			// 
			this.pictureBox1.Location = new System.Drawing.Point(0, 0);
			this.pictureBox1.Name = "pictureBox1";
			this.pictureBox1.Size = new System.Drawing.Size(83, 46);
			this.pictureBox1.TabIndex = 15;
			this.pictureBox1.TabStop = false;
			// 
			// groupBox6
			// 
			this.groupBox6.Location = new System.Drawing.Point(160, 0);
			this.groupBox6.Name = "groupBox6";
			this.groupBox6.Size = new System.Drawing.Size(3, 160);
			this.groupBox6.TabIndex = 11;
			this.groupBox6.TabStop = false;
			// 
			// groupBox3
			// 
			this.groupBox3.Location = new System.Drawing.Point(320, 0);
			this.groupBox3.Name = "groupBox3";
			this.groupBox3.Size = new System.Drawing.Size(4, 160);
			this.groupBox3.TabIndex = 10;
			this.groupBox3.TabStop = false;
			// 
			// radioButtonBottomRight
			// 
			this.radioButtonBottomRight.Location = new System.Drawing.Point(336, 0);
			this.radioButtonBottomRight.Name = "radioButtonBottomRight";
			this.radioButtonBottomRight.Size = new System.Drawing.Size(80, 45);
			this.radioButtonBottomRight.TabIndex = 9;
			this.radioButtonBottomRight.Text = "Bottom is right";
			// 
			// radioButtonBottomLeft
			// 
			this.radioButtonBottomLeft.Location = new System.Drawing.Point(180, 0);
			this.radioButtonBottomLeft.Name = "radioButtonBottomLeft";
			this.radioButtonBottomLeft.Size = new System.Drawing.Size(80, 45);
			this.radioButtonBottomLeft.TabIndex = 5;
			this.radioButtonBottomLeft.Text = "Bottom is left";
			// 
			// pictureBox2
			// 
			this.pictureBox2.Location = new System.Drawing.Point(0, 0);
			this.pictureBox2.Name = "pictureBox2";
			this.pictureBox2.Size = new System.Drawing.Size(83, 46);
			this.pictureBox2.TabIndex = 16;
			this.pictureBox2.TabStop = false;
			// 
			// checkBoxGenerateHorizon
			// 
			this.checkBoxGenerateHorizon.Location = new System.Drawing.Point(13, 163);
			this.checkBoxGenerateHorizon.Name = "checkBoxGenerateHorizon";
			this.checkBoxGenerateHorizon.Size = new System.Drawing.Size(134, 15);
			this.checkBoxGenerateHorizon.TabIndex = 11;
			this.checkBoxGenerateHorizon.Text = "Generate horizon lines:";
			this.checkBoxGenerateHorizon.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			this.checkBoxGenerateHorizon.CheckedChanged += new System.EventHandler(this.checkBoxGenerateHorizon_CheckedChanged);
			// 
			// label6
			// 
			this.label6.Location = new System.Drawing.Point(227, 163);
			this.label6.Name = "label6";
			this.label6.Size = new System.Drawing.Size(40, 15);
			this.label6.TabIndex = 13;
			this.label6.Text = "lines";
			this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// groupBox5
			// 
			this.groupBox5.Dock = System.Windows.Forms.DockStyle.Top;
			this.groupBox5.Location = new System.Drawing.Point(3, 37);
			this.groupBox5.Name = "groupBox5";
			this.groupBox5.Size = new System.Drawing.Size(494, 8);
			this.groupBox5.TabIndex = 1;
			this.groupBox5.TabStop = false;
			// 
			// panel5
			// 
			this.panel5.Controls.Add(this.checkBoxUseAlignment);
			this.panel5.Dock = System.Windows.Forms.DockStyle.Top;
			this.panel5.Location = new System.Drawing.Point(3, 16);
			this.panel5.Name = "panel5";
			this.panel5.Size = new System.Drawing.Size(494, 21);
			this.panel5.TabIndex = 0;
			// 
			// checkBoxUseAlignment
			// 
			this.checkBoxUseAlignment.Location = new System.Drawing.Point(13, 7);
			this.checkBoxUseAlignment.Name = "checkBoxUseAlignment";
			this.checkBoxUseAlignment.Size = new System.Drawing.Size(254, 15);
			this.checkBoxUseAlignment.TabIndex = 0;
			this.checkBoxUseAlignment.Text = "Automatic pre-aligning of image";
			this.checkBoxUseAlignment.CheckedChanged += new System.EventHandler(this.checkBoxUseAlignment_CheckedChanged);
			// 
			// panel10
			// 
			this.panel10.Controls.Add(this.groupBox1);
			this.panel10.Controls.Add(this.groupBox2);
			this.panel10.Dock = System.Windows.Forms.DockStyle.Top;
			this.panel10.DockPadding.All = 3;
			this.panel10.Location = new System.Drawing.Point(3, 3);
			this.panel10.Name = "panel10";
			this.panel10.Size = new System.Drawing.Size(506, 100);
			this.panel10.TabIndex = 5;
			// 
			// groupBox1
			// 
			this.groupBox1.Controls.Add(this.comboBoxKPSaveWhere);
			this.groupBox1.Controls.Add(this.textBoxKPSavePrefix);
			this.groupBox1.Controls.Add(this.label2);
			this.groupBox1.Controls.Add(this.label1);
			this.groupBox1.Controls.Add(this.comboBoxKPNumber);
			this.groupBox1.Dock = System.Windows.Forms.DockStyle.Left;
			this.groupBox1.Location = new System.Drawing.Point(3, 3);
			this.groupBox1.Name = "groupBox1";
			this.groupBox1.Size = new System.Drawing.Size(190, 94);
			this.groupBox1.TabIndex = 0;
			this.groupBox1.TabStop = false;
			this.groupBox1.Text = "Keypoint generation";
			// 
			// comboBoxKPSaveWhere
			// 
			this.comboBoxKPSaveWhere.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
			this.comboBoxKPSaveWhere.Items.AddRange(new object[] {
																	 "Save keypoints to files",
																	 "Save keypoints to files(Compressed)",
																	 "Keep keypoiints in memory only"});
			this.comboBoxKPSaveWhere.Location = new System.Drawing.Point(7, 45);
			this.comboBoxKPSaveWhere.Name = "comboBoxKPSaveWhere";
			this.comboBoxKPSaveWhere.Size = new System.Drawing.Size(180, 21);
			this.comboBoxKPSaveWhere.TabIndex = 3;
			this.comboBoxKPSaveWhere.SelectedIndexChanged += new System.EventHandler(this.comboBoxKPSaveWhere_SelectedIndexChanged);
			// 
			// textBoxKPSavePrefix
			// 
			this.textBoxKPSavePrefix.Location = new System.Drawing.Point(80, 67);
			this.textBoxKPSavePrefix.Name = "textBoxKPSavePrefix";
			this.textBoxKPSavePrefix.Size = new System.Drawing.Size(93, 20);
			this.textBoxKPSavePrefix.TabIndex = 4;
			this.textBoxKPSavePrefix.Text = "ap_temp_";
			this.textBoxKPSavePrefix.Validating += new System.ComponentModel.CancelEventHandler(this.textBoxKPSavePrefix_Validating);
			// 
			// label2
			// 
			this.label2.Location = new System.Drawing.Point(13, 67);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(60, 15);
			this.label2.TabIndex = 2;
			this.label2.Text = "Save prefix: ";
			this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(120, 15);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(60, 22);
			this.label1.TabIndex = 1;
			this.label1.Text = "downscale resolution";
			this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
			// 
			// comboBoxKPNumber
			// 
			this.comboBoxKPNumber.Items.AddRange(new object[] {
																  "700",
																  "1300",
																  "Double input size",
																  "Keep input size"});
			this.comboBoxKPNumber.Location = new System.Drawing.Point(7, 15);
			this.comboBoxKPNumber.Name = "comboBoxKPNumber";
			this.comboBoxKPNumber.Size = new System.Drawing.Size(100, 21);
			this.comboBoxKPNumber.TabIndex = 0;
			this.comboBoxKPNumber.Validating += new System.ComponentModel.CancelEventHandler(this.comboBoxKPNumber_Validating);
			// 
			// groupBox2
			// 
			this.groupBox2.Controls.Add(this.checkBoxUseRANSAC);
			this.groupBox2.Controls.Add(this.comboBoxKPMatchMax);
			this.groupBox2.Controls.Add(this.label3);
			this.groupBox2.Controls.Add(this.checkBoxuseAreafilter);
			this.groupBox2.Dock = System.Windows.Forms.DockStyle.Right;
			this.groupBox2.Location = new System.Drawing.Point(263, 3);
			this.groupBox2.Name = "groupBox2";
			this.groupBox2.Size = new System.Drawing.Size(240, 94);
			this.groupBox2.TabIndex = 1;
			this.groupBox2.TabStop = false;
			this.groupBox2.Text = "Keypoint matching";
			// 
			// checkBoxUseRANSAC
			// 
			this.checkBoxUseRANSAC.Checked = true;
			this.checkBoxUseRANSAC.CheckState = System.Windows.Forms.CheckState.Checked;
			this.checkBoxUseRANSAC.Location = new System.Drawing.Point(13, 37);
			this.checkBoxUseRANSAC.Name = "checkBoxUseRANSAC";
			this.checkBoxUseRANSAC.Size = new System.Drawing.Size(174, 22);
			this.checkBoxUseRANSAC.TabIndex = 4;
			this.checkBoxUseRANSAC.Text = "Use RANSAC filtration";
			// 
			// comboBoxKPMatchMax
			// 
			this.comboBoxKPMatchMax.Items.AddRange(new object[] {
																	"12",
																	"15",
																	"20",
																	"unlimited"});
			this.comboBoxKPMatchMax.Location = new System.Drawing.Point(7, 15);
			this.comboBoxKPMatchMax.Name = "comboBoxKPMatchMax";
			this.comboBoxKPMatchMax.Size = new System.Drawing.Size(53, 21);
			this.comboBoxKPMatchMax.TabIndex = 3;
			this.comboBoxKPMatchMax.Validating += new System.ComponentModel.CancelEventHandler(this.comboBoxKPMatchMax_Validating);
			// 
			// label3
			// 
			this.label3.Location = new System.Drawing.Point(60, 15);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(173, 15);
			this.label3.TabIndex = 2;
			this.label3.Text = "maximum keypoints per image pair";
			this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
			// 
			// checkBoxuseAreafilter
			// 
			this.checkBoxuseAreafilter.Checked = true;
			this.checkBoxuseAreafilter.CheckState = System.Windows.Forms.CheckState.Checked;
			this.checkBoxuseAreafilter.Location = new System.Drawing.Point(13, 59);
			this.checkBoxuseAreafilter.Name = "checkBoxuseAreafilter";
			this.checkBoxuseAreafilter.Size = new System.Drawing.Size(174, 23);
			this.checkBoxuseAreafilter.TabIndex = 5;
			this.checkBoxuseAreafilter.Text = "Use Area filtration";
			// 
			// groupBox9
			// 
			this.groupBox9.Controls.Add(this.label7);
			this.groupBox9.Controls.Add(this.textBoxImageCount);
			this.groupBox9.Controls.Add(this.splitter4);
			this.groupBox9.Controls.Add(this.panel3);
			this.groupBox9.Controls.Add(this.listView1);
			this.groupBox9.Dock = System.Windows.Forms.DockStyle.Fill;
			this.groupBox9.Location = new System.Drawing.Point(3, 3);
			this.groupBox9.Name = "groupBox9";
			this.groupBox9.Size = new System.Drawing.Size(250, 528);
			this.groupBox9.TabIndex = 5;
			this.groupBox9.TabStop = false;
			this.groupBox9.Text = "Source images:";
			// 
			// label7
			// 
			this.label7.Location = new System.Drawing.Point(93, 0);
			this.label7.Name = "label7";
			this.label7.Size = new System.Drawing.Size(134, 15);
			this.label7.TabIndex = 6;
			this.label7.Text = "files (Select to preview)";
			// 
			// textBoxImageCount
			// 
			this.textBoxImageCount.BorderStyle = System.Windows.Forms.BorderStyle.None;
			this.textBoxImageCount.Cursor = System.Windows.Forms.Cursors.No;
			this.textBoxImageCount.ForeColor = System.Drawing.Color.Red;
			this.textBoxImageCount.Location = new System.Drawing.Point(80, 0);
			this.textBoxImageCount.Name = "textBoxImageCount";
			this.textBoxImageCount.ReadOnly = true;
			this.textBoxImageCount.Size = new System.Drawing.Size(13, 13);
			this.textBoxImageCount.TabIndex = 5;
			this.textBoxImageCount.Text = "0";
			this.textBoxImageCount.Validating += new System.ComponentModel.CancelEventHandler(this.textBoxImageCount_Validating);
			// 
			// splitter4
			// 
			this.splitter4.Location = new System.Drawing.Point(3, 16);
			this.splitter4.Name = "splitter4";
			this.splitter4.Size = new System.Drawing.Size(3, 480);
			this.splitter4.TabIndex = 4;
			this.splitter4.TabStop = false;
			// 
			// panel3
			// 
			this.panel3.Controls.Add(this.buttonAdd);
			this.panel3.Controls.Add(this.buttonRemove);
			this.panel3.Dock = System.Windows.Forms.DockStyle.Bottom;
			this.panel3.Location = new System.Drawing.Point(3, 496);
			this.panel3.Name = "panel3";
			this.panel3.Size = new System.Drawing.Size(244, 29);
			this.panel3.TabIndex = 3;
			// 
			// buttonAdd
			// 
			this.buttonAdd.Location = new System.Drawing.Point(0, 7);
			this.buttonAdd.Name = "buttonAdd";
			this.buttonAdd.Size = new System.Drawing.Size(93, 22);
			this.buttonAdd.TabIndex = 1;
			this.buttonAdd.Text = "Add images";
			this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click);
			// 
			// buttonRemove
			// 
			this.buttonRemove.Location = new System.Drawing.Point(107, 7);
			this.buttonRemove.Name = "buttonRemove";
			this.buttonRemove.Size = new System.Drawing.Size(93, 22);
			this.buttonRemove.TabIndex = 2;
			this.buttonRemove.Text = "Remove selected";
			this.buttonRemove.Click += new System.EventHandler(this.buttonRemove_Click);
			// 
			// listView1
			// 
			this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
																						this.columnHeader1,
																						this.columnHeader2,
																						this.columnHeader3});
			this.listView1.Dock = System.Windows.Forms.DockStyle.Fill;
			this.listView1.FullRowSelect = true;
			this.listView1.Location = new System.Drawing.Point(3, 16);
			this.listView1.Name = "listView1";
			this.listView1.Size = new System.Drawing.Size(244, 509);
			this.listView1.Sorting = System.Windows.Forms.SortOrder.Ascending;
			this.listView1.TabIndex = 0;
			this.listView1.View = System.Windows.Forms.View.Details;
			this.listView1.SelectedIndexChanged += new System.EventHandler(this.listView1_SelectedIndexChanged);
			// 
			// columnHeader1
			// 
			this.columnHeader1.Text = "Filename";
			this.columnHeader1.Width = 100;
			// 
			// columnHeader2
			// 
			this.columnHeader2.Text = "Information";
			this.columnHeader2.Width = 100;
			// 
			// columnHeader3
			// 
			this.columnHeader3.Text = "FilePath";
			this.columnHeader3.Width = 500;
			// 
			// panelLeft
			// 
			this.panelLeft.Controls.Add(this.groupBox9);
			this.panelLeft.Dock = System.Windows.Forms.DockStyle.Fill;
			this.panelLeft.DockPadding.All = 3;
			this.panelLeft.Location = new System.Drawing.Point(0, 0);
			this.panelLeft.Name = "panelLeft";
			this.panelLeft.Size = new System.Drawing.Size(256, 534);
			this.panelLeft.TabIndex = 6;
			// 
			// openFileDlgAddImage
			// 
			this.openFileDlgAddImage.Filter = "Image file (*.*)|*.*";
			this.openFileDlgAddImage.Multiselect = true;
			this.openFileDlgAddImage.RestoreDirectory = true;
			this.openFileDlgAddImage.Title = "Add image file";
			// 
			// openFileDlgOutputFile
			// 
			this.openFileDlgOutputFile.CheckFileExists = false;
			this.openFileDlgOutputFile.DefaultExt = "pto";
			this.openFileDlgOutputFile.Filter = "PTO file (*.pto)|*.pto";
			this.openFileDlgOutputFile.RestoreDirectory = true;
			this.openFileDlgOutputFile.Title = "Select output file";
			// 
			// errorProvider
			// 
			this.errorProvider.BlinkRate = 200;
			this.errorProvider.ContainerControl = this;
			// 
			// Form1
			// 
			this.AcceptButton = this.buttonCompute;
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(768, 574);
			this.Controls.Add(this.panelLeft);
			this.Controls.Add(this.panelRight);
			this.Controls.Add(this.splitter1);
			this.Controls.Add(this.panelBottom);
			this.Name = "Form1";
			this.Text = "autopano-sift-winGUI";
			this.panelBottom.ResumeLayout(false);
			this.panelRight.ResumeLayout(false);
			this.panel11.ResumeLayout(false);
			this.panel9.ResumeLayout(false);
			this.groupBoxPreview.ResumeLayout(false);
			this.groupBox7.ResumeLayout(false);
			this.groupBox8.ResumeLayout(false);
			this.groupBox10.ResumeLayout(false);
			this.panelAlign.ResumeLayout(false);
			this.panel5.ResumeLayout(false);
			this.panel10.ResumeLayout(false);
			this.groupBox1.ResumeLayout(false);
			this.groupBox2.ResumeLayout(false);
			this.groupBox9.ResumeLayout(false);
			this.panel3.ResumeLayout(false);
			this.panelLeft.ResumeLayout(false);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// 应用程序的主入口点。
		/// </summary>
		[STAThread]
		static void Main(string[] args) 
		{
			Form1 f1 = new Form1 ();

			int optionN = 0;
			int optionCount = 0;
			while (optionN < args.Length && args[optionN].Length >= 2 &&
				args[optionN][0] == '-')
			{
				string optionStr = args[optionN];

				if (args[optionN][1] != '-') {
					Usage ();
					Environment.Exit (1);
				}

				if (String.Compare (optionStr, "--output") == 0) {
					f1.textBoxOutputFilename.Text = args[optionN + 1];
					optionN += 2;
				} else if (String.Compare (optionStr, "--absolute") == 0) {
					f1.checkBoxAbsPath.Checked = true;
					optionN += 1;
				} else if (String.Compare (optionStr, "--imagelist") == 0) {
					StreamReader inputFiles = new StreamReader (args[optionN + 1]);
					optionN += 2;

					string iLine;
					while ((iLine = inputFiles.ReadLine ()) != null) {
						Console.WriteLine ("adding: {0}", iLine);
						f1.AddSingleImage (iLine);
					}
				} else {
					Usage ();
					Environment.Exit (1);
				}
			}
			optionCount = optionN;

			// The remaining image files
			if ((args.Length - optionCount) > 0) {
				Console.WriteLine ("B");
				string[] imgFiles = new string[args.Length - optionCount];
				Array.Copy (args, optionCount, imgFiles, 0, args.Length - optionCount);

				foreach (string imageFile in imgFiles) {
					f1.AddSingleImage (imageFile);
				}
			}

			try {
				Application.Run (f1);
			} catch (Exception ex) {
				MessageBox.Show(ex.Message);
			}
		}

		private static void Usage ()
		{
			Console.WriteLine ("usage: autopano-win32.exe [options] [imagefile1 [imagefile2 [..]]]\n");

			Console.WriteLine ("Options");
			Console.WriteLine ("  --output <filepath>     Pre-set the output PTO pathname");
			Console.WriteLine ("  --imagelist <file.txt>  Take a list of input images from a file");
			Console.WriteLine ("  --absolute              Use absolute pathnames in PTO file");
			Console.WriteLine ("\nNote:");
			Console.WriteLine ("  It is possible to use the --imagelist option multiple times.");
			Console.WriteLine ("  It is also possible to combine it with the command line image list.");
			Console.WriteLine ("");
		}

		private void buttonAdd_Click(object sender, System.EventArgs e)
		{
			string strErrorMsg = "";

			if (openFileDlgAddImage.ShowDialog () == DialogResult.OK) {
				foreach (string filename in openFileDlgAddImage.FileNames) {
					strErrorMsg += AddSingleImage (filename);

					Refresh ();					
				}

				if (bIOSameDir == false)
					checkBoxAbsPath.Checked = true;

				if (strErrorMsg != "") {
					MessageBox.Show (strErrorMsg,
						"Warning",
						MessageBoxButtons.OK,
						MessageBoxIcon.Warning);				
				}
			}
		}

		private string AddSingleImage (string filename)
		{
			Image image = null;

			try {
				image = Image.FromFile (filename);
			} catch (Exception ex) {
				return (filename + " is not an image file.\n");
			}
			
			// If loading a image existed in the tree
			for (int index = 0 ; index < listView1.Items.Count ; ++index) {
				if (filename == listView1.Items[index].SubItems[2].Text) {
					return (filename + " has already been loaded.\n");
				}
			}

			if (strInputDir == "") {
				strInputDir = Path.GetDirectoryName (filename);
			} else if (strInputDir != Path.GetDirectoryName (filename)) {
				bIOSameDir = false;						
			}

			ListViewItem listViewItem1 =
				new ListViewItem (Path.GetFileName (filename));
			listViewItem1.SubItems.Add (image.Width + " X " + image.Height);
			listViewItem1.SubItems.Add (filename);					
			listView1.Items.Add (listViewItem1);
			textBoxImageCount.Text = listView1.Items.Count.ToString ();

			return ("");
		}

		private void buttonCompute_Click(object sender, System.EventArgs e)
		{
			try
			{
				//check input validation
				bIsAllValid = true;
				iImageCount = listView1.Items.Count;
				textBoxImageCount.Text = iImageCount.ToString();		
				ArrayList arrayControl = new ArrayList();
				arrayControl.Add(textBoxImageCount);
				arrayControl.Add(comboBoxKPNumber);
				arrayControl.Add(comboBoxKPMatchMax);
				arrayControl.Add(textBoxKPSavePrefix);
				if(checkBoxGenerateHorizon.Checked)
					arrayControl.Add(comboBoxHorizonLines);
				foreach( Control control in arrayControl ) 
				{
					control.Focus();
					Validate();
				}
				if(!bIsAllValid)
				{
					MessageBox.Show("Wrong input specified, please check the reason by picking the warning icons:-)",
						"Input error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error);
					return;
				}
				//check input & output files are in the same directory
				if(strOutputDir != strInputDir && !checkBoxAbsPath.Checked){
					string strErrorMsg = "If the source images and output file are in different directories, \n" +
						"maybe you'd like to save absolute image pathnames in PTO file.\n" +
						"Press YES to enable absolute pathname, press NO to continue.";

					if(DialogResult.Yes	== MessageBox.Show(strErrorMsg, "Warning",MessageBoxButtons.YesNo, MessageBoxIcon.Warning))
						checkBoxAbsPath.Checked = true;
				}
				//get value of comboBoxKPNumber
				switch(comboBoxKPNumber.Text.Trim())
				{
					case "Double input size":iDownscaleResolution = -1; break;
					case "Keep input size":iDownscaleResolution = 0 ;break;
					default:iDownscaleResolution = Int32.Parse (comboBoxKPNumber.Text);break;
				}
				//get value of comboBoxKPMatchMax
				if (String.Compare (comboBoxKPMatchMax.Text.Trim(), "unlimited") == 0)
				{
					iMaxPairKeypoints = 0;
				} 
				else 
				{
					iMaxPairKeypoints = Int32.Parse (comboBoxKPMatchMax.Text);
				}
				//get value of comboBoxHorizonLines
				if(checkBoxGenerateHorizon.Checked)
				{
					if (String.Compare (comboBoxHorizonLines.Text.Trim(), "unlimited") == 0)
					{
						iHorizonCount = 1024;
					} 
					else 
					{
						iHorizonCount = Int32.Parse (comboBoxHorizonLines.Text);
					}
				}				
				
				iImageDoneCount = 0;
				formProcess = new FormProcess();
				formProcess.progressBarGeneration.Maximum = iImageCount;
				formProcess.progressBarGeneration.Minimum = 0;
				formProcess.labelGeneration.Text = iImageDoneCount.ToString() + " / " + iImageCount.ToString();
				formProcess.Show();
				memoryKeypointsList = new ArrayList ();
				keypointFilesList = new ArrayList ();
				formProcess.Refresh();
				switch(comboBoxKPSaveWhere.SelectedIndex)
				{
					case 0:keypointsTarget = KeypointsTarget.File;break;
					case 1:keypointsTarget = KeypointsTarget.FileCompressed;break;
					case 2:keypointsTarget = KeypointsTarget.Memory;break;
				}
				
				for(int i=0;i<iImageCount;i++)
					GenerateKeypointForImage(i);
				
				formProcess.labelMatching.Text = "Generating kd-tree...";
				formProcess.Refresh();
				MultiMatch mm = new MultiMatch ();
				if (keypointsTarget == KeypointsTarget.Memory) 
				{
					mm.LoadKeysetsFromMemory (memoryKeypointsList);
				} 
				else 
				{
					mm.LoadKeysets ((string[]) keypointFilesList.ToArray (typeof (string)));
				}
				formProcess.labelMatching.Text = "";
				formProcess.Refresh();

				formProcess.progressBarMatching.Maximum = 100;
				mm.MatchKeypoint += new MultiMatch.MatchKeypointEventHandler (UpdateMatchProgress);

				ArrayList matches = mm.LocateMatchSets (3, iMaxPairKeypoints,
					checkBoxUseRANSAC.Enabled, checkBoxuseAreafilter.Enabled);
      	
				// Component check.
				ArrayList components = mm.ComponentCheck (matches);
      	
				// BondBall algorithm
				int bottomDefault = -1;
				if (radioButtonBottomLeft.Enabled)
					bottomDefault = 0;
				else if (radioButtonBottomRight.Enabled)
					bottomDefault = 1;
      	
				BondBall bb = null;
				if (checkBoxUseAlignment.Checked) 
				{
					// FIXME: bottomDefault
					bb = mm.BuildBondBall (matches, bottomDefault);
      	
					if (bb == null) 
					{
						MessageBox.Show(String.Format ("Creating the bondball for automatic image alignment failed.{0}",
							(bottomDefault == -1) ?
							"\n\nIf your input images are not in normal position, try giving the image orientation manually using the picture icons :-)" : ""),
						"Error",
						MessageBoxButtons.OK,
						MessageBoxIcon.Error);
						formProcess.Hide();
						return;
					}
				}
				// Refine
				if (enableRefine.Checked) 
				{
					formProcess.labelMatching.Text = "Refining keypoints...";

					Autopano.RefineKeypoints (matches, this.refineMethodMiddle.Checked,
						this.keepUnrefinable.Checked,
						new Autopano.RefineKeypointEventHandler (UpdateRefineProgress));
				}

				// Write PTO file
				strPTOFilePath = textBoxOutputFilename.Text.Trim();
				TextWriter pto = new StreamWriter (strPTOFilePath, false);
				Autopano.WritePTOFile (pto, mm, matches, bb,
					iHorizonCount, checkBoxUseSubpixel.Enabled == false, checkBoxAbsPath.Enabled);
				pto.Close ();
      	
				formProcess.progressBarGeneration.Value = formProcess.progressBarGeneration.Maximum;
				if(File.Exists(strPTOFilePath))
					formProcess.labelMatching.Text = "Finished. PTO file saved.";
				else formProcess.labelMatching.Text = "There may be a bug, report it to nowozin@cs.tu-berlin.de please. \n Thank you very much!";
				formProcess.buttonOK.Enabled = true;
      	
				if (components.Count > 1) 
				{
					string componentDesc = "";
					int compN = 1;
					foreach (MultiMatch.Component comp in components)
						componentDesc += String.Format ("component {0}: {1}\n\n", compN++, comp);
      	
					MessageBox.Show(String.Format
						("A connected-component check has identified {0} components among the image matches. This means, there are images that have no connection with other images. The following components have been identified:\n\n{1}", components.Count, componentDesc),
						"Warning",
						MessageBoxButtons.OK,
						MessageBoxIcon.Warning);
				}
			}
			catch(Exception ex)
			{
				MessageBox.Show(ex.ToString());
			}
		}
		private void UpdateMatchProgress (int index, int total)
		{
			formProcess.progressBarMatching.Value = index * formProcess.progressBarMatching.Maximum / total;
			formProcess.labelMatching.Text = String.Format ("{0} / {1}", index, total);
		}
		private void UpdateRefineProgress (int index, int total)
		{
			formProcess.refiningProgress.Value = index * formProcess.refiningProgress.Maximum / total;
			formProcess.refiningLabel.Text = String.Format ("{0} / {1}", index, total);
		}

		private bool GenerateKeypointForImage (int index)
		{
			try
			{
				string strSourceFilePath = listView1.Items[index].SubItems[2].Text;
				DisplayImage disp = new DisplayImage (strSourceFilePath);
				int pW = disp.Width;
				int pH = disp.Height;

				double startScale = 1.0;
				bool doubleInputSize = false;
				switch (iDownscaleResolution) 
				{
						// Double input image size
					case (-1):
						doubleInputSize = true;
						break;
						// Keep input image size
					case (0):
						break;
						// Downscale to fit within a quadratic box of DownscaleResolution
						// pixels
					default:
						startScale = disp.ScaleWithin (iDownscaleResolution);
						break;
				}

				ImageMap picMap = disp.ConvertToImageMap (null);
				disp = null;

				LoweFeatureDetector lf = new LoweFeatureDetector ();
				lf.DetectFeaturesDownscaled(picMap, 0, 1.0 / startScale);
				iImageDoneCount++;
				formProcess.progressBarGeneration.Value = iImageDoneCount;
				formProcess.labelGeneration.Text = String.Format ("{0} / {1}", iImageDoneCount, iImageCount);
			
				if (keypointsTarget == KeypointsTarget.Memory) 
				{
					memoryKeypointsList.Add (new KeypointXMLList (strSourceFilePath,
						pW, pH, lf.GlobalNaturalKeypoints));
				} 
				else 
				{
					string targetfile = textBoxKPSavePrefix.Text +
						Path.GetFileName (strSourceFilePath) + ".xml";
					if (keypointsTarget == KeypointsTarget.FileCompressed)
						targetfile = targetfile + ".gz";

					keypointFilesList.Add (targetfile);

					KeypointXMLWriter.WriteComplete (strSourceFilePath, pW, pH, targetfile,
						lf.GlobalNaturalKeypoints);
				}
				formProcess.Refresh();
				return (false);
			}
			catch(Exception ex)
			{
				MessageBox.Show(ex.Message);
				return (false);
			}
		}

		private void listView1_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			pictureBoxPreview.Image = null;
			pictureBoxPreview.Width = 10;
			pictureBoxPreview.Height = 10;
			if(listView1.SelectedItems.Count == 0)return;
			try
			{
				Image image = Image.FromFile(listView1.SelectedItems[0].SubItems[2].Text);
				String strWidthHeight = listView1.SelectedItems[0].SubItems[1].Text;
				char[] charArray = "X".ToCharArray();
				String[] strArrayWidthHeight = strWidthHeight.Split(charArray, 2);
				pictureBoxPreview.Height = groupBoxPreview.Height-15;
				pictureBoxPreview.Width = pictureBoxPreview.Height * Convert.ToInt32(strArrayWidthHeight[0]) / Convert.ToInt32(strArrayWidthHeight[1]);				
				pictureBoxPreview.Location = new Point((groupBoxPreview.Width-pictureBoxPreview.Width)/2, (groupBoxPreview.Height-pictureBoxPreview.Height)/2+5);
				pictureBoxPreview.Image = image;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}
		private void pictureBoxPreview_Paint(Object sender, PaintEventArgs e)
		{
			// If there is an image being previewed, paint it when the Form is repainted.
			base.OnPaint(e);
			RepaintPreview();
		}
		private void RepaintPreview()
		{
			buttonCompute.Location = new Point((panelBottom.Width-buttonCompute.Width)/2,buttonCompute.Location.Y);
			if(listView1.SelectedItems.Count == 0)return;
			String strWidthHeight = listView1.SelectedItems[0].SubItems[1].Text;
			char[] charArray = "X".ToCharArray();
			String[] strArrayWidthHeight = strWidthHeight.Split(charArray, 2);
			
			pictureBoxPreview.Height = groupBoxPreview.Height-15;
			pictureBoxPreview.Width = pictureBoxPreview.Height * Convert.ToInt32(strArrayWidthHeight[0]) / Convert.ToInt32(strArrayWidthHeight[1]);				
			pictureBoxPreview.Location = new Point((groupBoxPreview.Width-pictureBoxPreview.Width)/2, (groupBoxPreview.Height-pictureBoxPreview.Height)/2+5);				
		}
		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);
			RepaintPreview();
		}
		protected override void OnResize(EventArgs e)
		{
			RepaintPreview();			
			base.OnResize(e);
		}
		
		private void buttonRemove_Click(object sender, System.EventArgs e)
		{
			if(listView1.SelectedItems.Count == 0)return;
			int iSelectCount = listView1.SelectedItems.Count;
			for(int i=iSelectCount-1;i>=0;i--)
				listView1.Items.Remove(listView1.SelectedItems[i]);
			textBoxImageCount.Text = listView1.Items.Count.ToString();
			bIOSameDir = true;
			if(listView1.Items.Count == 0)
				strInputDir = "";
			else
			{
				strInputDir = Path.GetDirectoryName(listView1.Items[0].SubItems[2].Text);
				for(int i=1;i<listView1.Items.Count;i++)
					if(Path.GetDirectoryName(listView1.Items[i].SubItems[2].Text) != strInputDir)
					{
						bIOSameDir = false;
						break;
					}
			}
		}

		private void comboBoxKPSaveWhere_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			if(comboBoxKPSaveWhere.SelectedIndex == 2)
				textBoxKPSavePrefix.Enabled = false;
			else textBoxKPSavePrefix.Enabled = true;
		}

		private void checkBoxUseAlignment_CheckedChanged(object sender, System.EventArgs e)
		{
			panelAlign.Enabled = checkBoxUseAlignment.Checked;
		}

		private void checkBoxGenerateHorizon_CheckedChanged(object sender, System.EventArgs e)
		{
			comboBoxHorizonLines.Enabled = checkBoxGenerateHorizon.Checked;
		}

		private void buttonOutput_Click(object sender, System.EventArgs e)
		{
			if(openFileDlgOutputFile.ShowDialog() == DialogResult.OK)
			{
				int iFilenameLength = openFileDlgOutputFile.FileName.Length;
				textBoxOutputFilename.Text = openFileDlgOutputFile.FileName;
				if(openFileDlgOutputFile.FileName.Substring(iFilenameLength-4).ToLower() != ".pto")
					textBoxOutputFilename.Text += ".pto";
				strOutputDir = Path.GetDirectoryName(Path.GetFullPath(textBoxOutputFilename.Text.Trim()));				
				if(strInputDir != "" && strOutputDir != strInputDir)
					checkBoxAbsPath.Checked = true;
			}
		}
		
		private void comboBoxKPNumber_Validating(object sender, CancelEventArgs e)
		{
			string strValue = comboBoxKPNumber.Text.Trim();
			if(strValue == "Double input size" || strValue == "Keep input size")
			{
				errorProvider.SetError(comboBoxKPNumber,"");
				return;
			}
			int iValue;
			string strErrorMsg = "Please input a integer not less than 64";
			try
			{
				iValue = Int32.Parse(strValue);
			}
			catch( Exception ex ) 
			{
				bIsAllValid = false;
				errorProvider.SetError(comboBoxKPNumber,strErrorMsg);
				return;
			}
			if(iValue<64)
			{
				bIsAllValid = false;
				errorProvider.SetError(comboBoxKPNumber,strErrorMsg);
			}
			else errorProvider.SetError(comboBoxKPNumber,"");
		}
		private void comboBoxKPMatchMax_Validating(object sender, CancelEventArgs e)
		{
			string strValue = comboBoxKPMatchMax.Text.Trim();
			if(strValue == "unlimited")
			{
				errorProvider.SetError(comboBoxKPMatchMax,"");
				return;
			}
			int iValue;
			string strErrorMsg = "Please input a integer not less than 3";
			try
			{
				iValue = Int32.Parse(strValue);
			}
			catch( Exception ex ) 
			{
				bIsAllValid = false;
				errorProvider.SetError(comboBoxKPMatchMax,strErrorMsg);
				return;
			}
			if(iValue<3)
			{
				bIsAllValid = false;
				errorProvider.SetError(comboBoxKPMatchMax,strErrorMsg);
			}
			else errorProvider.SetError(comboBoxKPMatchMax,"");
		}
		private void textBoxKPSavePrefix_Validating(object sender, CancelEventArgs e)
		{
			string strValue = textBoxKPSavePrefix.Text.Trim();
			string strErrorMsg = @"The filename can not contain \/:*?<>|""";
			Regex re = new Regex(@"^[^/:<>\|\*\?\\""]*$");
			if( !re.IsMatch(strValue) ) 
			{
				bIsAllValid = false;
				errorProvider.SetError(textBoxKPSavePrefix,strErrorMsg);
			}
			else errorProvider.SetError(textBoxKPSavePrefix,"");
		}
		private void comboBoxHorizonLines_Validating(object sender, CancelEventArgs e)
		{
			string strValue = comboBoxHorizonLines.Text.Trim();
			if(!checkBoxGenerateHorizon.Checked || strValue == "unlimited"){
				errorProvider.SetError(comboBoxHorizonLines,"");
				return;
			}
			string strErrorMsg = "Please input * or a positive integer.";
			int iValue;
			try 
			{				
				iValue = Int32.Parse(strValue);
			}
			catch( Exception ex ) 
			{
				bIsAllValid = false;
				errorProvider.SetError(comboBoxHorizonLines,strErrorMsg);
				return;
			}
			if(iValue <= 0)
			{
				bIsAllValid = false;
				errorProvider.SetError(comboBoxHorizonLines,strErrorMsg);
			}
			else errorProvider.SetError(comboBoxHorizonLines,"");
		}
		private void textBoxImageCount_Validating(object sender, CancelEventArgs e)
		{
			string strValue = textBoxImageCount.Text.Trim();
			string strErrorMsg = "Please add images not less than 2";
			if(Int32.Parse(strValue) <2)
			{
				bIsAllValid = false;
				errorProvider.SetError(textBoxImageCount,strErrorMsg);
			}
			else errorProvider.SetError(textBoxImageCount,"");
		}


		private enum KeypointsTarget 
		{
			File,
			FileCompressed,
			Memory,
		}
	}
}
