using System;
using Microsoft.SPOT;

namespace CPF
{
    public class StructQueue
    {
        //public delegate void qDelegate(qStruct inQStruct);

        public enum QRecordType : int
        {
            Optode = 0,
            SBE41,
            CN0254,
            PTH,
            InstrumentHandler,
            Console,
            WriteLog,
            PositionReport,
            MT_MessageArrived,
            FileReceived,
            FileSent
        }

        public struct qStruct
        {
            public QRecordType          qRecordType;
            public int                  errorCode;
            public DateTime             timeStamp;
            public Program.CPFStates    state;
            public byte[]               byteArray;
        }

        private const int qDepth = 64;
        public const int qRecordWidth = 512;

        private static qStruct[] queue;

        private static qStruct returnStruct;

        private static int head;
        private static int tail;
        private static int count;

        public StructQueue()
        {
            queue = new qStruct[qDepth];

            head = 0;
            tail = 0;
            count = 0;

            for (int i = 0; i < qDepth; i++)
                queue[i].byteArray = new byte[qRecordWidth];

        }

        public int Count
        {
            get { return count; }
        }

        public void Clear()
        {
            count = 0;
            tail = head;
        }

        public void Enqueue(qStruct inStruct)
        {
            //GM I've taken out the ability to grow since if the queue does have to grow, something is wrong
            //if (count == qDepth)
            //{
            //  Grow();
            //}
            //queue[head] = value;
            if (count >= qDepth)
            {
                throw new InvalidOperationException("Queue is full");
            }
            else
            {
                queue[head].qRecordType = inStruct.qRecordType;
                queue[head].timeStamp = inStruct.timeStamp;
                queue[head].state = inStruct.state;
                Array.Copy(inStruct.byteArray, queue[head].byteArray, inStruct.byteArray.Length);
                head = (head + 1) % qDepth;
                count++;
            }
        }

        public qStruct Dequeue()
        {
            if (count == 0)
            {
                throw new InvalidOperationException("Queue is empty");
            }
            else
            {
                returnStruct = queue[tail];

                //returnStruct.qRecordType = queue[tail].qRecordType;
                //returnStruct.timeStamp = queue[tail].timeStamp;
                //returnStruct.state = queue[tail].state;
                //Array.Copy(queue[tail].byteArray, returnStruct.byteArray, queue[tail].byteArray.Length);

                tail = (tail + 1) % qDepth;
                count--;
                return returnStruct;
            }
        }
    }
}
