/* File "queue.h"
 * Contains the interface for the queue adt.
 */

#ifndef _QUEUE_H
#define _QUEUE_H

#include "bool.h"
#include "apptcal.h"

/*The capacity of the queue. */
#define MAX_LENGTH 20


/* Each element of the queue represents an appointment that couldn't be printed 
 * in the table, because there were several in one time slot.  The queue will
 * thus contain two or more elements with the same footnote number (a group
 * of appointments from the same time slot), possibly followed by more groups 
 * of appointments.
 */

typedef struct elNode {
    int noteNum;		/*footnote number*/
    ApptNode *appt;		/*an appointment belonging to this footnote*/
} elementType;



/* Implementation: a "circular" array. */

/* The queue elements are stored from position head up to position tail
 * in the array (eg, position 1 up to position 4).  The front of the
 * queue is at position head; the rear at position tail.  If head and
 * tail are equal, there must be one element in the queue.  As elements
 * are added to and taken out of the queue, the head and tail positions
 * advance through the array (eg head could be at position 3 and tail at
 * position 7).  If the tail hits the end of the array, we "wrap around",
 * that is, the next entry is added at the beginning.  We can thus view
 * the array as circular.
 *     If tail is one position before head (eg tail is at 14 and head is
 * at 15), then either the queue is full, or it's empty -- the two
 * conditions look the same, but the variable size distinguishes them.
 */

typedef struct queueType {
    elementType elements[MAX_LENGTH];
    int head;
    int tail;
    int size;
} Queue;

/* InitQueue
 *----------------------------------------------------------------
 */
void
InitQueue(Queue *Q);

/* enqueue
 *----------------------------------------------------------------
 * Add element newElement to the end of the queue.  Return true
 * if successful, false otherwise.  (Failure occurs if the array
 * is already full.)
 */
boolean
enqueue(Queue *Q, elementType newElement);

/* dequeue
 *----------------------------------------------------------------
 * Remove the first element from the front of the queue and
 * return it.
 * Precondition: isEmpty must not be true.
 */
elementType
dequeue(Queue *Q);

/* isQueueEmpty
 *----------------------------------------------------------------
 * Return true iff the queue is empty.
 */
boolean
isQueueEmpty(Queue *Q);

/* isQueueFull
 *----------------------------------------------------------------
 * Return true iff the queue is full.
 */
boolean
isQueueFull(Queue *Q);

#endif
