//- Copyright (c) 2008-2020 James Grenning --- All rights reserved
//- For exclusive use by participants in Wingman Software training courses.
//- Cannot be used by attendees to train others without written permission.
//- www.wingman-sw.com james@wingman-sw.com

#include "CircularBuffer.h"
#include <memory.h>

struct CircularBuffer
{
    int head;
    int tail;
    int count;
    size_t capacity;
    int * values;
};

struct CircularBuffer * CircularBuffer_Create(size_t size)
{
    struct CircularBuffer * self = (struct CircularBuffer *)calloc(1, sizeof(struct CircularBuffer));
    self->values = (int *)calloc(size, sizeof(int));
    self->capacity = size;
    return self;
}

void CircularBuffer_Destroy(struct CircularBuffer * self)
{
    free(self->values);
    free(self);
}

bool CircularBuffer_IsEmpty(struct CircularBuffer * self)
{
    return (self->count == 0);
}

bool CircularBuffer_IsFull(struct CircularBuffer * self)
{
    return (self->count == self->capacity);
}

bool CircularBuffer_Put(struct CircularBuffer * self, int value)
{
    if (self->count == self->capacity)
        return false;
        
    self->values[self->head] = value;
    self->count++;
    self->head++;
    if (self->count >= self->capacity)
        self->head = 0;
    
    return true;
}

int CircularBuffer_Get(struct CircularBuffer * self)
{
    int value = self->values[self->tail];
    self->count--;
    self->tail++;
    return value;
}

size_t CircularBuffer_Capacity(struct CircularBuffer * self)
{
    return self->capacity;
}



