/******************************************************************************
 * Copyright (c) 2007 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.
 * *****************************************************************************/


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

using nsAlienRFID2;



namespace Ex14
{
    public partial class FormEx14 : Form
    {
        private static clsReader mReader;

        private static Queue<Stopwatch> mqTimers = new Queue<Stopwatch>(20);

        private delegate void displayMessageDlgt(string msg, object timer);
       


        public FormEx14()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, 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 'Ex14-ScriptPerformance' application.");

            mReader = new clsReader(true);

            mReader.MessageReceived +=
                new clsReader.MessageReceivedEventHandler(mReader_MessageReceived);
            mReader.Disconnected +=
                new CBaseReader.DisconnectedEventHandler(mReader_Disconnected);
        }

        private void connectToDevice(bool b)
        {
            try
            {
                if (b)
                {
                    mReader.ConnectAndLogin(
                        txtIPAddress.Text.Trim(), 
                        int.Parse(txtPort.Text), 
                        "alien", 
                        "password");

                if (!mReader.IsConnected)
                    b = !b;
                }
                else
                {
                    mReader.Disconnect();
                    btnConnect.Enabled = true;
                    btnDisconnect.Enabled = false;
                    txtComands.Enabled = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Connection failed: " + ex.Message);
            }

            btnConnect.Enabled = !b;
            btnDisconnect.Enabled = b;
            txtComands.Enabled = b;
            txtResponses.Clear();
        }


        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            mReader.Disconnect();
            mReader.Dispose();
        }

        private void btnSendReceive_Click(object sender, EventArgs e)
        {
            txtResponses.Clear();
            txtTime.Clear();

            for (int i = 0; i < txtComands.Lines.Length; i++)
            {
                string response = null;
                string command = txtComands.Lines[i];
                Stopwatch timer = new Stopwatch();
                try
                {
                    timer.Start();
                    response = mReader.SendReceive(command, false);
                    timer.Stop();
                }
                catch (Exception ex)
                {
                    timer.Stop();
                    response = ex.Message;
                }

                txtResponses.AppendText(response + "\r\n");
                txtTime.AppendText(timer.ElapsedMilliseconds.ToString() + "\r\n");
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            txtResponses.Clear();
            txtTime.Clear();

            mqTimers.Clear();

            for (int i = 0; i < txtComands.Lines.Length; i++)
            {
                string command = txtComands.Lines[i];
                Stopwatch t = new Stopwatch();
                try
                {
                    t.Start();
                    mqTimers.Enqueue(t);
                    mReader.Send(command, false);
                    Thread.Sleep(1);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Sending the command \"" + command + "\" caused exception: " + ex.Message + "\r\n");
                }
            }
        }
        
        private void displayText(String data, object timer)
        {
            if (this.InvokeRequired)
            {
                object[] temp = { data, timer };
                this.Invoke(new displayMessageDlgt(displayText), temp);

                return;
            }
            else
            {
                if ((data.Contains("disconnected")) || 
                    (data.Contains("closed")) ||
                    (data.ToLower().Contains("Not connected")))
                {
                    btnConnect.Enabled = true;
                    btnDisconnect.Enabled = false;
                    txtComands.Enabled = false;
                }

                txtResponses.AppendText(data.Replace("\0", ""));
                Stopwatch t = timer as Stopwatch;
                if (t != null)
                    txtTime.AppendText(t.ElapsedMilliseconds.ToString() + "\r\n");
                else
                    txtTime.AppendText("\r\n");
            }
        }

        void mReader_MessageReceived(string data)
        {
            Stopwatch t = null;
       
            if (mqTimers.Count > 0)
            {
                t = mqTimers.Dequeue();
                t.Stop();
                Debug.WriteLine(data);
            }
            try { displayText(data, t); }
            catch (Exception ex) { Debug.WriteLine("_MessageReceived event handler in client: " + ex.Message); }
        }

        void mReader_Disconnected(string data)
        {
            displayText(data, null);
        }


        private void btnConnect_Click(object sender, EventArgs e)
        {
            connectToDevice(true);
        }

        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            connectToDevice(false);
        }
    }
}