/**
 * A node in a linked list along with some associated utilities.
 *
 * @author Samuel A. Rebelsky
 * @version 1.0 of November 1999
 */
public class Node {
  // +--------+--------------------------------------------------
  // | Fields |
  // +--------+

  /** The contents of the node. */
  protected Object contents;

  /** The next node in the list. */
  protected Node next;

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

  /** Build a new node with specified contents and next. */
  public Node(Object contents, Node next) {
    this.contents = contents;
    this.next = next;
  } // Node(Object, Node)

  // +-----------------------------------------------------------
  // | Extractors |
  // +------------+

  /**
   * Get the contents of the node.
   * Pre: The node is initialized and nonempty.
   * Post: Returns the contents of the current node.
   * Post: Does not modify the node.
   */
  public Object getContents() {
    return this.contents;
  } // getContents()

  /**
   * Get the next node in the list.
   * Pre: The list is initialized and nonempty.
   * Post: Returns the next node in the list.
   * Post: Does not modify the node.
   */
  public Node getNext() {
    return this.next;
  } // getNext()

  /**
   * Determine if the list represented by a node is empty.
   * We use null to represent the empty list.
   * Pre: (none)
   * Post: Returns true if the parameter is the empty list
   *   and false otherwise.
   */
  public static boolean isEmpty(Node checkMe) {
    return (checkMe == null);
  } // isEmpty(checkMe)


  // +-----------+-----------------------------------------------
  // | Modifiers |
  // +-----------+

  /**
   * Set the contents of this node to newContents.
   * Pre: The node is initialized.
   * Post: Subsequent calls to getContents return newContents (until the
   *   contents is updated again).
   * Post: The rest of the list is not modified.
   */
  public void setContents(Object newContents) {
    this.contents = newContents;
  } // setHead(Object)

  /**
   * Set the next node in the list to newNext.
   * Pre: The node is initialized.
   * Post: Subsequent calls to getNext return newNext (until the
   *   next element is updated again).
   * Post: newNext is not modified.
   */
  public void setNext(Node newNext) {
    this.next = newNext;
  } // setTail(Node)

  /**
   * Create an empty list.
   */
  public static Node nil() {
    return null;
  } // nil()

  /**
   * Cons a value onto the front of a list.
   */
  public static Node cons(Object contents, Node next) {
    return new Node(contents, next);
  } // cons(Object, Node)

} // class Next

