// carqueue.cc: the queue of waiting cars for the CSC 270 simulation example
// -- J. Clarke, March-June 1996

#include <stdlib.h>
#include <iostream.h>
#include "event.h"
#include "evlist.h"
#include "car.h"
#include "carqueue.h"
#include "stats.h"
#include "pump.h"
#include "pstand.h"
#include "globals.h"

carQueueClass::carQueueClass (void)
{
	firstWaitingCar = NULL;
	lastWaitingCar = NULL;
	localQueueSize = 0;
	totalEmptyQueueTime = 0.0;
}

int carQueueClass::queueSize (void)
{
	return localQueueSize;
}

double carQueueClass::emptyTime (void)
{
	if (localQueueSize > 0)
		return totalEmptyQueueTime;
	else
		return totalEmptyQueueTime + simulationTime;
}

void carQueueClass::insert (carClass * newestCar)
{
	queueItem * newQueueItem;
	newQueueItem = new queueItem;
	newQueueItem -> data = newestCar;
	newQueueItem -> next = NULL;

	if (lastWaitingCar == NULL) {
		// assert queueSize = 0
		firstWaitingCar = newQueueItem;
		totalEmptyQueueTime += simulationTime;
	}
	else {
		// assert queueSize > 0
		lastWaitingCar -> next = newQueueItem;
	}

	lastWaitingCar = newQueueItem;
	localQueueSize += 1;
}

carClass * carQueueClass::getNext (void)
{
	// pre queueSize > 0 and firstWaitingCar not= NULL

	if (firstWaitingCar == NULL) {
		cout << "Error! car queue unexpectedly empty\n";
		return NULL;
	}

	carClass * carToReturn = firstWaitingCar -> data;

	localQueueSize -= 1;
	queueItem * restOfList = firstWaitingCar -> next;
	delete firstWaitingCar;
	firstWaitingCar = restOfList;

	if (firstWaitingCar == NULL) {
		// empty queue: update the pointer to the end of queue too!
		lastWaitingCar = NULL;
		totalEmptyQueueTime -= simulationTime;
	}

	return carToReturn;
}
