/**
 * Something that can be used to look at all the elements in one of
 * Yvonne's doubly-linked lists.
 *
 * @author Alex Leach
 * @author Yvonne Palm
 * @author Samuel A. Rebelsky
 * @author Jonathan "JWells" Wellons
 */
public class YDLLIterator
  implements ListIterator
{
  // +--------+---------------------------------------------------
  // | Fields |
  // +--------+

  /**
   * The node that we are currently "on".
   */
  DoublyLinkedNode here;

  // +--------------+---------------------------------------------
  // | Constructors |
  // +--------------+

  /**
   * Create a new iterator that refers to a particular node.
   */
  public YDLLIterator(DoublyLinkedNode start) {
    this.here = start;
  } // YDLLIterator


  // +---------+--------------------------------------------------
  // | Methods |
  // +---------+

  /**
   * Advance the iterator to the next element.
   */
  public void advance() {
    this.here = this.here.next;
  } // advance()

  /**
   * Get the current value.
   */
  public Object current() {
    return this.here.contents;
  } // current()

  /** 
   * Delete the thing the iterator currently refers to and 
   * advance the iterator to the next element.  Return the 
   * deleted value.
   */
  public Object delete() {
    DoublyLinkedNode oldNode = this.here;
    // Update the next link of the previous node
    if (this.here.prev != null)
      this.here.prev.next = this.here.next;
    // Update the previous link of the next node
    if (this.here.next != null)
      this.here.next.prev = this.here.prev;
    // Advance to the next node
    this.here = oldNode.next;
    // Forget about the links
    oldNode.prev = null;
    oldNode.next = null;
    // That's it, were' done.
    return oldNode.contents;
  } // delete()

  /**
   * Advance the iterator to a particular value.  If the value
   * does not appear in the list, move the iterator off the list.
   */
  public void find(Object findMe) {
    // STUB
  }

  /**
   * Insert a value before the current value.
   */
  public void insertBefore(Object newValue) {
    DoublyLinkedNode newNode = 
      new DoublyLinkedNode(this.here.prev, newValue, this.here);
    if (this.here.prev != null)
      this.here.prev.next = newNode;
    this.here.prev = newNode;
  } // insertBefore(Object)

  /**
   * Insert a value after the current value.
   */
  public void insertAfter(Object newValue) {
    // STUB
  }

  /**
   * Replace the current value.  Return the old value.
   */
  public Object replace(Object newValue) {
    return this.here.contents;  // STUB
  }

  /**
   * Determine if we're still in the list.
   */
  public boolean isValid() {
    return this.here != null;
  } // isValid()
} // interface YDLLIterator

