/******************************************************************************
Sequence Interface

----------------------------------------------------
Copyright (c) Gunnar Gotshalks. All Rights Reserved.

Permission to use, copy, modify, and distribute this software
and its documentation for NON-COMMERCIAL purposes and
without fee is hereby granted. 
*******************************************************************************/

package FlexOr.container;

/**
This interface together with the container interface parallels the that of
the java Vector class since a vector is an implementation of a sequence --
although it is not of type Sequence.  In principle Vector would be defined as
implementing a Sequence.

<P> We make use of the implied mapping between items in a sequence and the
nonnegative integers (0,1,2, ...)  to specify a collection of methods which
index the sequence.

<P>
@author Gunnar Gotshalks
@see java.util.Vector
@version 1.0 1999 Jan 15
*/

public interface Sequence extends Container {

/*******************************************************************************
   Access Methods
*******************************************************************************/

/** Return the element at the specified index.

<P><PRE><B>Requires:</B> 0 <= index < size
<B>Ensures:</B> result = sequence[index]
</PRE>
@exception SequenceIndexException if index is out of bounds.
*/

  Object elementAt(int index); 

/** Return the first element in the sequence.

<P><PRE><B>Requires:</B> True
<B>Ensures:</B> length > 0 => result = sequence[first]
                length = 0 => result = null
</PRE>
*/
 
  Object firstElement();

/** Return the index of the specified element.

<P><PRE><B>Requires:</B> True
<B>Ensures:</B> contains(obj) => sequence[result] = obj
            not contains(obj) => result = -1
</PRE>
*/  

  int indexOf(Object obj);

/** Return the index of the specified element between the start index and
the end of the sequence.

<P><PRE><B>Requires:</B> True
<B>Ensures:</B> 
       sequence[startIndex..length-1].contains(obj) => sequence[result] = obj
   not sequence[startIndex..length-1].contains(obj) => result = -1
</PRE>
*/  

  int indexOf(Object obj, int startIndex);

/** Return the last element in the sequence.

<P><PRE><B>Requires:</B> True
<B>Ensures:</B> isEmpty => result = null
        not isEmpty => result = sequence[last]
</PRE>
*/
  
  Object lastElement();

/*******************************************************************************
   Update Methods
*******************************************************************************/

/** Insert the element at the specified index. We permit index to be size
-- instead of size - 1 -- to specify adding at the end of the list.

<P><PRE><B>Requires:</B> 0 <= index < old size + 1
<B>Ensures:</B>
    sequence = old sequence[first..index-1] ^ obj ^ old sequence[index..last]
</PRE>
@exception SequenceIndexException if index is out of bounds.
@exception ContainerFullException if container already contains MaxLength
elements for finite size sequences.
*/
  
  void insertAt(Object obj, int index);

/** If <CODE>obj</CODE> is found remove it from the container.

<P><PRE><B>Requires:</B> True
<B>Ensures:</B>
    old sequence.contains(obj) => sequence = old sequence / obj and result = true 
not old sequence.contains(obj) => sequence = old sequence and result = false
</PRE>
*/

  boolean remove(Object obj);

/** Remove the element at the specified index.

<P><PRE><B>Requires:</B> 0 <= index < size
<B>Ensures:</B>
    sequence = old sequence[first..index-1] ^ old sequence[index+1..last]
</PRE>
@exception SequenceIndexException if index is out of bounds. 
*/
  
  void removeAt(int index);

/** Replace the object at the specified index.
<PRE><B>Requires:</B> 0 <= index < size
<B>Ensures:</B> sequence[index] = obj
</PRE>
@exception SequenceIndexException if index is out of bounds. 
*/
  
  void setAt(Object obj, int index);
  
}