#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

// Type for vector, change to the desired type to be used in the vector
#define VECTOR_TYPE int

typedef struct vector {
    size_t length;
    VECTOR_TYPE* arr;
    size_t start;
    size_t size;
} vector_t;

inline static size_t vector_end(vector_t* self) {
    return (self->start + self->size) % self->length;
}

vector_t vector_init(size_t length) {
    vector_t self;
    self.length = length;
    self.arr = malloc(length * sizeof(VECTOR_TYPE));
    self.start = 0;
    self.size = 0;
    return self;
}

bool vector_add(vector_t* self, VECTOR_TYPE element, bool to_end) {
    if (self->size == self->length) {
        return false;
    }
    if (to_end) {
        self->arr[vector_end(self)] = element;
    } else {
        if (self->size == 0) {
            self->arr[self->start] = element;
        } else {
            self->arr[self->start - 1] = element;
            self->start--;
        }
    }
    self->size++;
    return true;
}

bool vector_remove(vector_t* self, VECTOR_TYPE* destination, bool from_end) {
    if (self->size == 0) {
        return false;
    }

    *destination = self->arr[!from_end ? vector_end(self) : self->start];
    self->start = from_end ? (self->start + 1) % self->length : self->start;
    self->size--;
    return true;
}

void vector_destroy(vector_t* self) {
    if (self->arr != NULL) {
        free(self->arr);
        self->arr = NULL;
    }
}
