/**
   The ArrayStack class implements the Stack interface by means of an array.

   @author      Franck van Breugel
   @version     1.3    June 13, 2001
*/
public class ArrayStack implements Stack 
{

    public static final int CAPACITY = 1000; // default capacity of stack

    private int capacity;                    // maximum capacity of stack
    private Object[] stack;                  // stack holds elements of stack
    private int top;                         // top element of stack
 
    /** 
       Constructs a stack of default capacity. 
    */
    public ArrayStack() 
    {
        this(CAPACITY);
    }

    /** 
       Constructs a stack of specified capacity. 
     
       @param capacity the capacity of the stack. 
    */
    public ArrayStack(int capacity) 
    {
        this.capacity = capacity;
        this.stack = new Object[capacity];
        this.top = -1;
    }
 
    public int size() 
    {
        return (top + 1);
    }

    public boolean isEmpty() 
    {
        return (top < 0);
    }

    public Object top() throws StackEmptyException 
    {
        if (isEmpty()) 
        {
            throw new StackEmptyException("Stack is empty.");
        }
        return stack[top];
    }

    public void push(Object element) 
    {
        if (size() == capacity) 
        {
            throw new StackFullException("Stack overflow.");
        }
        stack[++top] = element; // increment top and update stack[top]
    }

    public Object pop() throws StackEmptyException 
    {
        if (isEmpty()) 
        {
            throw new StackEmptyException("Stack is empty.");
        }
        Object element = stack[top];
        stack[top--] = null; // dereference stack[top] and decrement top
        return element;
    }    

    /**
     * Returns a string representation of this stack.
     *
     * @return A string representation of this stack.
     */
    public String toString() 
    {
        String rep = "";
        for (int i = 0; i <= top; i++) 
        {
        /* rep = stack[0].toString() + "\n" + ... + stack[i-1].toString() + "\n" */
            rep += stack[i].toString();
            rep += "\n";
        }
        return rep;
    }
}
