using System;
using Microsoft.SPOT;

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

        public struct qStruct
        {
            public qDelegate qDel;
            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].qDel = inStruct.qDel;
                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.qDel = queue[tail].qDel;
                //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;
            }
        }
    }
}
