/*
  
  Name: Owen Sullivan
  Date Submitted: 9/7/22
  Lab Section: 006
  Assignment Name: Lab 1: Linked List Based Stacks and Queues

*/

#ifndef LISTQUEUE_
#define LISTQUEUE_

// Add reference to List.h (which includes reference to Node.h) because sample test cases were missing these references
#include "List.h"

// This class represents a Queue implemented via Linked List
// Do not modify anything in the class interface
template <class T>
class ListQueue {

  private:
    List<T> queue;

  public:
    ListQueue();
    ~ListQueue();
    int size();
    bool empty();
    void enqueue(T);
    T dequeue();
    // Print the name and this ListQueue's size and values to stdout
    // This function is already implemented (no need to change it)
    void print(string name) {
      
      queue.print(name);
    
    }

}; // end of class interface (you may modify the code below)

// Implement all of the functions below

// Construct an empty ListQueue by initializing this ListQueue's instance variables
template <class T>
ListQueue<T>::ListQueue() {

  // Call the List constructor (of type T) and assign queue to it.
  
  queue = List<T>();

}

// Destroy all nodes in this ListQueue to prevent memory leaks
template <class T>
ListQueue<T>::~ListQueue() {

  // Remove each node procedurally from the end, checking
  // that the list is not empty before removing.
  
  while (!empty()) {

    dequeue();

  }

}

// Return the size of this ListQueue
template <class T>
int ListQueue<T>::size() {

  // Return the value of List<T>::size().
  
  return queue.size();

}

// Return true if this ListQueue is empty
// Otherwise, return false
template <class T>
bool ListQueue<T>::empty() {

  // Return the value of List<T>::empty().
  
  return queue.empty();

}

// Create a new node with value, and insert that new node
// into this ListQueue in its correct position
template <class T>
void ListQueue<T>::enqueue(T value) {

  // Pass the provided value to List<T>:insertEnd().
  
  queue.insertEnd(value);

}

// Dequeue an element from the queue.
// Note that here that means both removing it from the list
// AND returning the value
template <class T>
T ListQueue<T>::dequeue() {

  // Create a variable of type T to hold the first value in queue, then
  // call List<T>::removeStart() and return the stored value.
  
  T val = queue.getFirst();

  queue.removeStart();

  return val;

}

#endif