import java.util.Iterator;

/**
   The ArrayVector class implements the Vector interface by means of an array.
 
   @author      Franck van Breugel
   @version     1.6    June 13, 2001
*/
public class ArrayVector implements Vector
{
    public static final int CAPACITY = 1000; // default capacity of array

    private int capacity;                    // maximum capacity of array
    private Object[] vector;                 // vector holds elements of vector
    private int size;                        // number of elements in vector
 
    /** Constructs a vector of default capacity. */
    public ArrayVector() 
    {
        this(CAPACITY);
    }

    /** 
       Constructs a vector of specified capacity. 
     
       @param capacity the capacity of the vector. 
    */
    public ArrayVector(int capacity) 
    {
        this.capacity = capacity;
        this.vector = new Object[capacity];
        this.size = 0;
    }
 
    public int size() 
    {
        return size;
    }

    public boolean isEmpty() 
    {
        return (size == 0);
    }

    public Iterator elements()
    {
        java.util.Vector collection = new java.util.Vector();
        for (int i = 0; i < size; i++)
	{
            /* collection contains vector[0], ..., vector[i - 1] */
	    collection.addElement(vector[i]);
        }
        return collection.iterator();
    }

    /**
       Throws a BoundaryViolationException if specified rank is invalid: 
       smaller than 0 or greater than or equal to the size of this 
       vector.
      
       @param rank The rank to be checked.
       @exception BoundaryViolationException if the specified rank is
       invalid.
    */
    private void checkRank(int rank) throws BoundaryViolationException 
    {
        if (rank < 0 || rank > size - 1) 
        {
            throw new BoundaryViolationException("Invalid rank.");
        }
    }

    public Object elemAtRank(int rank) throws BoundaryViolationException 
    {
        checkRank(rank);
        return vector[rank];
    }

    public Object replaceAtRank(int rank, Object element) throws BoundaryViolationException 
    {
        checkRank(rank);
        Object temp = vector[rank];
        vector[rank] = element;
        return temp;
    }

    public void insertAtRank(int rank, Object element) throws BoundaryViolationException
    {
        if (size == capacity) 
        {
            throw new VectorFullException("Vector overflow.");
        }
        if (rank != size) 
        {
            checkRank(rank);
        }
        for (int i = size - 1; i >= rank; i--) 
        {
            /* 
               vector[i + 1], ..., vector[size - 1] have been moved one
               position to the right in the array.
             */
            vector[i + 1] = vector[i];
        }
        vector[rank] = element;
        size++;
    }

    public Object removeAtRank(int rank) throws BoundaryViolationException 
    {
        checkRank(rank);
        Object temp = vector[rank];
        for (int i = rank + 1; i <= size - 1; i++) 
        {
            /* 
               vector[rank + 1], ..., vector[i - 1] have been moved one
               position to the left in the array.
             */
            vector[i - 1] = vector[i];
        }
        size--;
        return temp;
    }

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