/* Copyright (C) 1998 H. Conrad Cunningham.  All rights reserved.  */

package SoftwareInterfaces;

import java.util.*;

/**
 * A class that adapts the <code>java.util.Vector</code> class to implement 
 * the ranked sequence abstract data type.
 * 
 * @author H. Conrad Cunningham
 * @version 1 June 1998
 */

public class VectorRankedSeq implements RankedSequence
{
    /**
     * Constructs an empty sequence (with the default initial capacity and 
     * incrementing policy).
     *
     * @throws AssertionViolation (e.g., if precondition not satisfied)
     * <dt><b>Postcondition:</b> 
     * <dd> constructs an empty sequence with initial capacity
     *     <code>DEFAULT_INITIAL_CAPACITY</code> and an incrementing policy
     *      such that the size is doubled on each expansion
     */
    public VectorRankedSeq() throws AssertionViolation
    {   theSeq = new Vector(); }



    /**
     * Constructs an empty sequence with the given initial capacity (and 
     * default incrementing policy).
     *
     * @param initialCapacity the number of (empty) slots in the sequence 
     *      initially 
     * <dt><b>Preconditon:</b> 
     * <dd><code>initialCapacity >= 0</code>
     *
     * @throws AssertionViolation (e.g., if precondition not satisfied)
     * <dt><b>Postcondition:</b> 
     * <dd>constructs an empty sequence with initial capacity
     *     <code>initialCapacity</code> and an incrementing policy such that 
     *     the size is doubled on each expansion
     */
    public VectorRankedSeq(int initialCapacity) throws AssertionViolation
    {  Assert.pre(initialCapacity >= 0);
       theSeq = new Vector(initialCapacity); 
    }


    /**
     * Constructs an empty sequence with the given initial capacity and 
     * increment.
     *
     * @param initialCapacity the number of (empty) slots in the sequence 
     *      initially 
     * @param capacityIncrement capacityIncrement if positive, the number of 
     *     slots to add when the capacity needs to be increased; if zero, 
     *     double the capacity.
     * <dt><b>Preconditon:</b> 
     * <dd><code>initialCapacity >= 0 && capacityIncrement >= 0</code>
     * 
     * @throws AssertionViolation (e.g., if precondition not satisfied)
     * <dt><b>Postcondition:</b> 
     * <dd>constructs an empty sequence with initial capacity
     *     <code>initialCapacity</code> and capacity increment 
     *     <code>capacityIncrement</code>
     */
    public VectorRankedSeq(int initialCapacity, int capacityIncrement)
        throws AssertionViolation
    {   Assert.pre(initialCapacity >= 0 && capacityIncrement >= 0);
        theSeq = new Vector(initialCapacity, capacityIncrement);
    }


    /**
     * Insert a new element at the given rank into the sequence.
     *
     * @param r the rank at which to insert the object
     * @param e the object to be inserted
     * <dt><b>Preconditon:</b> 
     * <dd><code>0 <= r <= length()</code>
     * 
     * @throws AssertionViolation (e.g., if precondition not satisfied)
     * <dt><b>Postcondition:</b> 
     * <dd>object <code>e</code> added as element at rank <code>r</code>.
     *     Ranks of all elements (if any) with old ranks >= <code>r</code>
     *     are increased by one.
     */
    public void insertAtRank(int r, Object e) throws AssertionViolation
    {   Assert.pre(0 <= r && r <= theSeq.size());
        theSeq.insertElementAt(e,r);  // java 1.1 or 1.2
    //  theSeq.add(r,e);              // java 1.2
    }
        
 
    /**
     * Delete the element at the given rank from the sequence.
     *
     * @param r the rank at which to delete the object
     * <dt><b>Preconditon:</b> 
     * <dd> <code> 0 <= r < length() </code>
     *
     * @throws AssertionViolation (e.g., if precondition not satisfied)
     * <dt><b>Postcondition:</b> 
     * <dd>element at rank <code>r</code> is removed.
     *     Ranks of all elements (if any) with old ranks > <code>r</code>
     *     are decreased by one.
     */
    public void deleteAtRank(int r) throws AssertionViolation
    {   Assert.pre(0 <= r && r < theSeq.size());  // thus the element exists
        theSeq.removeElementAt(r);        // java 1.1 or 1.2
    //  Object junk = theSeq.remove(r);   // java 1.2
    }
	      

    /**
     * Replace the element at the given rank in the sequence.
     *
     * @param r the rank at which to replace the object
     * @param e the replacement object
     * <dt><b>Preconditon:</b> 
     * <dd><code>0 <= r < length()</code>
     *
     * @throws AssertionViolation (e.g., if precondition not satisfied)
     * <dt><b>Postcondition:</b> 
     * <dd>element at rank <code>r</code> is replaced by object <code>e</code>.
     */
    public void replaceAtRank(int r, Object e) throws AssertionViolation
    {   Assert.pre(0 <= r && r < theSeq.size());  // thus the element exists
        theSeq.setElementAt(e,r);        // java 1.1 or 1.2
    //  Object junk = theSeq.set(r,e);   // java 1.2
    }


    /**
     * Retrieve the element at the given rank from the sequence.
     *
     * @param r the rank whose value is to be returned
     * <dt><b>Preconditon:</b> 
     * <dd><code>0 <= r < length()</code>
     *
     * @return the element at rank <code>r</code>
     * @throws AssertionViolation (e.g., if precondition not satisfied)
     *     
     */
    public Object elementAtRank(int r) throws AssertionViolation
    {   Assert.pre(0 <= r && r < theSeq.size()); // thus the element exists
        return theSeq.elementAt(r);  // java 1.1 or 1.2
    //  return theSeq.get(r);        // java 1.2
    }


    /**
     * Determine the length of (i.e., number of elements in) the sequence.
     *
     * @return the number of elements in the sequence.
     */
    public int length()
    {   return theSeq.size(); }


    /**
     * Determine whether the sequence is empty.
     *
     * @return true if the sequence contains no elements;
     *     otherwise false.
     */
    public boolean isEmpty()
    {   return theSeq.isEmpty(); }


    /**
     * Construct an enumeration iterator for the sequence.
     *
     * @return an enumeration iterator for the sequence
     */
    public java.util.Enumeration elements()
    {   return theSeq.elements(); }


    /**
     * Release the unused capacity of the sequence.
     *
     * @throws AssertionViolation (e.g., if precondition not satisfied)
     * <dt><b>Postcondition:</b> 
     * <dd>frees any unused capacity, making the capacity equal to the
     *     sequence length.
     */
    public void trimToLength() throws AssertionViolation
    {   theSeq.trimToSize(); }


    /**
     * Enables debugging option.
     *
     * <dt><b>Postcondition:</b> 
     * <dd>internal debugging option turned on
     */
    public void enableDebug()
    {  debugOn = true; }


    /**
     * Disables debugging option.
     *
     * <dt><b>Postcondition:</b> 
     * <dd>internal debugging option turned off
     */
    public void disableDebug()
    {   debugOn = false; }


    /**
     * Debugging method that displays internal information from the instance
     * on the standard output.
     */
    public void DEBUG_showSequence(String msg)
    {   System.out.println("***  BEGIN sequence display:  " + msg);
        System.out.println("Length = " + theSeq.size() + ",  " +
			   "Capacity = " + theSeq.capacity());
	for (int i = 0; i < theSeq.size(); i++)
        {   System.out.println(i + "\t" + theSeq.elementAt(i)); } // 1.1 or .2
    //  {   System.out.println(i + "\t" + theSeq.get(i)); }  // java 1.2
        System.out.println("***  END sequence display:  " + msg);
    }

    /* Invariant:  (for 0 <= r < theSeq.size(), 
                       theSeq.get(r) == element at rank r of the sequence)
    */

    private Vector theSeq;     // the Vector to store the sequence
    private boolean debugOn;  // debugging option
}
