/* structures and functions to support a first-come, first-served 
 * scheduler
 * Created by Henry Walker, 27 September 2004
 * Last modified by Janet Davis, 24 September 2006
 */

#include <stdlib.h>

struct jobQueueNode {
  struct Event * job;
  struct jobQueueNode * next;
};

struct jobQueue {
  struct jobQueueNode * first;
  struct jobQueueNode * last;
};

/* variable declaration for active jobs currently available for execution */
struct jobQueue readyJobs;

/* returns true (1) if queue is empty and false (0) otherwise */
int jobQueueIsEmpty (void) {
  return (readyJobs.first == NULL);
}

/* initialize jobQueue to a null queue */
void initializeJobQueue (void){
  readyJobs.first = NULL;
  readyJobs.last  = NULL;
}

/* insert job into job queue */
void insertJob (struct Event * job) {
  struct jobQueueNode *newNode
      = (struct jobQueueNode *)malloc(sizeof(struct jobQueueNode));

  /* copy event data to newNode */
  newNode->job = job;

    /* insert node into queue list */
  newNode->next = NULL;
  if (readyJobs.first == NULL) {
    readyJobs.first = newNode;
    readyJobs.last  = newNode;
  } else {
    readyJobs.last->next  = newNode;
    readyJobs.last  = newNode;
  }
}

/* remove job at head of queue and return it */
struct Event * selectJob (void) {
  struct Event * job;
  struct jobQueueNode *temp;

  /* if no jobs are ready, return NULL */
  if (readyJobs.first == NULL)
    return NULL;
  
  /* next job is at front of queue */
  job = readyJobs.first->job;

  /* record node at front of queue, so it can be removed later */
  temp = readyJobs.first;
  
  /* remove first job from queue */
  readyJobs.first = readyJobs.first->next;

  /* check if queue is now empty */
  if (readyJobs.first == NULL) {
    readyJobs.last = NULL;
  }

  /* return old front of queue to memory pool */
  free(temp);

  return job;
}

