package rpi.goldsd.container;

import java.util.Enumeration;

/**
 * The <tt>PrimeNumberSequence</tt> class implements the <tt>Sequence</tt>
 * interface by providing <tt>sequence()</tt> methods that generate
 * enumerations of <tt>Int</tt> objects representing sequential prime
 * numbers.
 *
 * @see Sequence
 * @version 1.1, 4/16/98
 * @author David Goldschmidt
 */
public class PrimeNumberSequence implements Sequence
{
  /**
   * Returns an enumeration of sequential prime number integer values
   * starting at 2.  When the enumeration reaches the defined
   * <tt>Int.MAX_VALUE</tt> value, the <tt>hasMoreElements()</tt> method
   * returns <tt>false</tt>.
   * @return an enumeration of sequential <tt>Int</tt> objects representing
   *         the prime numbers starting at 1.
   */
  public Enumeration sequence()  { return sequence( new Int( 2 ) ); }


  /**
   * Returns an enumeration of sequential prime number integer values starting
   * at the given start value <tt>i</tt>.
   * @param i the start of the generated sequence.
   * @return an enumeration of sequential prime number integer values starting
   *         at the given start value <tt>i</tt>.
   */
  public Enumeration sequence( int i )  { return sequence( new Int( i ) ); }


  /**
   * Returns an enumeration of sequential prime number integer values starting
   * at the given start value.  When the enumeration reaches the defined
   * <tt>Int.MAX_VALUE</tt> value, the <tt>hasMoreElements()</tt> method
   * returns <tt>false</tt>.
   * @param startValue the <tt>Int</tt> object representing the start of
   *                   the generated sequence.
   * @return an enumeration of sequential <tt>Int</tt> objects representing
   *         the prime numbers.
   * @exception IllegalArgumentException if the <tt>startValue</tt> argument
   *                                     is not of type <tt>Int</tt>, or if
   *                                     <tt>startValue</tt> is not a prime
   *                                     number.
   */
  public Enumeration sequence( final Object startValue )
    throws IllegalArgumentException
  {
    if ( ! ( startValue instanceof Int ) ) throw
      new IllegalArgumentException( "Start value must be of type Int." );

    if ( ! Int.isPrime( (Int)startValue ) ) throw
      new IllegalArgumentException( "Start value must be a prime number." );

    return ( new Enumeration() {
      private int x = ((Int)startValue).value;
      public boolean hasMoreElements()  { return ( x != Int.MAX_VALUE ); }
      public Object nextElement()
      {
        Int result = new Int(x);
        while ( x != Int.MAX_VALUE && ! Int.isPrime( ++x ) );
        return result;
      }
    } );
  }
}

