using System;
using Microsoft.SPOT;

namespace CPF
{
    public class RingBuffer
    {
        public readonly int     _size;
        private byte[]          _buffer;
        private int             _readPos = 0;
        int                     _writePos = 0;

        public void Clear()
        {
            _writePos = 0;
            _readPos = 0;
        }

        public RingBuffer(int Size)
        {
            _size = Size;
            _buffer = new byte[_size];
            Clear();
        }

        public bool IsEmpty()
        {
            return (_readPos == _writePos) ? true : false;
        }

        public int Count
        {
            get
            {
                int len = _writePos - _readPos;
                if (len < 0)
                    len += _size;
                return len;
            }
        }

        public void Write(byte[] data)
        {
            foreach (byte b in data)
            {
                Write(b);
            }
        }

        public void Write(byte[] data, int size)
        {
            for (int i = 0; i < size; i++)
            {
                Write(data[i]);
            }
        }

        public void Write(byte[] data, int offset, int size)
        {
            for (int i = 0; i < size; i++)
            {
                Write(data[offset + i]);
            }
        }

        public void Write(byte data)
        {
            _buffer[_writePos] = data;
            _writePos = (_writePos + 1) % _size;
            if (_readPos == _writePos)
                throw new Exception("Buffer full");
        }

        public byte Peek()
        {
            return _buffer[_readPos];
        }

        public byte Read()
        {
            int pos = _readPos;
            _readPos = (_readPos + 1) % _size;
            return _buffer[pos];
        }

        public void PushBack(byte data)
        {
            _readPos = (_readPos - 1) % _size;
            _buffer[_readPos] = data;
        }

        public void Read(byte[] buffer, int offset, int len)
        {
            for (int i = 0; i < len; ++i)
                buffer[i + offset] = Read();
        }

        public void Discard(int bytes)
        {
            if (Count < bytes)
                bytes = Count;

            _readPos = (_readPos + bytes) % _size;
        }
    }
}
