// Copyright(c) 1996,1997 ObjectSpace, Inc.
// Portions Copyright(c) 1995, 1996 Hewlett-Packard Company.

package COM.objectspace.jgl;

import java.util.Enumeration;
import java.util.Vector;

/**
 * VectorArray allows a java.util.Vector to be accessed like a Container.
 * It is particularly useful for applying generic algorithms like Sorting.sort()
 * to a java.util.Vector.
 * <p>
 * @version 2.0.2
 * @author ObjectSpace, Inc.
 */

public class VectorArray extends ArrayAdapter
  {
  java.util.Vector myVector;

  public VectorArray()
    {
    myVector = new java.util.Vector();
    }

  public VectorArray( java.util.Vector vector )
    {
    synchronized( vector )
      {
      myVector = vector;
      }
    }

  public VectorArray( VectorArray vector )
    {
    synchronized( vector )
      {
      myVector = vector.myVector;
      }
    }

  /**
   * Return a shallow copy of myself.
   */
  public synchronized Object clone()
    {
    return new VectorArray( this );
    }

  /**
   * Return a string that describes me.
   */
  public synchronized String toString()
    {
    return myVector.toString();
    }

  /**
   * Return true if I'm equal to a specified object.
   * @param object The object to compare myself against.
   * @return true if I'm equal to the specified object.
   */
  public boolean equals( Object object )
    {
    return myVector.equals( ((VectorArray) object).myVector );
    }

  /**
   * Return the number of objects that I contain.
   */
  public int size()
    {
    return myVector.size();
    }

  /**
   * Return the maximum number of objects that I can contain.
   */
  public int maxSize()
    {
    return Allocator.maxSize();
    }

  /**
   * Return an Enumeration of my elements.
   */
  public synchronized Enumeration elements()
    {
    return VectorIterator.begin( myVector, this );
    }

  /**
   * Return an iterator positioned at my first item.
   */
  public synchronized ForwardIterator start()
    {
    return VectorIterator.begin( myVector, this );
    }

  /**
   * Return an iterator positioned immediately after my last item.
   */
  public synchronized ForwardIterator finish()
    {
    return VectorIterator.end( myVector, this );
    }

  /**
   * Return the object at the specified index.
   * @param index The index.
   */
  public synchronized Object at( int index )
    {
    return myVector.elementAt( index );
    }

  /**
   * Set the object at a specified index.  The object must be a Integer
   * @param index The index.
   * @param object The object to place at the specified index.
   * @exception java.lang.IndexOutOfBoundsException if index is not in range.
   */
  public synchronized void put( int index, Object object )
    {
    myVector.setElementAt( object, index );
    }

  /**
   * Remove all of my objects.
   */
  public void clear()
    {
    myVector.removeAllElements();
    }

  /**
   * Add an object to myself.
   */
  public synchronized Object add( Object object )
    {
    myVector.addElement( object );
    return null;
    }

  /**
   * Insert an object in front of my first element.
   * @param object The object to insert.
   */
  public synchronized void pushFront( Object object )
    {
    myVector.insertElementAt( object, 0 );
    }

  /**
   * Remove and return my first element.
   */
  public synchronized Object popFront()
    {
    Object r = myVector.firstElement();
    myVector.removeElementAt( 0 );
    return r;
    }

  /**
   * Add an object at my end.
   * @param object The object to add.
   */
  public void pushBack( Object object )
    {
    add( object );
    }

  /**
   * Remove and return my last element.
   */
  public synchronized Object popBack()
    {
    Object r = myVector.lastElement();
    myVector.removeElementAt( myVector.size() - 1 );
    return r;
    }

  /**
   * Remove all elements that match a specified object and return the number of
   * objects that were removed.
   * @param object The object to remove.
   * @return The number of objects removed.
   */
  public synchronized int remove( Object object )
    {
    int count = 0;
    while ( myVector.removeElement( object ) )
      ++count;
    return count;
    }

  /**
   * Remove at most a given number of elements that match a specified object and return the number of
   * objects that were removed.
   * @param object The object to remove.
   * @param count The maximum number of objects to remove.
   * @return The number of objects removed.
   */
  public synchronized int remove( Object object, int count )
    {
    int c = 0;
    while ( count > 0 && myVector.removeElement( object ) )
      {
      ++c;
      --count;
      }
    return c;
    }

  /**
   * Remove all elements within a specified range that match a particular object
   * and return the number of objects that were removed.
   * @param first The index of the first object to remove.
   * @param last The index of the last object to remove.
   * @param object The object to remove.
   * @return The number of objects removed.
   * @exception java.lang.IndexOutOfBoundsException If either index is invalid.
   */
  public synchronized int remove( int first, int last, Object object )
    {
    if ( ( first < 0 ) || ( last > myVector.size() - 1 ) )
      throw new IndexOutOfBoundsException( "index out of range for this Vector." );

    int count = 0;
    int index = first;

    for ( int i = first; i < last; ++i )
      {
      if ( ( myVector.elementAt( index ) ).equals( object ) )
        {
        myVector.removeElementAt( index );
        ++count;
        }
      else
        {
        ++index;
        }
      }

    return count;
    }
  }
