// ..
//  Copyright (c) 1996-1998 University Freiburg, Computer Science Departement
// 
//  Project:  HsfLight - Heuristic Search Framework Light
//             
//  See file README for information on using and copying this software.
// 
//  Module:   /home/edelkamp/cdot/alg/hsfLight/include/Queue.h
//  Author:   Stefan Edelkamp
//  eMail:    edelkamp@informatik.uni-freiburg.de 
//  WWW:      http://www.informatik.uni-freiburg.de/edelkamp/~hsfLight
// ..

#ifndef QUEUE_H
#define QUEUE_H

#include <iostream.h>
#include <stdlib.h>

typedef enum {enque, deque} Q_opType;

template<class T>
class Queue {
private:
  int head, tail, size;
  Q_opType lastOp;
  T* element; 
 
public: 
  Queue(int sz): size(sz), head(0), tail(size-1), lastOp(deque) { 
    int i;
    element = new T[sz]; 
    for(i=0;i<sz;i++) element[i] = 0; }
  ~Queue() { delete [] element; }
  makeEmpty() { head = 0; tail = size-1; lastOp = deque; }
  empty() { return (head == (tail+ 1) % size); }
  enqueue(const T& elem) {
    if ((head == (tail+1) % size) && (lastOp == enque)) { 
      cout << "Queue full \n"; exit(1); } 
    lastOp = enque;
    tail = (tail + 1) % size;
    element[tail] = elem;  }

  T get_head() { return element[head];  }
  T get_tail() { return element[tail];  }
  T dequeue() {
    if ((head == (tail+1) % size) && (lastOp == enque)) 
      { cout << "Queue empty \n"; exit(1); } 
    T temp = element[head];
    lastOp = deque;
    head = (head + 1) % size;
    return temp;  }

  print() const { 
    int x=head;
    cout << "\nh:" << head << " t:" << tail << " ";
    while (x % size != (tail+1) % size) { 
      cout << element[(x % size)] << " "; x++; }
    cout << "\n"; }
  
  friend ostream& operator<<(ostream& os, const Queue& m) { m.print(); }
};

#endif //
