/*
  
  Name: Owen Sullivan
  Date Submitted: 9/7/22
  Lab Section: 006
  Assignment Name: Lab 1: Linked List Based Stacks and Queues

*/

#ifndef LISTSTACK_
#define LISTSTACK_

// 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 Stack implemented via Linked List
// Do not modify anything in the class interface
template <class T>
class ListStack {

  private:
    List<T> stack;

  public:
    ListStack();
    ~ListStack();
    int size();
    bool empty();
    void push(T);
    T pop();
    // Print the name and this ListStack's size and values to stdout
    // This function is already implemented (no need to change it)
    void print(string name) {
      
      stack.print(name);
    
    }

}; // end of class interface (you may modify the code below)

// Implement all of the functions below

// Construct an empty ListStack by initializing this ListStack's instance variables
template <class T>
ListStack<T>::ListStack() {

  // Call the List constructor (of type T) and assign stack to it.
  
  stack = List<T>();

}

// Destroy all nodes in this ListStack to prevent memory leaks
template <class T>
ListStack<T>::~ListStack() {

  // Remove each node procedurally from the end, checking
  // that the list is not empty before removing.
  
  while (!empty()) {

    pop();

  }

}

// Return the size of this ListStack
template <class T>
int ListStack<T>::size() {

  // Return the value of List<T>::size().
  
  return stack.size();

}

// Return true if this ListStack is empty
// Otherwise, return false
template <class T>
bool ListStack<T>::empty() {

  // Return the value of List<T>::empty().
  
  return stack.empty();

}

// Create a node with value <value> and push it onto the stack
template <class T>
void ListStack<T>::push(T value) {

  // Pass the provided value to List<T>:insertStart().
  
  stack.insertStart(value);

}

// Pop a node from the Stack.
// Note that here that includes both removing the node from the stack
// AND returning its value.
template <class T>
T ListStack<T>::pop() {

  // Create a variable of type T to hold the first value in stack, then
  // call List<T>::removeStart() and return the stored value.
  
  T val = stack.getFirst();

  stack.removeStart();
  
  return val;

}

#endif