using System;
using Microsoft.SPOT;

namespace Logger
{
    public class LogEntryQueueOverflowException : System.Exception
    {    
        public LogEntryQueueOverflowException() : base() { }
        public LogEntryQueueOverflowException(string message) : base(message) { }
        public LogEntryQueueOverflowException(string message, System.Exception inner) : base(message, inner) { }
    }

    public class LogEntryQueueEmptyException : System.Exception
    {
        public LogEntryQueueEmptyException() : base() { }
        public LogEntryQueueEmptyException(string message) : base(message) { }
        public LogEntryQueueEmptyException(string message, System.Exception inner) : base(message, inner) { }
    }

    public class LogEntryQueue
    {
        public      LogEntry[]      _logEntries;
        private     int             _head;
        private     int             _tail;

        public LogEntryQueue(int capacity) 
        {
            // validate capacity
            if (capacity <= 0) 
                throw new ArgumentException("Must be greater than zero", "capacity");
            // set capacity and init the cache
            Capacity = capacity;
            _logEntries = new LogEntry[capacity];
            for (int i = 0; i < capacity; i++ )
                _logEntries[i] = new LogEntry();
            Clear();
        }

        public void Clear()
        {
            Count = 0;
            _head = 0;
            _tail = 0;
        }

        public int Capacity { get; private set; }

        public int Count { get; private set; }

        public bool Empty()
        {
            return (Count == 0) ? true : false;
        }

        public bool Full()
        {
            return (Count == Capacity) ? true : false;
        }
        
        public void Insert(LogEntry e) 
        {
            if (!Full())
            {
                _logEntries[_tail] = (LogEntry) e.Clone();
                _tail = (_tail + 1) % _logEntries.Length;
                Count++;
            } 
            else
            {
                throw new LogEntryQueueOverflowException();
            }
        }

        public LogEntry Delete()
        {
            if (!Empty())
            {
                LogEntry e = _logEntries[_head];
                _head = (_head + 1) % _logEntries.Length;
                Count--;
                return e;
            }
            else
            {
                throw new LogEntryQueueEmptyException();
            }
        }
    }
}
