// Arup Guha
// 10/10/2023
// Code for COP 3502 Exam 1 A Section 1 Question 2

#include <stdio.h>

#define MAX 10

typedef struct queue {
    int items[MAX];
    int front;
    int cursize;
} queue;

int full(queue* q) {
    return q->cursize == MAX;
}

int empty(queue* q) {
    return q->cursize == 0;
}

void init(queue* q) {
    for (int i=0; i<MAX; i++) q->items[i] = 0;
    q->front = 0;
    q->cursize = 0;
}

int enqueue(queue* q, int value) {
    if (full(q)) return 0;
    q->items[(q->front+q->cursize)%MAX] = value;
    q->cursize++;
    return 1;
}

// Dequeues the front item in the queue (if it exists) storing it in the variable pointed to by retval and returns 1.
// Returns 0 if the queue is empty.
int dequeue(queue* q, int* retval) {

    // Get this out of the way.
    if (empty(q)) return 0;

    // Store the front value in the correct place.
    *retval = q->items[q->front];

    // Update the front and size.
    q->front = (q->front+1)%MAX;
    q->cursize--;

    // Signal success.
    return 1;
}

// A little test...
int main() {

    queue mine;
    init(&mine);
    int tmp;

    // Just did some random stuff for testing...
    for (int i=0; i<40; i++) {

        if (i%3 != 2) {

            int res = dequeue(&mine, &tmp);

            if (res) printf("dequeued %d\n", tmp);
            else printf("dequeue failed\n");
        }
        else {
            int res = enqueue(&mine, i);
            if (res) printf("enqueued %d\n", i);
            else printf("enqueue failed\n");
        }
    }

    while (!empty((&mine))) dequeue(&mine, &tmp);

    return 0;

}
