package linkedlist;

/**
 * A cursor for a linked list.
 *
 * @author CSC153 2003S
 * @version 1.0 of April 2003.
 */
public class LinkedListCursor
  implements Cursor
{
  // +--------+-----------------------------------------
  // | Fields |
  // +--------+

  Node position;
  LinkedList mylist;

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

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

  /**
   * Get the value associated with the cursor.
   * Preconditions:
   *   The cursor is at a valid position.  (See delete().)
   */
  public Object getValue() {
    return this.position.value;
  } // getValue()

  /**
   * Advance the cursor to the next value.
   * Preconditions: 
   *   The cursor is not at the end of the list.
   *   The cursor is at a valid position.  (See delete().)
   */
  public void advance() {
    this.position = this.position.next;
  } // advance()

  /**
   * Move the cursor backwards to the preev value.
   * Preconditions: 
   *   The cursor is not at the beginning of the list.
   *   The cursor is at a valid position.  (See delete().)
   */
  public void retreat() {
    // (1) Make a new cursor, iterate until we're right
    // before we want to be.
    // (2) Throw an error.
    //    throw new LazyProgrammerError();
    //    throw new Arjun();
    // (3) Go back and change the Node class to include
    //    a prev pointer
  } // retreat()

  /**
   * Delete the value associated with the cursor.
   * Preconditions:
   *   The cursor is at a valid position.  
   * Postconditions:
   *   The value associated with the cursor is no longer in the list.
   *   The list is now one element shorter.
   *   All cursors associated with the list are now at unknown
   *     (invalid) positions.
   * @return
   *   The deleted object.
   */
  public Object delete() {
    Object deletedElement = this.position.value;
    if (null != this.position.next)
      this.position.next.preev = this.position.preev;
    if (null != this.position.preev)
      this.position.preev.next = this.position.next;
    this.position.next = null;
    this.position.preev = null;
    this.position = null;
    return deletedElement;
  } // delete()

  /**
   * Determine if the cursor is at the end of the list.
   * Preconditions:
   *   The cursor is at a valid position (see delete).
   * @return
   *   True, if the cursor is at the end of the list.
   *   False, otherwise.
   */
  public boolean atEnd() {
    return null == this.position.next;
  } // atEnd()

  /**
   * Determine if the cursor is at the front of the list.
   * Preconditions:
   *   The cursor is at a valid position (see delete).
   * @return
   *   True, if the cursor is at the front of the list.
   *   False, otherwise.
   */
  public boolean atFront();

  /**
   * Move the cursor to the end of the list.
   * Preconditions:
   *   The list is nonempty.
   * Postconditions:
   *   The cursor is now at a valid position.
   *   The cursor is now at the end of the list (so atEnd returns
   *     true).
   */
  public void toEnd();

  /**
   * Move the cursor to the front of the list.
   * Preconditions:
   *   The list is nonempty.
   * Postconditions:
   *   The cursor is now at a valid position.
   *   The cursor is now at the front of the list (so atFront returns
   *     true).
   */
  public void toFront();

} // interface Cursor

