// Definition of a simple List class
// File:     SimpleList.javfa
// Based loosely on: C++ code list-class.h
// Author:   Henry M. Walker
// Date:     March 14, 2002

import ListNode;

public class SimpleList implements List {
    protected ListNode first;

    // Constructor
    public SimpleList () {
        // pre:  none
        // post: a null list is constructed
        first = null;
    }

    // observers
    public boolean isNull() {
        // pre: none
        // post:  function returns true if and only if list is empty
        return first == null;
    }

    public boolean isin (int i) {
        // pre:  the list has been initialized
        // post:  function returns TRUE if item is in list and FALSE otherwise 
        ListNode ptr = first;
        while (ptr != null) {
            if (i == ptr.getData())
                return true;
            ptr = ptr.getNext();
        }
        return false;
    }

    public int length () {
        // pre:  the list has been initialized
        // post:  the items in the list are counted and returned
        int i = 0;
        ListNode ptr = first;
        while (ptr != null) {
            i++;
            ptr = ptr.getNext();
        }
        return i;
    }

    public String toString() {
        // pre:  none
        // post:  a list is returned following a Scheme style 
        String temp;
        if (first == null)
            temp = "nil";
        else {
            temp = "(" + first.getData();
            for (ListNode ptr=first.getNext(); ptr!=null; ptr=ptr.getNext())
                temp = temp + "  " + ptr.getData();
            temp = temp + ")";
        }
        return temp;
    }
    
    public void print () {
        // pre:  the list has been initialized
        // post:  a title is printed, followed by the items from front to back
        System.out.println ("The integer values in the list nodes are");
        ListNode ptr = first;
        while (ptr != null) {
            System.out.println ("     " + ptr.getData());
            ptr = ptr.getNext();
        }
    }

    public void printReverse () {
        // pre:  the list has been initialized
        // post:  a title is printed, followed by the items from back to front
        System.out.println ("The integer values in the list (in reverse order) are");
        printReverseKernel (first);
    }

    private void printReverseKernel (ListNode ptr) {
        // a private, recursive method for printing a list in reverse order
        if (ptr != null) {
            printReverseKernel (ptr.getNext());
            System.out.println ("     " + ptr.getData());
        }
    }

    // modifiers
    public void insert (int newData) {
        // pre:  the list has been initialized
        // post:  the specified item is placed (first) on the list  
        first = new ListNode (newData, first);
    }

    public static void main (String argv[]) {
        // construct the list (3 5 7) in several steps, testing at each stage
        SimpleList a = new SimpleList();

        a.length ();

        // check lists and operations
        System.out.println ("Initial List:  " + a);
        System.out.println ("      length:   " + a.length());
        System.out.println ("      null?:    " + a.isNull());
        a.print();
        a.printReverse();
        System.out.println ("      check if 4 is on list:      " + a.isin(4));
        System.out.println ("      check if 5 is on list:      " + a.isin(5));

        System.out.println ("\nInsert 3");
        a.insert(3);
        System.out.println ("New list:  " + a);
        System.out.println ("      length:   " + a.length());
        System.out.println ("      null?:    " + a.isNull());
        a.print();
        a.printReverse();
        System.out.println ("      check if 4 is on list:      " + a.isin(4));
        System.out.println ("      check if 5 is on list:      " + a.isin(5));

        System.out.println ("\nInsert 5");
        a.insert(5);
        System.out.println ("New list:  " + a);
        System.out.println ("      length:   " + a.length());
        System.out.println ("      null?:    " + a.isNull());
        a.print();
        a.printReverse();
        System.out.println ("      check if 4 is on list:      " + a.isin(4));
        System.out.println ("      check if 5 is on list:      " + a.isin(5));

        System.out.println ("\nInsert 7");
        a.insert(7);
        System.out.println ("New list:  " + a);
        System.out.println ("      length:   " + a.length());
        System.out.println ("      null?:    " + a.isNull());
        a.print();
        a.printReverse();
        System.out.println ("      check if 4 is on list:      " + a.isin(4));
        System.out.println ("      check if 5 is on list:      " + a.isin(5));
    }

}

