/**
 * Sequence.java
 *
 *
 * Created: Fri Mar 31 09:33:27 2000
*
 * @author Hans Kyndesgaard
 * @version 1
 */

public class Sequence {
    private class SNode implements Locator{
	SNode prev;
	SNode next;
	Object element;
	boolean isContained;

	public SNode(SNode prev, SNode next, Object element){
	    this.prev = prev;
	    this.next = next;
	    this.element = element;
	    this.isContained = true;
	}

	public Object element(){
	    return this.element;
	}
	
	public Object container(){
	    return Sequence.this;
	}
	
	public boolean isContained(){
	    return this.isContained;
	}
    } //SNode

    SNode first;
    SNode last;
    Object stop = new Object();
    int size;

    /** Constructs an empty sequence. O(1) */
    public Sequence() {
	first = new SNode(null, null, stop);
	last = new SNode(first, null, stop); 
	first.next = last;
    }

    public int size(){
	return size;
    }

    /** Inserts an object at the last posistion of the sequence. O(1).
	@param o the object to be insterted.
     */
    public Locator insertLast(Object o){
	SNode n = new SNode(last.prev,last,o);
	n.prev.next = n;
	n.next.prev = n;
	size++;
	return n;
    }
    
    /** Removes an element from the sequence given that elemnts locator.
	O(1).
	@param l The locator of the element to be removed.
     */
    public void remove(Locator l){
	if (l instanceof SNode && l.isContained() && l.container() == this) {
	    SNode sn = (SNode) l;
	    sn.prev.next = sn.next;
	    sn.next.prev = sn.prev;
	    sn.isContained = false;
	    size--;
	} 
    }
    
    /** Make a string representation of the sequence. It is just the string 
	representation of all the elements. 
	@return the constructed string.
    */
    public String toString(){
	StringBuffer result = new StringBuffer("{");
	java.util.Enumeration e = elements();
	while (e.hasMoreElements()) {
	    result.append(e.nextElement().toString());
	    if (e.hasMoreElements()) {
		result.append(", ");
	    }
	}
	result.append("}");
	return result.toString();
    }
    
    /** Makes an Enumeration of all the elements of the sequence. This
	method uses O(1) time and so does all of the methods of the
	constructed Enumeration.
	@return the constructed enumeration */
    public java.util.Enumeration elements(){
	return new SEnumeration();
    }
    
    private class SEnumeration implements java.util.Enumeration{
	SNode current;
	public SEnumeration(){
	    current = first.next;
	}
	
	public boolean hasMoreElements(){
	    return current != last;
	} 
	
	public Object nextElement(){
	    if (hasMoreElements()) {
		Object result = current.element;
		current = current.next;
		return result;
	    } else {
		throw new java.util.NoSuchElementException("No more elements in Enumeration.");
	    }
	} 
    } //SEnumeration

} // Sequence
