/* Version 0.0
** From "Wayne's Little DSA Library" (DSA == Data Structures and
** Algorithms) Feel free to change, modify, or burn these sources, but if
** you modify them please don't distribute your changes without a clear
** indication that you've done so.  If you think your change is spiffy,
** send it to me and maybe I'll include it in the next release.
**
** Wayne Hayes, wayne@csri.utoronto.ca (preffered), or wayne@csri.toronto.edu
*/

#include "misc.h"
#include "queue.h"
#include <stdlib.h>

QUEUE *QueueAlloc(int maxSize)
{
    QUEUE *q = Malloc(sizeof(QUEUE));
    q->queue = Malloc(sizeof(foint) * maxSize);
    q->maxSize = maxSize;
    q->front = q->length = 0;
    return q;
}

void QueueFree(QUEUE *q)
{
    free(q->queue);
    free(q);
}

int QueueSize(QUEUE *q)
{
    return q->length;
}

foint QueueFront(QUEUE *q)
{
    if(q->length == 0)
	return ABSTRACT_ERROR;
    else
	return q->queue[q->front];
}

foint QueueGet(QUEUE *q)
{
    if(q->length == 0)
	return ABSTRACT_ERROR;
    else
    {
	foint front = q->queue[q->front];
	q->front = (q->front + 1) % q->maxSize;
	q->length--;
	return front;
    }
}

foint QueuePut(QUEUE *q, foint new)
{
    if(q->length == q->maxSize) /* grow the array */
    {
	int oldSize = q->maxSize, i;
	q->maxSize *= 2;
	q->queue = Realloc(q->queue, sizeof(foint) * q->maxSize);

	/* move old stuff into proper place in the new array.  Note the
	** new one can't wrap around since it's only half full now.
	*/
	for(i=0; i < q->front; i++)
	    q->queue[oldSize + i] = q->queue[i];
    }
    q->queue[(q->front + q->length) % q->maxSize] = new;
    q->length++;
    return new;
}

foint QueueBelowTop(QUEUE *q, int n)
{
    if(n > q->length)
	return ABSTRACT_ERROR;
    else
	return q->queue[(q->front + n) % q->maxSize];
}
