using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;
using System.Diagnostics;
using System.Threading;

using nsAlienRFID2;

namespace Ex1
{
	public delegate void displayMessageDlgt(string msg);

	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private clsReader mReader;
		private ReaderInfo mReaderInfo;

		#region Auto-generated code

		private System.Windows.Forms.Button btnReaderVersion;
		private System.Windows.Forms.GroupBox grpConnection;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Button btnConnect;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.TextBox textBox1;
		private System.Windows.Forms.NumericUpDown PortUD;
		private System.Windows.Forms.TextBox textTelnet;
		private System.Windows.Forms.NumericUpDown udTimeout;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Button btnLogin;
        private CheckBox checkBox1;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

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

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.btnReaderVersion = new System.Windows.Forms.Button();
            this.btnConnect = new System.Windows.Forms.Button();
            this.grpConnection = new System.Windows.Forms.GroupBox();
            this.udTimeout = new System.Windows.Forms.NumericUpDown();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.label2 = new System.Windows.Forms.Label();
            this.PortUD = new System.Windows.Forms.NumericUpDown();
            this.label1 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.checkBox1 = new System.Windows.Forms.CheckBox();
            this.textTelnet = new System.Windows.Forms.TextBox();
            this.btnLogin = new System.Windows.Forms.Button();
            this.grpConnection.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.udTimeout)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.PortUD)).BeginInit();
            this.SuspendLayout();
            // 
            // btnReaderVersion
            // 
            this.btnReaderVersion.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.btnReaderVersion.Location = new System.Drawing.Point(421, 118);
            this.btnReaderVersion.Name = "btnReaderVersion";
            this.btnReaderVersion.Size = new System.Drawing.Size(111, 28);
            this.btnReaderVersion.TabIndex = 1;
            this.btnReaderVersion.Text = "Get Reader Version";
            this.btnReaderVersion.UseVisualStyleBackColor = false;
            this.btnReaderVersion.Click += new System.EventHandler(this.btnReaderVersion_Click);
            // 
            // btnConnect
            // 
            this.btnConnect.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.btnConnect.Location = new System.Drawing.Point(421, 36);
            this.btnConnect.Name = "btnConnect";
            this.btnConnect.Size = new System.Drawing.Size(111, 25);
            this.btnConnect.TabIndex = 2;
            this.btnConnect.Text = "Connect";
            this.btnConnect.UseVisualStyleBackColor = false;
            this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
            // 
            // grpConnection
            // 
            this.grpConnection.Controls.Add(this.udTimeout);
            this.grpConnection.Controls.Add(this.textBox1);
            this.grpConnection.Controls.Add(this.label2);
            this.grpConnection.Controls.Add(this.PortUD);
            this.grpConnection.Controls.Add(this.label1);
            this.grpConnection.Controls.Add(this.label3);
            this.grpConnection.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.grpConnection.Location = new System.Drawing.Point(20, 192);
            this.grpConnection.Name = "grpConnection";
            this.grpConnection.Size = new System.Drawing.Size(513, 63);
            this.grpConnection.TabIndex = 5;
            this.grpConnection.TabStop = false;
            this.grpConnection.Text = "Network Connection";
            // 
            // udTimeout
            // 
            this.udTimeout.Increment = new decimal(new int[] {
            100,
            0,
            0,
            0});
            this.udTimeout.Location = new System.Drawing.Point(391, 35);
            this.udTimeout.Maximum = new decimal(new int[] {
            2147483647,
            0,
            0,
            0});
            this.udTimeout.Minimum = new decimal(new int[] {
            60000,
            0,
            0,
            0});
            this.udTimeout.Name = "udTimeout";
            this.udTimeout.Size = new System.Drawing.Size(75, 20);
            this.udTimeout.TabIndex = 12;
            this.udTimeout.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.udTimeout.ThousandsSeparator = true;
            this.udTimeout.Value = new decimal(new int[] {
            60000,
            0,
            0,
            0});
            this.udTimeout.ValueChanged += new System.EventHandler(this.udTimeout_ValueChanged);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(184, 35);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(140, 20);
            this.textBox1.TabIndex = 1;
            this.textBox1.Text = "192.168.1.100";
            this.textBox1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            // 
            // label2
            // 
            this.label2.Location = new System.Drawing.Point(181, 20);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(116, 20);
            this.label2.TabIndex = 9;
            this.label2.Text = "Reader IP Address:";
            // 
            // PortUD
            // 
            this.PortUD.Location = new System.Drawing.Point(40, 35);
            this.PortUD.Maximum = new decimal(new int[] {
            10000,
            0,
            0,
            0});
            this.PortUD.Name = "PortUD";
            this.PortUD.Size = new System.Drawing.Size(78, 20);
            this.PortUD.TabIndex = 0;
            this.PortUD.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            this.PortUD.Value = new decimal(new int[] {
            23,
            0,
            0,
            0});
            this.PortUD.ValueChanged += new System.EventHandler(this.MyUpDowns_ValueChanged);
            // 
            // label1
            // 
            this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.label1.Location = new System.Drawing.Point(37, 20);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(67, 20);
            this.label1.TabIndex = 6;
            this.label1.Text = "Telnet Port:";
            // 
            // label3
            // 
            this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.label3.Location = new System.Drawing.Point(373, 20);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(112, 20);
            this.label3.TabIndex = 11;
            this.label3.Text = "Response Timeout:";
            // 
            // checkBox1
            // 
            this.checkBox1.AutoSize = true;
            this.checkBox1.Checked = true;
            this.checkBox1.CheckState = System.Windows.Forms.CheckState.Checked;
            this.checkBox1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.checkBox1.Location = new System.Drawing.Point(411, 169);
            this.checkBox1.Name = "checkBox1";
            this.checkBox1.Size = new System.Drawing.Size(134, 17);
            this.checkBox1.TabIndex = 13;
            this.checkBox1.Text = "Keep Conenction Alive";
            this.checkBox1.UseVisualStyleBackColor = true;
            this.checkBox1.CheckedChanged += new System.EventHandler(this.checkBox1_CheckedChanged);
            // 
            // textTelnet
            // 
            this.textTelnet.BackColor = System.Drawing.SystemColors.WindowFrame;
            this.textTelnet.ForeColor = System.Drawing.SystemColors.Info;
            this.textTelnet.Location = new System.Drawing.Point(24, 16);
            this.textTelnet.Multiline = true;
            this.textTelnet.Name = "textTelnet";
            this.textTelnet.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.textTelnet.Size = new System.Drawing.Size(377, 170);
            this.textTelnet.TabIndex = 12;
            this.textTelnet.KeyUp += new System.Windows.Forms.KeyEventHandler(this.textTelnet_KeyUp);
            // 
            // btnLogin
            // 
            this.btnLogin.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.btnLogin.Enabled = false;
            this.btnLogin.Location = new System.Drawing.Point(421, 77);
            this.btnLogin.Name = "btnLogin";
            this.btnLogin.Size = new System.Drawing.Size(111, 25);
            this.btnLogin.TabIndex = 3;
            this.btnLogin.Text = "Login";
            this.btnLogin.UseVisualStyleBackColor = false;
            this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.BackColor = System.Drawing.SystemColors.ControlText;
            this.ClientSize = new System.Drawing.Size(553, 266);
            this.Controls.Add(this.checkBox1);
            this.Controls.Add(this.btnLogin);
            this.Controls.Add(this.textTelnet);
            this.Controls.Add(this.grpConnection);
            this.Controls.Add(this.btnConnect);
            this.Controls.Add(this.btnReaderVersion);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
            this.grpConnection.ResumeLayout(false);
            this.grpConnection.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.udTimeout)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.PortUD)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

		}

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

		#endregion

		private void Form1_Load(object sender, System.EventArgs e)
		{
            string exePath = Application.ExecutablePath;
            int idx = exePath.LastIndexOf("\\");
            if (idx != -1)
                AlienLog.Path = exePath.Substring(0, idx + 1);
            AlienLog.WriteLine(true, "Starting the 'Ex2-Telnet Connection' application.");

            mReader = new clsReader(true);

            mReaderInfo = new ReaderInfo();
			PortUD.Value = 23;

			this.Text = "Alien Library .NET - Testing Telnet Connection";

			Thread.CurrentThread.Name = "Alien-Ex.2: Test Telnet";

            mReader.KeepNetworkConnectionAlive = checkBox1.Checked;

			//subscribe to mReader's events
			mReader.DataReceived +=new nsAlienRFID2.clsReader.DataReceivedEventHandler(mReader_DataReceived);
			mReader.MessageReceived += new nsAlienRFID2.clsReader.MessageReceivedEventHandler(mReader_MessageReceived);
			mReader.Disconnected +=new nsAlienRFID2.clsReader.DisconnectedEventHandler(mReader_Disconnected);
		}

		private void btnReaderVersion_Click(object sender, System.EventArgs e)
		{		//Get Reader Version
			this.Cursor = Cursors.WaitCursor;
            try
            {
                DisplayText(mReader.ReaderVersion);
            }
            catch (Exception ex)
            {
                DisplayText(ex.Message);
            }
		}

		private void btnConnect_Click(object sender, System.EventArgs e)
		{
			String result;
			this.Cursor = Cursors.WaitCursor;
			try
			{
				if (!mReader.IsConnected)
				{
                    string ip = textBox1.Text;
                    int port = (int)(PortUD.Value);
					mReader.InitOnNetwork(ip, port);
					result = mReader.Connect();
                    bool state = mReader.IsConnected;
                    if (state)
                    {
                        textTelnet.AppendText(result);
                        btnConnect.Text = "Disconnect";
                    }
                    else
                    {
                        DisplayText("Can't connect to IP Address '" +
                            ip + "' and Port #: " + port.ToString());
                    }
                    btnLogin.Enabled = state;
                    grpConnection.Enabled = !state;
				}
				else
				{		//disconnect
					mReader.Disconnect();
					btnConnect.Text = "Connect";
                    btnLogin.Enabled = false;
                    grpConnection.Enabled = true;
					DisplayText("Reader connection closed");
				}
			}
			catch(Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
			this.Cursor = Cursors.Default;
		}

        private void btnLogin_Click(object sender, System.EventArgs e)
        {
            if (mReader.Login("alien", "password"))		//returns result synchronously
            {
                DisplayText("Logged in - OK!");
            }
            else
            {
                DisplayText("Login failed");
            }
            bool connected = mReader.IsConnected;
            btnConnect.Text = connected ? "Disconnect" : "Connect";
            btnLogin.Enabled = !connected;
            grpConnection.Enabled = !connected;
        }
        
        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			if (mReader != null)
			{
				mReader.Dispose();
			}
		}

		private void MyUpDowns_ValueChanged(object sender, System.EventArgs e)
		{
			NumericUpDown who = (NumericUpDown)sender;
			mReaderInfo.TelnetPort = Convert.ToInt32(who.Value);
			mReader.ReaderSettings = mReaderInfo;
		}

		private void mReader_DataReceived(string data)
		{
//			try
//			{
//				DisplayText("From DataReceived event:\r\n" + 
//					"----------------------------------------\r\n" + data);			}
//			catch(Exception ex)
//			{
//				MessageBox.Show(ex.Message);
//			}
		}

		private void mReader_MessageReceived(string data)
		{
			String stemp = "";
			if (data.Length > 1)
				stemp = "From MessageReceived event:\r\n" + 
							"-------------------------------------------------\r\n" + data;
			else	//don't show MessageReceived header if only '\0'
				stemp = data;

			DisplayText(stemp);
		}

		private void mReader_Disconnected(string data)
		{
			DisplayText("From Disconnected event:\r\n" + 
							"---------------------------------\r\n" + data);
		}
		
		private void textTelnet_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			String command = null;
			try
			{
				if (e.KeyCode == Keys.Enter)
				{
                    string[] lines = textTelnet.Lines;
                    int idx = textTelnet.GetLineFromCharIndex(textTelnet.SelectionStart) - 1;
                    if (idx >= 0)   // must be always true
                    {   
                        command = lines[idx];
                        if (!string.IsNullOrEmpty(command))
                        {
                            DisplayText(mReader.SendReceive(command, false));
                        }
                    }
				}
			}
			catch(Exception ex)
			{
				MessageBox.Show(ex.Message);
			}
		}


		private void DisplayText(String data)
		{
			if (InvokeRequired)
			{
				object[] temp = {data};
				this.Invoke(new displayMessageDlgt(DisplayText),temp);
				return;
			}
			else
			{
                try
                {
                    if (data.IndexOf("Username>") != -1)
                    {	//get rid of login prompt
                        data = data.Substring(0, data.Length - 10);
                    }
                    //add formatting with CR, LF
                    String stemp = "";
                    if (!data.StartsWith("\r\n"))
                    {
                        stemp = "\r\n" + data;
                        data = stemp;
                    }
                    if (!data.EndsWith("\r\n"))
                    {
                        stemp = data + "\r\n";
                        data = stemp;
                    }
                    addText(data);
                    if (data.Contains("From Disconnected event"))
                    {
                        btnLogin.Enabled = false;
                        btnConnect.Text = "Connect";
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
			}
		}

        void addText(string s)
        {
            textTelnet.AppendText(s.Replace("\0", "\\0"));
            textTelnet.Focus();
            textTelnet.ScrollToCaret();
            textBox1.SelectAll();
            this.Cursor = Cursors.Default;
        }

		private void udTimeout_ValueChanged(object sender, System.EventArgs e)
		{
			mReader.ComTimeOutInterval = (int)udTimeout.Value;			
		}

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (mReader != null)
                mReader.KeepNetworkConnectionAlive = checkBox1.Checked;
        }
	}
}
