#include <stdio.h>
#define SIZE 10

typedef struct
{
	int front;
	int rear;
	int arr[SIZE];
} que;

void init_queue(que *queue);		//a function to initialize the queue (set front and rear to -1)
int is_full(que *queue);			//check if the queue is full
int is_empty(que *queue);			//check if the queue is empty
int queue_first(que *queue);		//check queue's first element
int queue_last(que *queue);			//check queue's last element
int enqueue(que *queue, int val);	//enqueue val into the queue
int dequeue(que *queue);			//dequeue queue's last element
int queue_size(que *queue);			//return the queue's size
void print_queue(que *queue);		//print the queue's elements

int main(void)
{
    que queue;
    init_queue(&queue);
    enqueue(&queue, 5);
    enqueue(&queue, 12);
    enqueue(&queue, 21);
    print_queue(&queue);
    dequeue(&queue);
	print_queue(&queue);
    enqueue(&queue, 9);
    print_queue(&queue);
    enqueue(&queue, 10);
    enqueue(&queue, 11);
	dequeue(&queue);
    dequeue(&queue);
    enqueue(&queue, 13);
    enqueue(&queue, 14);
    printf("%d\n", queue_size(&queue));
    print_queue(&queue);
    printf("First: %d\n",queue_first(&queue));
    printf("Last: %d\n",queue_last(&queue));
    enqueue(&queue, 15);
    enqueue(&queue, 16);
    print_queue(&queue);
    printf("%d\n", queue_size(&queue));
    enqueue(&queue, 9);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    dequeue(&queue);
    print_queue(&queue);
    dequeue(&queue);
    
    return 0;
}


void init_queue(que *queue)
{
	queue->front = queue->rear = -1;
}

int is_full(que *queue)
{
	if (queue->rear == SIZE-1)
	{
		printf("Queue is full!\n");
		return 1;
	}
	else return 0;
}

int is_empty(que *queue)
{
	if (queue->front == queue->rear)
	{
		printf("Queue is empty!\n");
		return 1;
	}
	else return 0;
}

int queue_first(que *queue)
{
	if (is_empty(queue))
	{
		printf("Queue is empty!\n");
		return -1;
	}
	return queue->arr[queue->front+1];
}

int queue_last(que *queue)
{
	if (is_empty(queue))
	{
		printf("Queue is empty!\n");
		return -1;
	}
	return queue->arr[queue->rear];
}

int enqueue(que *queue, int val)
{
	if (is_full(queue))
	{
		printf("I cannot enqueue!\n");
		return -1;
	}
	
	queue->arr[queue->rear+1]=val;
	queue->rear++;
	return 1;
}

int dequeue(que *queue)
{
	if (is_empty(queue))
	{
		printf("I cannot dequeue!\n");
		return -1;
	}
	(queue->front)++;
	return queue->arr[queue->front];
}

int queue_size(que *queue)
{
	return queue->rear - queue->front;
}

void print_queue(que *queue)
{
	int i;
	if (is_empty(queue))
		printf("Queue is Empty!\n");

	for (i=(queue->front)+1; i<=(queue->rear); i++)
		printf("%d\t",queue->arr[i]);
	printf("\n");
}
