using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using EMDServer.Common;
using System.IO.Ports;

namespace EMDHardwareClientSimulation.Connection.RS232
{
    class RxHandler
    {
        #region Class variables
        // ----------------------------------------
        private Queue<byte[]> rxQueue;
        private bool running;
        private SerialPort com;

        public event EventHandler msgReceived;
        // ----------------------------------------
        #endregion

        #region Public methods
        // ----------------------------------------
        /// <summary>
        /// Creates a new instance of the class
        /// </summary>
        /// <param name="com">SerialPort over which data will be received</param>
        public RxHandler(SerialPort com)
        {
            this.rxQueue = new Queue<byte[]>();
            this.running = true;

            this.com = com;

            // start rx thread
            Thread t = new Thread(new ThreadStart(run));
            t.Start();

            Debug.WriteLine("RXHANDLER - Instantiated!");
        }

        public void createDummyMessage()
        {
            byte[] data = new byte[6];
            data[0] = 11;
            data[1] = (byte)Constants.EMD_COMMAND.POWER_VALUE;
            data[2] = 2;
            data[3] = 8;
            data[4] = 5;
            data[5] = 1;

            lock (this)
            {
                rxQueue.Enqueue(data);
            }

            onMessageReceived();
        }

        /// <summary>
        /// Reads and removes the first message from the 
        /// receiver queue
        /// </summary>
        /// <returns>a received message as String</returns>
        public byte[] getMessage()
        {
            byte[] msg = null;

            lock (rxQueue)
            {
                if (rxQueue.Count > 0)
                {
                    msg = rxQueue.Dequeue();
                }
            }
            //Debug.WriteLine("DEVICEMANAGER - Got message: " + msg);

            return msg;
        }

        /// <summary>
        /// Receives command messages from the serial
        /// port and writes it into a receiver queue
        /// </summary>
        public void run()
        {
            byte[] data = new byte[6];

            while (running)
            {
                try
                {

                    for (int i = 0; i < 6; i++)
                    {
                        data[i] = (byte)com.ReadByte();
                    }

                    lock (rxQueue)
                    {
                        rxQueue.Enqueue(data);
                    }

                    Debug.WriteLine("RXHANDLER - New data received...");
                    onMessageReceived();
                }
                catch (Exception e)
                {
                    Debug.WriteLine("RXHANDLER - Nid gäbig: " + e);
                }
            }
        }

        /// <summary>
        /// Stops the receiver thread
        /// </summary>
        public void exit()
        {
            this.running = false;

            Debug.WriteLine("RXHANDLER - Exit!");
        }
        // ----------------------------------------
        #endregion

        #region Eventhandler
        // ----------------------------------------
        public void onMessageReceived()
        {
            if (this.msgReceived != null)
            {
                msgReceived(this, null);
            }
        }
        // ----------------------------------------
        #endregion
    }
}
