/**
 * The DequeStack class implements the Stack interface by means of
 * a Deque.
 *
 * @version     1.3    June 7, 2001
 * @author      Franck van Breugel
 * @see Deque
 * @see Stack
 */
public class DequeStack implements Stack 
{
    private Deque deque; // deque contains the elements of this stack

    /**
     * Constructs an empty stack representation by emptying the specified deque.
     * @param deque The deque used to implement this stack.
     */
    public DequeStack(Deque deque) 
    {
        while (!deque.isEmpty()) 
        {
            deque.removeLast();
        }
        this.deque = deque;
    }

    /** 
     * Returns the size of this stack. 
     * @return The size of this stack.
     */
    public int size() 
    {
        return deque.size();
    }

    /** 
     * Tests if this stack is empty. 
     * @return true if this stack is empty, false otherwise.
     */
    public boolean isEmpty()  
    {
        return deque.isEmpty();
    }

    /** 
     * Returns the element at the top of this stack.
     * Throws a StackEmptyException if this stack is empty. 
     * @return The element at the top of this stack.
     * @exception StackEmptyException if this stack is empty. 
     */
    public Object top() throws StackEmptyException 
    {
        try 
        {
            return deque.last(); // last throws DequeEmptyException if deque is empty 
        } 
        catch (DequeEmptyException e) 
        {
            throw new StackEmptyException("Stack is empty.");
        }
    }

    /** 
     * Adds the specified element onto the top of this stack. 
     * @param element the element to be added to this stack.
     **/
    public void push(Object element) 
    {
        deque.insertLast(element);
    }

    /** 
     * Removes the element at the top of this stack and returns that element.
     * Throws a StackEmptyException if this stack is empty. 
     * @return The element at the top of this stack.
     * @exception StackEmptyException if this stack is empty. 
     */
    public Object pop() throws StackEmptyException 
    {
        try 
        {
            return deque.removeLast(); // removeLast throws DequeEmptyException if deque is empty
        } 
        catch (DequeEmptyException e) 
        {
            throw new StackEmptyException("Stack is empty.");
        }
    }

    /**
     * Returns a string representation of this stack.
     * @return A string representation of this stack.
     */
    public String toString() 
    {
        return deque.toString();
    }

}
