using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace MyNamespace
{
	/// <summary>
	///	History form for multiple precision calculators
	///		Developed in TURBO Pascal 5.5 and 6.0, converted to Visual Basic 6
	///		and now in Visual C# .Net
	///
	/// ---------------- *** LEGAL NOTICE: *** ------------------
	///
	/// This program is free software; you can redistribute it and/or modify
	/// it under the terms of the GNU General Public License (GPL) as published
	/// by the Free Software Foundation. cf. the file COPYING.txt.
	///
	/// ------------ *** end of legal notice *** ------------------
	/// </summary>

	public class HistoryForm : Form
	{
		private Button buttonDeleteC;
		private Button buttonDoIt;
		private Button buttonFind;
		private Button buttonFindUp;
		private Label labelCNumber;
		private Label labelMComs;
		private Label labelTitle;
		private MainMenu mainMenuHistory;
		private MenuItem menuItem1;
		private MenuItem menuItemClearHistory;
		private MenuItem menuItemDash;
		private MenuItem menuItemExit;
		private MenuItem menuItemFile;
		private MenuItem menuItemRestoreHistory;
		private MenuItem menuItemSaveHistory;
		private RichTextBox richTextOut;
		private TextBox textBoxCNumber;
		private TextBox textBoxDeleteC;
		private TextBox textBoxFind;
		private Timer timerHistory;

		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.IContainer components;

		public HistoryForm()
		{
			InitializeComponent();

			findSt = "";
		}

		/// <summary>
		/// no "Clean up any resources being used"
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			RunForm.histWidth = this.Width;
			RunForm.histHeight = this.Height;
			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();
			System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(HistoryForm));
			this.richTextOut = new RichTextBox();
			this.mainMenuHistory = new MainMenu(this.components);
			this.menuItemFile = new MenuItem();
			this.menuItemClearHistory = new MenuItem();
			this.menuItemRestoreHistory = new MenuItem();
			this.menuItemSaveHistory = new MenuItem();
			this.menuItemDash = new MenuItem();
			this.menuItemExit = new MenuItem();
			this.menuItem1 = new MenuItem();
			this.labelCNumber = new Label();
			this.textBoxCNumber = new TextBox();
			this.buttonDoIt = new Button();
			this.buttonDeleteC = new Button();
			this.textBoxDeleteC = new TextBox();
			this.labelMComs = new Label();
			this.timerHistory = new Timer(this.components);
			this.buttonFindUp = new Button();
			this.textBoxFind = new TextBox();
			this.buttonFind = new Button();
			this.labelTitle = new Label();
			this.SuspendLayout();
			// 
			// richTextOut
			// 
			this.richTextOut.BackColor = System.Drawing.SystemColors.Window;
			this.richTextOut.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.richTextOut.Location = new System.Drawing.Point(0, 72);
			this.richTextOut.Name = "richTextOut";
			this.richTextOut.ReadOnly = true;
			this.richTextOut.Size = new System.Drawing.Size(696, 504);
			this.richTextOut.TabIndex = 0;
			this.richTextOut.Text = "richTextOut";
			this.richTextOut.KeyDown += new KeyEventHandler(this.richTextOut_KeyDown);
			this.richTextOut.MouseDown += new MouseEventHandler(this.richTextOut_MouseDown);
			// 
			// mainMenuHistory
			// 
			this.mainMenuHistory.MenuItems.AddRange(new MenuItem[] {
			this.menuItemFile,
			this.menuItem1});
			// 
			// menuItemFile
			// 
			this.menuItemFile.Index = 0;
			this.menuItemFile.MenuItems.AddRange(new MenuItem[] {
			this.menuItemClearHistory,
			this.menuItemRestoreHistory,
			this.menuItemSaveHistory,
			this.menuItemDash,
			this.menuItemExit});
			this.menuItemFile.Text = "&File";
			// 
			// menuItemClearHistory
			// 
			this.menuItemClearHistory.Index = 0;
			this.menuItemClearHistory.Text = "&Clear History";
			this.menuItemClearHistory.Click += new System.EventHandler(this.menuItemClearHistory_Click);
			// 
			// menuItemRestoreHistory
			// 
			this.menuItemRestoreHistory.Index = 1;
			this.menuItemRestoreHistory.Text = "&Restore History";
			this.menuItemRestoreHistory.Click += new System.EventHandler(this.menuItemRestoreHistory_Click);
			// 
			// menuItemSaveHistory
			// 
			this.menuItemSaveHistory.Index = 2;
			this.menuItemSaveHistory.Text = "&Save History";
			this.menuItemSaveHistory.Click += new System.EventHandler(this.menuItemSaveHistory_Click);
			// 
			// menuItemDash
			// 
			this.menuItemDash.Index = 3;
			this.menuItemDash.Text = "-";
			// 
			// menuItemExit
			// 
			this.menuItemExit.Index = 4;
			this.menuItemExit.Text = "E&xit";
			this.menuItemExit.Click += new System.EventHandler(this.menuItemExit_Click);
			// 
			// menuItem1
			// 
			this.menuItem1.Index = 1;
			this.menuItem1.Text = "";
			// 
			// labelCNumber
			// 
			this.labelCNumber.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.labelCNumber.Location = new System.Drawing.Point(8, 8);
			this.labelCNumber.Name = "labelCNumber";
			this.labelCNumber.Size = new System.Drawing.Size(200, 16);
			this.labelCNumber.TabIndex = 1;
			this.labelCNumber.Text = "No. of command to restore:";
			// 
			// textBoxCNumber
			// 
			this.textBoxCNumber.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.textBoxCNumber.Location = new System.Drawing.Point(192, 8);
			this.textBoxCNumber.Name = "textBoxCNumber";
			this.textBoxCNumber.Size = new System.Drawing.Size(72, 24);
			this.textBoxCNumber.TabIndex = 2;
			this.textBoxCNumber.Text = "1";
			this.textBoxCNumber.TextChanged += new System.EventHandler(this.textBoxCNumber_TextChanged);
			this.textBoxCNumber.KeyDown += new KeyEventHandler(this.textBoxCNumber_KeyDown);
			// 
			// buttonDoIt
			// 
			this.buttonDoIt.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.buttonDoIt.Location = new System.Drawing.Point(272, 8);
			this.buttonDoIt.Name = "buttonDoIt";
			this.buttonDoIt.Size = new System.Drawing.Size(64, 24);
			this.buttonDoIt.TabIndex = 3;
			this.buttonDoIt.Text = "Do It";
			this.buttonDoIt.Click += new System.EventHandler(this.buttonDoIt_Click);
			// 
			// buttonDeleteC
			// 
			this.buttonDeleteC.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.buttonDeleteC.Location = new System.Drawing.Point(368, 8);
			this.buttonDeleteC.Name = "buttonDeleteC";
			this.buttonDeleteC.Size = new System.Drawing.Size(120, 24);
			this.buttonDeleteC.TabIndex = 4;
			this.buttonDeleteC.Text = "Delete No.:";
			this.buttonDeleteC.Click += new System.EventHandler(this.buttonDeleteC_Click);
			// 
			// textBoxDeleteC
			// 
			this.textBoxDeleteC.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.textBoxDeleteC.Location = new System.Drawing.Point(496, 8);
			this.textBoxDeleteC.Name = "textBoxDeleteC";
			this.textBoxDeleteC.Size = new System.Drawing.Size(72, 24);
			this.textBoxDeleteC.TabIndex = 5;
			this.textBoxDeleteC.Text = "1";
			this.textBoxDeleteC.TextChanged += new System.EventHandler(this.textBoxDeleteC_TextChanged);
			this.textBoxDeleteC.KeyDown += new KeyEventHandler(this.textBoxDeleteC_KeyDown);
			// 
			// labelMComs
			// 
			this.labelMComs.Font = new System.Drawing.Font("Courier New", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.labelMComs.Location = new System.Drawing.Point(576, 16);
			this.labelMComs.Name = "labelMComs";
			this.labelMComs.Size = new System.Drawing.Size(120, 16);
			this.labelMComs.TabIndex = 6;
			this.labelMComs.Text = "Max = 100000";
			// 
			// timerHistory
			// 
			this.timerHistory.Enabled = true;
			this.timerHistory.Interval = 500;
			this.timerHistory.Tick += new System.EventHandler(this.timerHistory_Tick);
			// 
			// buttonFindUp
			// 
			this.buttonFindUp.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.buttonFindUp.Location = new System.Drawing.Point(632, 40);
			this.buttonFindUp.Name = "buttonFindUp";
			this.buttonFindUp.Size = new System.Drawing.Size(48, 24);
			this.buttonFindUp.TabIndex = 7;
			this.buttonFindUp.Text = "F2 Up";
			this.buttonFindUp.Click += new System.EventHandler(this.buttonFindUp_Click);
			// 
			// textBoxFind
			// 
			this.textBoxFind.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.textBoxFind.Location = new System.Drawing.Point(528, 40);
			this.textBoxFind.Name = "textBoxFind";
			this.textBoxFind.Size = new System.Drawing.Size(100, 22);
			this.textBoxFind.TabIndex = 8;
			this.textBoxFind.KeyDown += new KeyEventHandler(this.textBoxFind_KeyDown);
			// 
			// buttonFind
			// 
			this.buttonFind.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.buttonFind.Location = new System.Drawing.Point(464, 40);
			this.buttonFind.Name = "buttonFind";
			this.buttonFind.Size = new System.Drawing.Size(56, 24);
			this.buttonFind.TabIndex = 9;
			this.buttonFind.Text = "F3 Find:";
			this.buttonFind.Click += new System.EventHandler(this.buttonFind_Click);
			this.buttonFind.KeyDown += new KeyEventHandler(this.textBoxFind_KeyDown);
			// 
			// labelTitle
			// 
			this.labelTitle.Font = new System.Drawing.Font("Tahoma", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
			this.labelTitle.Location = new System.Drawing.Point(24, 40);
			this.labelTitle.Name = "labelTitle";
			this.labelTitle.Size = new System.Drawing.Size(440, 24);
			this.labelTitle.TabIndex = 10;
			this.labelTitle.Text = "<App.Title> Help Form";
			// 
			// HistoryForm
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(696, 470);
			this.Controls.Add(this.labelTitle);
			this.Controls.Add(this.buttonFind);
			this.Controls.Add(this.textBoxFind);
			this.Controls.Add(this.buttonFindUp);
			this.Controls.Add(this.labelMComs);
			this.Controls.Add(this.textBoxDeleteC);
			this.Controls.Add(this.buttonDeleteC);
			this.Controls.Add(this.buttonDoIt);
			this.Controls.Add(this.textBoxCNumber);
			this.Controls.Add(this.labelCNumber);
			this.Controls.Add(this.richTextOut);
			this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
			this.Menu = this.mainMenuHistory;
			this.Name = "HistoryForm";
			this.Text = "HistoryForm";
			this.Resize += new System.EventHandler(this.HistoryForm_Resize);
			this.Closing += new System.ComponentModel.CancelEventHandler(this.HistoryForm_Closing);
			this.KeyDown += new KeyEventHandler(this.richTextOut_KeyDown);
			this.ResumeLayout(false);
			this.PerformLayout();

		}
		#endregion

		// -------- Begin Main program, Restore Input from History
		public void History()
		{
			// don't allow History to be brought up more than once
			if (Common.historyUp) { Dispose(true); return; }
			Common.historyUp = true;
			this.Text = Global.title + " - Restore Input History";
			labelTitle.Text = Global.title + " History";
			richTextOut.SelectionStart = 0;
			richTextOut.Text = "";	// clear text output window
			DisplayComs();			// display Commands
			ReFocus();
			this.Width = RunForm.histWidth;			// Resize the form
			this.Height = RunForm.histHeight;
		}

		private void DisplayComs()	// display all Commands that can be Restored
									// and set TextBoxes to max and min command numbers
		{
			labelMComs.Text = "Max = " + Common.mComs;
			textBoxDeleteC.Text = "1";
			textBoxCNumber.Text = Common.cComs.ToString();
			if (Common.cComs == 0) textBoxDeleteC.Text = "0";
			richTextOut.Text = "";					// clear text output window
			for (int i = Common.cComs; i > 0; i--)	// display all previous commands input
			{
				Prn(Common.comPF[i] + i + ": " + Common.comHL[i]);
				if (i > 1)
				{
					PLn("");
					PLn(Common.StringOf(40, "-"));
				}
			}
			textBoxDeleteC.SelectionStart = textBoxDeleteC.Text.Length;
			richTextOut.SelectionStart = 0; // move cursor to top
		}

		private void buttonDeleteC_Click(object sender, System.EventArgs e) // delete a command from history list
		{
			int n = System.Int32.Parse(textBoxDeleteC.Text);
			DeleteCom(n);
			if (n > 0)
			{
				textBoxDeleteC.Focus();
				textBoxDeleteC.SelectionStart = textBoxDeleteC.Text.Length;
			}
			else
			{
				ReFocus();
			}
		}

		private void buttonDoIt_Click(object sender, System.EventArgs e) // restore the selected command to top of list,
																		 // accept it and close this form
		{
			if (labelCNumber.Enabled)
			{
				int i = System.Int32.Parse(textBoxCNumber.Text);
				if (1 <= i && i < Common.cComs) // move selected command to comHL(cComs)
				{
					string st = Common.comHL[i];
					string sP = Common.comPF[i];
					for (int j = i; j < Common.cComs; j++)
					{
						Common.comHL[j] = Common.comHL[j+1];
						Common.comPF[j] = Common.comPF[j+1];
					}
					Common.comHL[Common.cComs] = st;
					Common.comPF[Common.cComs] = sP;
				}
				Common.inS.Focus();								// moved SetFocus to before Text update
				Common.inS.Text = Common.comHL[Common.cComs];	// restore last command to input
				Common.inS.SelectionStart = Common.inS.Text.Length;
				Common.iComs = Common.cComs;
			}
			Common.historyUp = false;
			Dispose(true);
		}

		private void menuItemClearHistory_Click(object sender, System.EventArgs e) // same as ClearHist command
		{
			Common.DoubleSpace();
			Common.ClearHist();
			DisplayComs();
			ReFocus();
		}

		private void menuItemRestoreHistory_Click(object sender, System.EventArgs e) // read history file and add it to command list
		{
			Common.RestoreHist();
			richTextOut.Text = "";					// clear text output window
			Prn(Common.cComs + " Command");
			if (Common.cComs != 1) Prn("s");
			PLn2(" read from History file " + Common.histFile + ".");
			if (Common.cComs != 0) DisplayComs();	// display the new command history list
			ReFocus();
		}

		private void menuItemSaveHistory_Click(object sender, System.EventArgs e) // save command history to a file
		{
			Common.SaveHist();
			ReFocus();
		}

		private void textBoxDeleteC_TextChanged(object sender, System.EventArgs e) // validate the Delete Command number
		{
			textBoxDeleteC.Text = textBoxDeleteC.Text.TrimStart(' '); // remove leading spaces
			string sNum = textBoxDeleteC.Text;
			if (Global.IsInt32(sNum))
			{
				int iNum = System.Int32.Parse(sNum);
				buttonDeleteC.Enabled = (1 <= iNum && iNum <= Common.cComs);
			}
			else
			{
				buttonDeleteC.Enabled = false;
			}
			int n = sNum.Length;
			if (n > 0)
			{
				if (sNum[n-1] == ' ') // if space at end, accept
				{
					textBoxDeleteC.Text = textBoxDeleteC.Text.Trim(' ');
					textBoxDeleteC.SelectionStart = textBoxDeleteC.Text.Length;
					if (buttonDeleteC.Enabled) buttonDeleteC_Click(sender, e);
				}
			}
		}

		private void Prn(string p) // print string to richTextOut window
		{
			richTextOut.SelectionStart = richTextOut.Text.Length;
			richTextOut.Text += p;
		}

		private void PLn(string p) // print string ... and new line
		{
			if (p != "") Prn(p);
			richTextOut.Text += "\n";
		}

		private void PLn2(string p) // print string ... and double new line
		{
			if (p != "") Prn(p);
			richTextOut.Text += "\n\n";
		}

		private void textBoxCNumber_TextChanged(object sender, System.EventArgs e) // validate Select Command number to restore
		{
			int iNum;
			int n;
			textBoxCNumber.Text = textBoxCNumber.Text.TrimStart(' '); // remove leading spaces
			string sNum = textBoxCNumber.Text;
			if (Global.IsInt32(sNum))
			{
				iNum = System.Int32.Parse(sNum);
				labelCNumber.Enabled = (1 <= iNum && iNum <= Common.cComs);
			}
			else
			{
				labelCNumber.Enabled = false;
			}
			if (labelCNumber.Enabled) // bold font
				this.labelCNumber.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			else // regular font
				this.labelCNumber.Font = new System.Drawing.Font("Tahoma", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0)));
			n = sNum.Length;
			if (n > 0)
			{
				if (sNum[n-1] == ' ') // if space at end, accept
				{
					buttonDoIt_Click(sender, e);
				}
			}
		}

		private void menuItemExit_Click(object sender, System.EventArgs e) // exit History form
		{
			Common.historyUp = false;
			Dispose(true);
		}

		private int SelectCom() // move cursor to beginning of this command
								// and select the command number to restore, return command number
		{
			int j;
			int n;
			string st;
			if (Common.cComs == 0) return 0;	// no commands in history so exit
			string EndL = "----\n";				// set end of command indicator
			int i = richTextOut.SelectionStart; // i = current cursor position
			if (i < 1) i = 1;
			i = richTextOut.Text.LastIndexOf(EndL, i-1);
			if (i < 0)							// at top so select max command number
			{
				n = Common.cComs;
				i = richTextOut.Text.IndexOf(n.ToString() + ": ") - 1;
			}
			else
			{
				i += 5 ;
				j = Math.Min(richTextOut.Text.Length - i, 20);
				st = richTextOut.Text.Substring(i, j);
				j = st.IndexOf(":");
				if (j < 0)						// at bottom so select Command number 1
				{
					n = 1;
					i -= 5;
					i = richTextOut.Text.LastIndexOf(EndL, i);
					i += 5;
				}
				else
				{
					st = st.Substring(1, j - 1);
					if (Global.IsInt32(st))
					{
						n = System.Int32.Parse(st);
					}
					else
					{
						n = 1;
					}
				}
			}
			textBoxCNumber.Text = n.ToString();
			textBoxDeleteC.Text = n.ToString();
			richTextOut.SelectionStart = i;
			return n;
		}

		private void MoveToN(int n) // move cursor to command number n
		{
			if (n < 1) n = Common.cComs;
			if (n > Common.cComs) n = 1;
			if (n == Common.cComs)
			{
				richTextOut.SelectionStart = 0;
			}
			else if (n == 1)
			{
				richTextOut.SelectionStart = richTextOut.Text.Length;
			}
			int i = richTextOut.Text.IndexOf("----\n " + n + ": ");
			if (i < 1)
			{
				i = richTextOut.Text.IndexOf("----\n#" + n + ": ");
			}
			if (i < 1)
			{
				i = richTextOut.Text.IndexOf(n + ": ") - 2;
			}
			else
			{
				i += 5;
			}
			if (i < 0) i = 0;
			textBoxCNumber.Text = n.ToString();
			textBoxDeleteC.Text = n.ToString();
			richTextOut.SelectionStart = i;
		}

		private void DeleteCom(int n) // delete command number n
		{
			if (Common.cComs < 1 || n < 1 || n > Common.cComs) return;
			if (Common.comPF[n] != " ")
			{
				MoveToN(n + 1);
				return;									// don't delete a protected command
			}
			Common.cComs = Common.cComs - 1;
			Common.iComs = Common.cComs;
			for (int i = n; i <= Common.cComs; i++)
			{
				Common.comHL[i] = Common.comHL[i+1];	// move commands to close-up list
				Common.comPF[i] = Common.comPF[i+1];
			}
			Common.comHL[Common.cComs+1] = "";			// purge unused list entry
			richTextOut.SelectionStart = 0;
			richTextOut.Text = "";						// clear text output window
			DisplayComs();								// redisplay commands
			if (n > Common.cComs) n = Common.cComs;
			if (System.Int32.Parse(textBoxDeleteC.Text) > Common.cComs) textBoxDeleteC.Text = Common.cComs.ToString();
			if (System.Int32.Parse(textBoxCNumber.Text) > Common.cComs) textBoxCNumber.Text = Common.cComs.ToString();
			MoveToN(n);
		}

		private void ProtectCom(int n) // protect command n from deleting, toggle
		{
			string sP;
			int i;
			if (Common.comPF[n] == " ")
				sP = "#";
			else
				sP = " ";
			Common.comPF[n] = sP;
			i = richTextOut.SelectionStart;
			richTextOut.Text = richTextOut.Text.Substring(0, i) + sP +
				richTextOut.Text.Substring(i+1);
			richTextOut.SelectionStart = i;
		}

		private void textBoxCNumber_KeyDown(object sender, KeyEventArgs e)
		// process keys when in command to restore box
		{
			if (e.KeyCode == Keys.Return)		// return is an accept key here
			{
				buttonDoIt_Click(sender, e);	// accept weather enabled or not
			}
			else if (e.KeyCode == Keys.Escape)	// exit History
			{
				Common.historyUp = false;
				Dispose(true);
			}
			else if (e.KeyCode == Keys.F2)	// F2 key pressed so do a find going up
			{
				buttonFindUp_Click(sender, e);
			}
			else if (e.KeyCode == Keys.F3 || e.KeyCode == Keys.Return) // F3 key or Return pressed so do a normal find
			{
				buttonFind_Click(sender, e);
			}
		}

		private void textBoxDeleteC_KeyDown(object sender, KeyEventArgs e)
		// process keys when in Delete command number box
		{
			if (e.KeyCode == Keys.Escape)		// exit History
			{
				Common.historyUp = false;
				Dispose(true);
			}
			else if (e.KeyCode == Keys.Return)	// return is an accept key here
			{
				// this sounds the bell
				if (buttonDeleteC.Enabled) buttonDeleteC_Click(sender, e);
			}
			else if (e.KeyCode == Keys.F2)	// F2 key pressed so do a find going up
			{
				buttonFindUp_Click(sender, e);
			}
			else if (e.KeyCode == Keys.F3 || e.KeyCode == Keys.Return) // F3 key or Return pressed so do a normal find
			{
				buttonFind_Click(sender, e);
			}
		}

		private void richTextOut_KeyDown(object sender, KeyEventArgs e)
			// process keys input to output TextBox
		{
			int n;
			if (e.KeyCode == Keys.Escape)		// ESC key pressed so Exit History
			{
				Common.historyUp = false;
				Dispose(true);
			}
			else if (e.KeyCode == Keys.Return || e.KeyCode == Keys.Space) // accept the command
			{
				SelectCom();
				buttonDoIt_Click(sender, e);
			}
			else if (e.KeyCode == Keys.Delete)	// Del Key, Delete the command
			{
				DeleteCom(SelectCom());
			}
			else if (e.KeyCode == Keys.Insert)	// Ins Key, Protect command toggle
			{
				n = SelectCom();
				ProtectCom(n);
				MoveToN(n + 1);
			}
			else if (e.KeyCode == Keys.Add)		// + Key, Scroll down the list by one command
			{
				MoveToN(SelectCom() - 1);
			}
			else if (e.KeyCode == Keys.Subtract) // - Key, Scroll up the list by one command
			{
				MoveToN(SelectCom() + 1);
				// - is up and + is down due to layout of keypad, - above +
				// only the keypad + and - keys are used here
			}
			else if (e.KeyCode == Keys.F2)	// F2 key pressed so do a find going up
			{
				buttonFindUp_Click(sender, e);
			}
			else if (e.KeyCode == Keys.F3 || e.KeyCode == Keys.Return) // F3 key or Return pressed so do a normal find
			{
				buttonFind_Click(sender, e);
			}
			else if (e.KeyCode == Keys.F)	// F key pressed so copy selected text to textBoxFind
			{
				if (e.Control)
				{
					string st = richTextOut.SelectedText;	// only copy up to first newline
					int i = st.IndexOf("\n");
					if (i >= 0) st = st.Substring(0, i);
					textBoxFind.Text = st;
					textBoxFind.Select(0, st.Length);		// move cursor found location
					textBoxFind.Focus();					// and focus
				}
			}
		} // richTextOut_KeyDown

		private void textBoxFind_KeyDown(object sender, KeyEventArgs e)
		// process keys input to output TextBox
		{
			if (e.KeyCode == Keys.Escape)		// ESC key pressed so Exit History
			{
				Common.historyUp = false;
				Dispose(true);
			}
			else if (e.KeyCode == Keys.F2)	// F2 key pressed so do a find going up
			{
				buttonFindUp_Click(sender, e);
			}
			else if (e.KeyCode == Keys.F3 || e.KeyCode == Keys.Return) // F3 key or Return pressed so do a normal find
			{
				buttonFind_Click(sender, e);
			}
		} // textBoxFind_KeyDown

		private void richTextOut_MouseDown(object sender, MouseEventArgs e)
		// process Mouse down in output TextBox
		{
			if (richTextOut.Focused && e.Button.ToString() == "Right")
			{
				SelectCom();
				buttonDoIt_Click(sender, e);
			}
		}

		private void HistoryForm_Resize(object sender, System.EventArgs e) // resize the history form
		{
			int jTop = buttonFind.Top + buttonFind.Height + 8;
			this.richTextOut.SetBounds(1, jTop , this.ClientRectangle.Width - 2, this.ClientRectangle.Height - jTop - 1);
		}

		private void ReFocus() // focus on CNumber Text Box
		{
			textBoxCNumber.Focus();
			textBoxCNumber.SelectionStart = textBoxCNumber.Text.Length;
		}

		private void HistoryForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		// exit History form
		{
			Common.historyUp = false;
		}

		private void timerHistory_Tick(object sender, System.EventArgs e)
		{
			if (!Global.runFormUp)
			{
				Common.historyUp = false;
				Dispose(true);
			}
		}

		internal class Helpers
		{
			[Flags]
				public enum PlaySoundFlags : int
			{
				SND_SYNC = 0x0000,	/* play synchronously (default) */
				SND_ASYNC = 0x0001,	/* play asynchronously */
				SND_NODEFAULT = 0x0002,	/* silence (!default) if sound not found */
				SND_MEMORY = 0x0004,	/* pszSound points to a memory file */
				SND_LOOP = 0x0008,		/* loop the sound until next sndPlaySound */
				SND_NOSTOP = 0x0010,	/* don't stop any currently playing sound */
				SND_NOWAIT = 0x00002000,	/* don't wait if the driver is busy */
				SND_ALIAS = 0x00010000,		/* name is a registry alias */
				SND_ALIAS_ID = 0x00110000,	/* alias is a predefined ID */
				SND_FILENAME = 0x00020000,	/* name is file name */
				SND_RESOURCE = 0x00040004	/* name is resource name or atom */
			}

			[DllImport("winmm.dll")]
			public static extern bool PlaySound( string szSound, IntPtr hMod, PlaySoundFlags flags );

			[DllImport("kernel32.dll")]
			public static extern bool Beep(int freq, int dur);
		}

		public class Sound
		{
			public static void Play( string strFileName )
			{
				try
				{
					Helpers.PlaySound( strFileName, IntPtr.Zero, Helpers.PlaySoundFlags.SND_FILENAME | Helpers.PlaySoundFlags.SND_ASYNC );
				}
				catch
				{
					// DllImport("winmm.dll") file not found or no PlaySound entry point in the file
					// so generate no sound
				}
			}
		}
		
		public int FindMyText(string searchText, int searchStart, int searchEnd)
		{
			// Initialize the return value to false by default.
			int returnValue = -1;

			// Ensure that a search string and a valid starting point are specified.
			if (searchText.Length > 0 && searchStart >= 0)
			{
				// Ensure that a valid ending value is provided.
				if (searchEnd > searchStart || searchEnd == -1)
				{
					// Obtain the location of the search string in the richTextBox.
					int indexToText = richTextOut.Find(searchText, searchStart, searchEnd, RichTextBoxFinds.None);
					// Determine whether the text was found in richTextBox1.
					if(indexToText >= 0)
					{
						// Return the index to the specified search text.
						returnValue = indexToText;
					}
				}
			}
			return returnValue;
		} // FindMyText

		public int FindMyTextUp(string searchText, int searchStart, int searchEnd)
		{
			// Initialize the return value to false by default.
			int returnValue = -1;

			// Ensure that a search string and a valid starting point are specified.
			if (searchText.Length > 0 && searchStart >= 0)
			{
				// Ensure that a valid ending value is provided.
				if (searchEnd > searchStart || searchEnd == -1)
				{
					// Obtain the location of the search string in the richTextBox.
					int indexToText = richTextOut.Find(searchText, searchStart, searchEnd, RichTextBoxFinds.Reverse);
					// Determine whether the text was found in richTextBox1.
					if(indexToText >= 0)
					{
						// Return the index to the specified search text.
						returnValue = indexToText;
					}
				}
			}
			return returnValue;
		} // FindMyTextUp
		
		private void buttonFind_Click(object sender, System.EventArgs e)
		{
			int found = -1;
			richTextOut.Focus();			// focus on output text
			if (textBoxFind.Text != "")
				findSt = textBoxFind.Text;
			int length = findSt.Length;
			if (length == 0)
				return;
			int scope = richTextOut.Text.Length;
			int start = richTextOut.SelectionStart;
			int begin = Math.Min(start + 1, scope);
			if (begin != scope)
				found = FindMyText(findSt, begin, scope);
			if (found < 0)
			{
				int end = Math.Min(start + length, scope);
				found = FindMyText(findSt, 0, end);
				if (found >= 0)
				{
					Sound.Play("Wrap.wav");
				}
				else
				{
					Sound.Play("NotFound.wav");
				}
			}
			else
			{
				TryBeep(277, 50);			// beep Frequency 277Hz, Length 50ms
			}								// 277 is middle C#
			if (found >= 0)
			{
				richTextOut.Select(found, length);	// move cursor found location
				richTextOut.Focus();				// and focus
			}		
		}

		private void buttonFindUp_Click(object sender, System.EventArgs e)
		{
			int found = -1;
			richTextOut.Focus();			// focus on output text
			if (textBoxFind.Text != "")
				findSt = textBoxFind.Text;
			int length = findSt.Length;
			if (length == 0)
				return;
			int scope = richTextOut.Text.Length;
			int start = richTextOut.SelectionStart + length;
			int end = Math.Max(start - 1, 0);
			if (end != 0)
				found = FindMyTextUp(findSt, 0, end);
			if (found < 0)
			{
				int begin = Math.Max(start - length, 0);
				found = FindMyTextUp(findSt, begin, scope);
				if (found >= 0)
				{
					Sound.Play("Wrap.wav");
				}
				else
				{
					Sound.Play("NotFound.wav");
				}
			}
			else
			{
				TryBeep(277*2, 50);			// beep Frequency 554Hz, Length 50ms
			}								// 554 is one octave above middle C#
			if (found >= 0)
			{
				richTextOut.Select(found, length);	// move cursor found location
				richTextOut.Focus();				// and focus
			}		
		} // buttonFindUp_Click

		private void TryBeep(int freq, int dur)
		{
			try
			{
				Helpers.Beep(freq, dur);			// beep freq, duration
			}
			catch
			{
				// DllImport("kernel32.dll") file not found or no Beep entry point in the file
				// so no beep
			}
		}
		
		private string findSt;	// string to find
	}
}
