#region "Legal Notice"
/*******************************************************************************
 *
 * Copyright (c) 2006 Alien Technology Corporation.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1)	Redistributions of source code must retain the above copyright 
 *		notice, this list of conditions and the following disclaimer. 
 *
 * 2)	Redistributions in binary form must reproduce the above copyright 
 *		notice, this list of conditions and the following disclaimer 
 *		in the documentation and/or other materials provided with the distribution. 
 *
 * 3)	Neither the name of Alien Technology Corporation nor the names of any 
 *		contributors may be used to endorse or promote products derived from this 
 *		software without specific prior written permission. 
 *
 *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 *	AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 *	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *	ARE DISCLAIMED. IN NO EVENT SHALL ALIEN TECHNOLOGY CORPORATION OR ITS 
 *	CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 *	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 *	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 *	OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 *	WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 *	OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 *	OF THE POSSIBILITY OF SUCH DAMAGE.
 ***********************************************************************************/

#endregion

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Text;
using System.Threading;

using nsAlienRFID2;

namespace Ex10
{
	public delegate void displayConnectionDelegate(string msg);
	public delegate void displayUpgradeDelegate(object upgradeState);

    public delegate void displayMessageDlgt(string msg);

    public class Form1 : Form
    {
        clsReader mReader = null;
        volatile bool mbComplete = true;
        private ReaderInfo mReaderInfo;
        private Stack mProgress = new Stack();
        private static readonly object mTimerLock = new object();
        private volatile bool mbClosing = false;
        private ComInterface meReaderInterface = ComInterface.enumTCPIP;


        #region Windows Form Designer generated code

        private System.Windows.Forms.Button btnUpgrade;
        private System.Windows.Forms.Button btnCancel;
        private System.Windows.Forms.ProgressBar progressBar1;
        private System.Windows.Forms.Button btnDisconnect;
        private System.Windows.Forms.Button btnConnect;
        private System.Windows.Forms.GroupBox grpNetwork;
        private System.Windows.Forms.TextBox txtIPAddress;
        private System.Windows.Forms.Label label2;
        private System.Windows.Forms.NumericUpDown PortUD;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.GroupBox grpStatus;
        private System.Windows.Forms.TextBox txtFile;
        private System.Windows.Forms.OpenFileDialog openFileDialog1;
        private System.Windows.Forms.Button btnBrowse;
        private System.Windows.Forms.TextBox txtPassword;
        private System.Windows.Forms.Label label6;
        private System.Windows.Forms.TextBox txtUserName;
        private System.Windows.Forms.Label label5;
        private System.Windows.Forms.Label lblStatus;
        private System.Windows.Forms.Timer timer1;


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

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (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.components = new System.ComponentModel.Container();
            this.btnUpgrade = new System.Windows.Forms.Button();
            this.btnCancel = new System.Windows.Forms.Button();
            this.progressBar1 = new System.Windows.Forms.ProgressBar();
            this.btnDisconnect = new System.Windows.Forms.Button();
            this.btnConnect = new System.Windows.Forms.Button();
            this.grpNetwork = new System.Windows.Forms.GroupBox();
            this.txtPassword = new System.Windows.Forms.TextBox();
            this.label6 = new System.Windows.Forms.Label();
            this.txtUserName = new System.Windows.Forms.TextBox();
            this.label5 = new System.Windows.Forms.Label();
            this.txtIPAddress = 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.grpStatus = new System.Windows.Forms.GroupBox();
            this.lblStatus = new System.Windows.Forms.Label();
            this.txtFile = new System.Windows.Forms.TextBox();
            this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
            this.btnBrowse = new System.Windows.Forms.Button();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.grpNetwork.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.PortUD)).BeginInit();
            this.grpStatus.SuspendLayout();
            this.SuspendLayout();
            // 
            // btnUpgrade
            // 
            this.btnUpgrade.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.btnUpgrade.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.btnUpgrade.ForeColor = System.Drawing.Color.Black;
            this.btnUpgrade.Location = new System.Drawing.Point(737, 101);
            this.btnUpgrade.Name = "btnUpgrade";
            this.btnUpgrade.Size = new System.Drawing.Size(83, 34);
            this.btnUpgrade.TabIndex = 3;
            this.btnUpgrade.Text = "&Upgrade";
            this.btnUpgrade.UseVisualStyleBackColor = false;
            this.btnUpgrade.Click += new System.EventHandler(this.btnUpgrade_Click);
            // 
            // btnCancel
            // 
            this.btnCancel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.btnCancel.ForeColor = System.Drawing.Color.Black;
            this.btnCancel.Location = new System.Drawing.Point(46, 101);
            this.btnCancel.Name = "btnCancel";
            this.btnCancel.Size = new System.Drawing.Size(83, 34);
            this.btnCancel.TabIndex = 4;
            this.btnCancel.Text = "&Cancel";
            this.btnCancel.UseVisualStyleBackColor = false;
            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
            // 
            // progressBar1
            // 
            this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.progressBar1.ForeColor = System.Drawing.Color.Blue;
            this.progressBar1.Location = new System.Drawing.Point(32, 24);
            this.progressBar1.Name = "progressBar1";
            this.progressBar1.Size = new System.Drawing.Size(766, 12);
            this.progressBar1.TabIndex = 3;
            // 
            // btnDisconnect
            // 
            this.btnDisconnect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.btnDisconnect.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.btnDisconnect.Enabled = false;
            this.btnDisconnect.ForeColor = System.Drawing.SystemColors.WindowText;
            this.btnDisconnect.Location = new System.Drawing.Point(728, 21);
            this.btnDisconnect.Name = "btnDisconnect";
            this.btnDisconnect.Size = new System.Drawing.Size(112, 23);
            this.btnDisconnect.TabIndex = 27;
            this.btnDisconnect.Text = "&Disconnect";
            this.btnDisconnect.UseVisualStyleBackColor = false;
            this.btnDisconnect.Click += new System.EventHandler(this.btnDisconnect_Click);
            // 
            // btnConnect
            // 
            this.btnConnect.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.btnConnect.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.btnConnect.ForeColor = System.Drawing.SystemColors.WindowText;
            this.btnConnect.Location = new System.Drawing.Point(728, 50);
            this.btnConnect.Name = "btnConnect";
            this.btnConnect.Size = new System.Drawing.Size(112, 25);
            this.btnConnect.TabIndex = 1;
            this.btnConnect.Text = "Co&nnect + Login";
            this.btnConnect.UseVisualStyleBackColor = false;
            this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
            // 
            // grpNetwork
            // 
            this.grpNetwork.Controls.Add(this.txtPassword);
            this.grpNetwork.Controls.Add(this.label6);
            this.grpNetwork.Controls.Add(this.txtUserName);
            this.grpNetwork.Controls.Add(this.label5);
            this.grpNetwork.Controls.Add(this.txtIPAddress);
            this.grpNetwork.Controls.Add(this.label2);
            this.grpNetwork.Controls.Add(this.PortUD);
            this.grpNetwork.Controls.Add(this.label1);
            this.grpNetwork.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.grpNetwork.Location = new System.Drawing.Point(22, 12);
            this.grpNetwork.Name = "grpNetwork";
            this.grpNetwork.Size = new System.Drawing.Size(664, 63);
            this.grpNetwork.TabIndex = 0;
            this.grpNetwork.TabStop = false;
            this.grpNetwork.Text = "Network Settings";
            // 
            // txtPassword
            // 
            this.txtPassword.Location = new System.Drawing.Point(553, 26);
            this.txtPassword.Name = "txtPassword";
            this.txtPassword.PasswordChar = '*';
            this.txtPassword.Size = new System.Drawing.Size(87, 20);
            this.txtPassword.TabIndex = 3;
            this.txtPassword.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            // 
            // label6
            // 
            this.label6.Location = new System.Drawing.Point(499, 27);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(57, 20);
            this.label6.TabIndex = 16;
            this.label6.Text = "Password:";
            // 
            // txtUserName
            // 
            this.txtUserName.Location = new System.Drawing.Point(391, 29);
            this.txtUserName.Name = "txtUserName";
            this.txtUserName.Size = new System.Drawing.Size(87, 20);
            this.txtUserName.TabIndex = 2;
            this.txtUserName.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            // 
            // label5
            // 
            this.label5.Location = new System.Drawing.Point(329, 28);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(68, 20);
            this.label5.TabIndex = 1511;
            this.label5.Text = "User Name:";
            // 
            // txtIPAddress
            // 
            this.txtIPAddress.Location = new System.Drawing.Point(214, 27);
            this.txtIPAddress.Name = "txtIPAddress";
            this.txtIPAddress.Size = new System.Drawing.Size(82, 20);
            this.txtIPAddress.TabIndex = 1;
            this.txtIPAddress.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
            // 
            // label2
            // 
            this.label2.Location = new System.Drawing.Point(150, 29);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(75, 20);
            this.label2.TabIndex = 19;
            this.label2.Text = "IP Address:";
            // 
            // PortUD
            // 
            this.PortUD.Location = new System.Drawing.Point(70, 30);
            this.PortUD.Maximum = new decimal(new int[] {
            10000,
            0,
            0,
            0});
            this.PortUD.Name = "PortUD";
            this.PortUD.Size = new System.Drawing.Size(47, 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(6, 30);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(72, 20);
            this.label1.TabIndex = 16;
            this.label1.Text = "Telnet Port:";
            // 
            // grpStatus
            // 
            this.grpStatus.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.grpStatus.Controls.Add(this.lblStatus);
            this.grpStatus.Controls.Add(this.progressBar1);
            this.grpStatus.Location = new System.Drawing.Point(22, 154);
            this.grpStatus.Name = "grpStatus";
            this.grpStatus.Size = new System.Drawing.Size(830, 351);
            this.grpStatus.TabIndex = 30;
            this.grpStatus.TabStop = false;
            this.grpStatus.Text = "Status: ";
            // 
            // lblStatus
            // 
            this.lblStatus.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.lblStatus.Location = new System.Drawing.Point(40, 56);
            this.lblStatus.Name = "lblStatus";
            this.lblStatus.Size = new System.Drawing.Size(758, 287);
            this.lblStatus.TabIndex = 0;
            this.lblStatus.Text = "Status";
            this.lblStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // txtFile
            // 
            this.txtFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.txtFile.Location = new System.Drawing.Point(147, 109);
            this.txtFile.Name = "txtFile";
            this.txtFile.Size = new System.Drawing.Size(536, 20);
            this.txtFile.TabIndex = 31;
            // 
            // openFileDialog1
            // 
            this.openFileDialog1.FileName = "openFileDialog1";
            this.openFileDialog1.InitialDirectory = "C:\\\\";
            // 
            // btnBrowse
            // 
            this.btnBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this.btnBrowse.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.btnBrowse.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.btnBrowse.ForeColor = System.Drawing.Color.Black;
            this.btnBrowse.Location = new System.Drawing.Point(680, 106);
            this.btnBrowse.Name = "btnBrowse";
            this.btnBrowse.Size = new System.Drawing.Size(40, 24);
            this.btnBrowse.TabIndex = 2;
            this.btnBrowse.Text = "...";
            this.btnBrowse.UseVisualStyleBackColor = false;
            this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);
            // 
            // timer1
            // 
            this.timer1.Enabled = true;
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.BackColor = System.Drawing.SystemColors.WindowText;
            this.ClientSize = new System.Drawing.Size(876, 517);
            this.Controls.Add(this.btnBrowse);
            this.Controls.Add(this.txtFile);
            this.Controls.Add(this.grpStatus);
            this.Controls.Add(this.btnDisconnect);
            this.Controls.Add(this.btnConnect);
            this.Controls.Add(this.grpNetwork);
            this.Controls.Add(this.btnCancel);
            this.Controls.Add(this.btnUpgrade);
            this.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(192)))));
            this.MinimumSize = new System.Drawing.Size(884, 400);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
            this.grpNetwork.ResumeLayout(false);
            this.grpNetwork.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.PortUD)).EndInit();
            this.grpStatus.ResumeLayout(false);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

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

        #endregion

        public Form1()
        {
            InitializeComponent();

            // set up double-buffering
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.DoubleBuffer, true);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string exepath = Application.ExecutablePath;
            AlienLog.Path = exepath.Substring(0, exepath.LastIndexOf("\\") + 1);

            mReader = new clsReader(true);
            mReader.UpgradeProgress += new clsReader.UpgradeProgressEventHandler(mReader_UpgradeProgress);
            mReader.UpgradeComplete += new clsReader.UpgradeCompleteEventHandler(mReader_UpgradeComplete);
            mReader.Disconnected += new clsReader.DisconnectedEventHandler(mReader_Disconnected);
            mReader.Connected += new clsReader.ConnectedEventHandler(mReader_Connected);
            mReaderInfo = mReader.ReaderSettings;

            Thread.CurrentThread.Name = "Alien-Ex.10: Reader Upgrade";
            this.Text = "Alien Library .NET - Upgrade Reader's Firmware";
        }

        void mReader_DataReceived(string data)
        {
            if (data.Trim() == "\0")
                return;
            displayText(data.Replace("\r", "[\\r]\r").Replace("\n", "[\\n]\n").Replace("\0", "[\\0]"));
        }

        private void displayText(String data)
        {
            try
            {
                if (this.InvokeRequired)
                {
                    object[] temp = { data };
                    this.Invoke(new displayMessageDlgt(displayText), temp);
                    return;
                }
                else
                {
                    lblStatus.Text = data;
                    this.Cursor = Cursors.Default;
                    return;
                }
            }
            catch (Exception ex)
            {
                AlienLog.WriteLine(true, "Exception in the DiscplayText: " + ex.Message);
            }
        }

        private void displayConnection(String data)
        {
            try
            {
                if (this.InvokeRequired)
                {
                    object[] temp = { data };
                    this.Invoke(new displayConnectionDelegate(displayConnection), temp);
                    return;
                }
                else
                {
                    if (data != null)
                        lblStatus.Text = data as string;

                    bool connected = (data == null);

                    btnDisconnect.Enabled = (connected) ? true : false;
                    btnConnect.Enabled = (connected) ? false : true;

                    bool state = btnUpgrade.Enabled;
                    grpNetwork.Enabled = state;

                    return;
                }
            }
            catch (Exception ex)
            {
                lblStatus.Text = "Exception in the DiscplayConnection: " + ex.Message;
            }
        }


        private void displayUpgrade(object upgradeState)
        {
            try
            {
                if (this.InvokeRequired)
                {
                    object[] temp = { upgradeState };
                    this.Invoke(new displayUpgradeDelegate(displayUpgrade), temp);
                    return;
                }
                else
                {
                    UpgradeInfo state = upgradeState as UpgradeInfo;
                    if (state != null)
                    {
                        if (state.PercentDone == 100)
                            this.progressBar1.Value = 0;
                        else
                            this.progressBar1.Value = state.PercentDone;

                        this.btnCancel.Enabled = state.CanCancel;
                        this.btnUpgrade.Enabled = state.Completed;
                        mbComplete = state.Completed;

                        AlienLog.WriteLine(true, state.ToString().Replace("\r", "\\r").Replace("\n", "\\n\t").Replace("\0", "\\0"));
                    }

                    return;
                }
            }
            catch (Exception ex)
            {
                lblStatus.Text = "Exception in the discplayUpgrade(): " + ex.Message;
            }
        }
        private void mReader_Connected()
        {
            displayConnection(null);
        }
        private void mReader_Disconnected(string data)
        {
            displayConnection(data);
        }


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

        void mReader_UpgradeComplete(UpgradeInfo upgradeState)
        {

            lock (mProgress.SyncRoot)
            {
                mbComplete = true;
                mProgress.Push(upgradeState);
            }
        }

        void mReader_UpgradeProgress(UpgradeInfo upgradeState)
        {
            lock (mProgress.SyncRoot) { mProgress.Push(upgradeState); }
        }

        private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (!mbComplete)
            {
                lblStatus.Text = "Trying to cancel upgrade...";
                mbClosing = true;
                try { mReader.CancelUpgrade(); }
                catch { }
                e.Cancel = true;
            }
            else
            {
                mReader.Disconnect();
                mReader.Dispose();
            }
        }

        private void btnUpgrade_Click(object sender, EventArgs e)
        {
            mbComplete = false;
            btnUpgrade.Enabled = false;
            btnCancel.Enabled = true;
            btnDisconnect.Enabled = false;

            try
            {
                mReader.UpgradeFirmware(txtFile.Text);
                this.Cursor = Cursors.WaitCursor;
                btnUpgrade.Enabled = false;
            }
            catch (Exception ex)
            {
                lblStatus.Text = ex.Message;
                mbComplete = true;
                btnUpgrade.Enabled = true;
                btnCancel.Enabled = false;
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            try { mReader.CancelUpgrade(); }
            catch (Exception ex)
            {
                lblStatus.Text = ex.Message;
            }
            this.btnCancel.Enabled = false;
        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            if ((openFileDialog1.ShowDialog() == DialogResult.OK))
            {
                txtFile.Text = openFileDialog1.FileName;
                btnUpgrade.Enabled = true;
                this.Cursor = Cursors.Default;
                this.ControlBox = true;
                if (mbClosing)
                    this.Close();
            }
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            String result;
            this.Cursor = Cursors.WaitCursor;
            try		// extra precausion though it shouldn't throw exceptions
            {
                if (meReaderInterface == ComInterface.enumTCPIP)
                    mReader.InitOnNetwork(txtIPAddress.Text, Convert.ToInt32(PortUD.Value));
                else
                    mReader.InitOnCom();

                lblStatus.Text = "Connecting to the reader...";
                this.Cursor = Cursors.WaitCursor;

                result = mReader.Connect();
                if (!mReader.IsConnected)
                {
                    lblStatus.Text = result;
                }
                else
                {
                    lblStatus.Text = "Connected.  Logging in...";
                    this.Cursor = Cursors.WaitCursor;
                    if (!mReader.Login(txtUserName.Text, txtPassword.Text))		//returns result synchronously
                    {
                        lblStatus.Text = "Login failed! Calling Disconnect()...";
                        mReader.Disconnect();
                        return;
                    }
                    lblStatus.Text = "Logged in - OK!";	//  Current firmware version: " + mReader.ReaderVersion;

                    string info = null;
                    try { info = mReader.Info; }
                    catch { }
                    if (info != null)
                    {
                        btnDisconnect.Enabled = true;
                        btnConnect.Enabled = false;
                        lblStatus.Text = info;
                        mReader.DataReceived += new CBaseReader.DataReceivedEventHandler(mReader_DataReceived);
                    }
                    else
                    {
                        lblStatus.Text = "Unknown reader version!";
                    }
                }
            }
            catch (Exception ex)
            {
                lblStatus.Text = ex.Message;
                btnDisconnect_Click(null, null);
            }
            this.Cursor = Cursors.Default;
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            mReader.DataReceived -= new CBaseReader.DataReceivedEventHandler(mReader_DataReceived);
            mReader.Disconnect();
            btnDisconnect.Enabled = false;
            btnConnect.Enabled = true;

            grpNetwork.Enabled = true;

            this.Cursor = Cursors.Default;
        }

        private void timer1_Tick(object sender, System.EventArgs e)
        {
            lock (mTimerLock)
            {
                timer1.Stop();

                UpgradeInfo data = null;

                lock (mProgress.SyncRoot)
                {
                    if (mProgress.Count > 0)
                    {
                        data = mProgress.Pop() as UpgradeInfo;
                        mProgress.Clear();
                    }
                }
                if (data != null)
                {
                    mbComplete = data.Completed;

                    if (data.PercentDone == 100)
                        this.progressBar1.Value = 0;
                    else if (data.PercentDone > 100)
                        this.progressBar1.Value = 100;
                    else
                        this.progressBar1.Value = data.PercentDone;

                    lblStatus.Text = data.ToString();

                    btnCancel.Enabled = data.CanCancel;
                    this.ControlBox = data.CanCancel;

                    btnUpgrade.Enabled = data.Completed;
                    if (mbComplete)
                    {
                        this.Cursor = Cursors.Default;
                        this.ControlBox = true;
                        if (mbClosing)
                            this.Close();
                    }
                }
                if (mbComplete)
                {
                    btnDisconnect.Enabled = true;
                }
                timer1.Start();
            }
        }
    }
}