# include "opihi.h"

/* these functions are somewhat fragile: we cannot do multiple 
   CreateQueue / FindQueue operations in a row or the pointers 
   will get messed up
   do we need a 'delete queue' function?
*/

Queue *queues;   /* queue to store the list of all queues */
int   Nqueues;   /* number of currently available queues */

void InitQueues () {
  Nqueues = 0;
  ALLOCATE (queues, Queue, 1); 
}

/* list known queues */
void ListQueues () {

  int i;

  for (i = 0; i < Nqueues; i++) {
    fprintf (stderr, "%-15s %3d\n", queues[i].name, queues[i].Nlines);
  }
  return;
}

/* return the given queue */
Queue *FindQueue (char *name) {

  int i;

  for (i = 0; i < Nqueues; i++) {
    if (!strcmp (queues[i].name, name)) {
      return (&queues[i]);
    }
  }
  return (NULL);
}

/* make a new named queue */
Queue *CreateQueue (char *name) {

  Queue *queue;

  queue = FindQueue (name);
  if (queue != NULL) return (queue);

  Nqueues ++;
  REALLOCATE (queues, Queue, Nqueues);
  queue = &queues[Nqueues - 1];
  queue[0].Nlines = 0;
  queue[0].NLINES = 10;
  queue[0].name = strcreate (name);
  ALLOCATE (queue[0].lines, char *, queue[0].NLINES);
  return (queue);
}

void PushQueue (Queue *queue, char *line) {

  int N;

  N = queue[0].Nlines;
  queue[0].lines[N] = strcreate (line);
  queue[0].Nlines ++;
  if (queue[0].Nlines == queue[0].NLINES) {
    queue[0].NLINES += 10;
    REALLOCATE (queue[0].lines, char *, queue[0].NLINES);
  }    
  return;
}

char *PopQueue (Queue *queue) {

  int i;
  char *line;

  if (queue[0].Nlines == 0) return (NULL);
  line = queue[0].lines[0];

  for (i = 1; i < queue[0].Nlines; i++) {
    queue[0].lines[i-1] = queue[0].lines[i];
  }
  queue[0].Nlines --;

  if (queue[0].Nlines < queue[0].NLINES - 20) {
    queue[0].NLINES -= 20;
    queue[0].NLINES = MAX (queue[0].NLINES, 10);
    REALLOCATE (queue[0].lines, char *, queue[0].NLINES);
  }    
  return (line);
}

