// Simulates the flow of customers through a line in a store.

#include <iostream>
#include <cstdlib> // for function rand()
#include <iomanip> // for setprecision manipulator

using namespace std;

template < class DT > // Forward declaration of the Queue class
class Queue;
template < class DT > // Facilitator class for the Queue class
class QueueNode
{
private:
    // Constructor
    QueueNode ( const DT &nodeData, QueueNode *nextPtr );
    // Data members
    DT dataItem;
    QueueNode *next;
    friend class Queue<DT>;
};
template < class DT >
class Queue
{
public:
    // Constructor
    Queue ();
    // Destructor
    ~Queue ();
    // Queue manipulation operations
    void enqueue ( const DT &newData ); // Enqueue data item
    DT dequeue (); // Dequeue data data item
    // Queue status operations
    bool isEmpty () const;  // Queue is empty
    int getLength () const; // Length of queue
private:
    // Data members
    QueueNode<DT> *front,   // Pointer to the front node
    *rear;    // Pointer to the rear node
};

//
// Input your code here !!!
//
template<class DT>
Queue<DT>::Queue() {
  front = 0;
  rear = 0;
}

template<class DT>
Queue<DT>::~Queue() {
  while (!isEmpty()){
    dequeue();
  }
}

template<class DT>
void Queue<DT>::enqueue ( const DT &newData ){
  if(isEmpty()){
    front = new QueueNode <DT>;
    rear = front;
    rear->next=0;
    rear->dataItem = newData;
  }
  rear->next= new QueueNode <DT> (newData, NULL);
  rear = rear -> next;
}

template<class DT>
DT Queue<DT>::dequeue() {
  if (isEmpty()) return 0;
  else {
  QueueNode <DT> *temp = front;
  DT res = temp -> dataItem;
  delete front;
  front = temp -> next;
  return res;
  }
}

template<class DT>
bool Queue<DT>::isEmpty() const {
  return front == 0;
}

template<class DT>
int Queue<DT>::getLength () const{
  int length = 0;
  if (!isEmpty()){
    for (QueueNode<DT> *temp = front; temp != rear; temp = temp->next ){
      length++;
    }
  }
  return length;
}

template<class DT>
QueueNode<DT>::QueueNode(const DT &nodeData, QueueNode *nextPtr ) {
  dataItem =nodeData;
  next = nextPtr;
}









int main ()
{
    Queue<int> custQ;      // Line (queue) of customers containing the
    //   time that each customer arrived and joined the line
    int simLength,     // Length of simulation (minutes)
    minute,            // Current minute
    numCust,           // Number of customers arrived
    timeArrived,       // Time dequeued customer arrived
    waitTime,          // How long dequeued customer waited
    totalServed = 0,   // Total customers served
    totalWait   = 0,   // Total waiting time
    maxWait     = 0,   // Longest wait
    numArrivals = 0;   // Number of new arrivals
    
    cout << endl << "Enter the length of time to run the simulator : ";
    cin >> simLength;
    
    for ( minute = 0 ; minute < simLength ; minute++ )
    {
        // Dequeue the first customer in line (if any). Increment
        // totalServed, add the time that this customer waited to
        // totalWait, and update maxWait if this customer waited
        // longer than any previous customer.
        // Determine the number of new customers and add them to
        // the line.
        
        //
        // Input your code here !!!
        //

        
    }
    
    cout << endl;
    cout << "Customers served : " << totalServed << endl;
    cout << "Average wait     : " << setprecision(2)
         << double(totalWait) / totalServed << endl;
    cout << "Longest wait     : " << maxWait << endl;
}
