#include "includes.h"

tdQueue* queue_create() {
    tdQueue* queue = (tdQueue*)malloc(sizeof(tdQueue));
    queue->data = NULL;
    queue->size = 0;
    queue->capacity = 0;
    return queue;
}

void queue_decontruct(tdQueue* queue)
{
    int i = 0;
    while ((i < queue->size) && (queue->data[i] != NULL)) {
        deconstruct_matrix2d(queue->data[i]); 
        i++;
    }
    free(queue);
}

bool queue_is_empty(tdQueue* queue)
{
    return queue->size == 0;
}

int queue_size(tdQueue* queue)
{
    return queue->size;
}

void queue_enqueue(tdQueue* queue, matrix2d* data)
{
    if (queue->capacity == queue->size) {
        if (queue->capacity) {
            queue->capacity = ceil(queue->capacity*sqrt(2));
            queue->data = (matrix2d**)realloc(queue->data, sizeof(matrix2d*)*(queue->capacity));
        } else {
            queue->capacity = ceil(sqrt(2));
            queue->data = (matrix2d**)malloc(sizeof(matrix2d*)*(queue->capacity));
        }
    }
    queue->data[queue->size++] = data;
}

matrix2d* queue_dequeue(tdQueue* queue)
{
    if (queue->data == NULL) return NULL;
    matrix2d* data = queue->data[0];
    for (int i = 1; i < queue->size; i++) {
        queue->data[i-1] = queue->data[i];
    }
    queue->size -= 1;
    return data;
}

matrix2d* queue_peek(tdQueue* queue)
{
    if (queue->data == NULL) return NULL;
    matrix2d* data = queue->data[0];
    return data;
}

void queue_clear(tdQueue* queue)
{
    int i = 0;
    while (i < queue->capacity && queue->data[i] != NULL)
        deconstruct_matrix2d((matrix2d*) (queue->data)[i++]);
    queue->size = 0;    
}
