import java.util.*;

/**
 * Stack.java
 * @author Eric Alexander
 *
 * This class is an implementation of a stack using a linked list.
 * Used for CS 367 - Data Structures.
 * UW-Madison, Summer 2011
 *
 * @param <E>	the intended data type for storing in the stack
 */
public class Stack<E> {
	// Instance variables
	private ListNode<E> head;
	private int numItems;
	
	/**
	 * Constructor creates an empty stack.
	 */
	public Stack() {
		numItems = 0;
		head = null;
	}
	
	/**
	 * Pushes a given item to the top of the stack.
	 * @param item	the new element at the top of the stack.
	 */
	public void push(E item) {
		head = new ListNode<E>(item, head);
		numItems++;
	}
	
	/**
	 * Pops the top element off of the stack, removing and returning it.
	 * @return	the top element of the stack
	 * @throws	EmptyStackException if stack is empty
	 */
	public E pop() {
		if (numItems == 0) {
			throw new EmptyStackException();
		}
		
		ListNode<E> temp = head;
		head = head.getNext();
		numItems--;
		return temp.getData();
	}
	
	/**
	 * Returns the top element of the stack without removing it.
	 * @return	the top element of the stack
	 * @throws	EmptyStackException if stack is empty
	 */
	public E peek() {
		if (numItems == 0) {
			throw new EmptyStackException();
		}
		
		return head.getData();
	}
	
	/**
	 * Gives the number of elements in the stack
	 * @return	size of the stack
	 */
	public int size() {
		return numItems;
	}
	
	/**
	 * Returns if the stack is empty or not.
	 * @return	true if stack is empty, else false
	 */
	public boolean isEmpty() {
		return (numItems == 0);
	}
}
