#include "queue.h"


void init_queue(Queue *q) {
/*      Allocate memory for our Queue  */
     q->tail = malloc(sizeof(*q->tail));
     q->head = malloc(sizeof(*q->head));

     q->tail->next = NULL;
     q->tail->value = -1;

     q->head->prev = NULL;
     q->head->value = -1;
     
     q->head->next = q->tail;
     q->tail->prev = q->head;

     q->size = 0;

     print_q(q);
}


void insert_q(Queue *q, int value) {
    if (q == NULL) {
       return;
    }
    q_node *prev;
    q_node *inserted = malloc(sizeof(*inserted));
    prev = q->tail->prev;
    prev->next = inserted;

    inserted->next = q->tail;
    inserted->prev = prev;
    inserted->value = value;

    q->tail->prev = inserted;

    q->size++;

}

void remove_q(Queue *q, int value) {
    if (q == NULL) {
        return;
    }
    q_node *iter = q->tail->prev;
    while (iter != NULL) {
        if (iter->value == value) { // Found the first instance of the value
            q_node *prev = iter->prev;
            
            prev->next = iter->next;
            iter->next->prev = prev;

            free(iter);
            
            q->size--;

            return;
            
        }
        iter = iter->prev;
    }

}

int next_in_q(Queue *q) {
    if (q == NULL) {
       return;
    }
    return q->head->next->value;
}

int is_empty_q(Queue *q) {
    if (q == NULL) {
       return;
    }
    return q->size;
}

int pop_next_in_q(Queue *q) {
    if (q == NULL) {
       return;
    }
    if (is_empty_q(q) > 0) {
        int value = next_in_q(q);
        q_node *removed = q->head->next;
        q_node *next = removed->next;

        q->head->next = next;
        next->prev = q->head;

        free(removed);
        q->size--;

        return value;
    }
    return -1;
}

    

void print_q(Queue *q) {
    if (q == NULL) {
       return;
    }
    q_node *iter = q->head;
    printf("Contents of Queue:\n");
    while (iter != NULL) {
        printf("Value: %x Pointer: %p\n", iter->value, iter);
        iter = iter->next;
    }
}

void view_q(Queue *q, int **contents) {
    if (q == NULL) {
       return;
    }

    *contents = malloc(q->size + 1);
    int *citer = *contents;
    q_node *iter = q->head->next;
    while (iter != NULL) {
        *citer = iter->value;
        iter = iter->next;
        citer++;
    }
    
    return ;
}

