/** 
 * OurSinglyLinkedList2
 * Paul Heider, Dan Schulte-Sasse, Jim Finnessy
 * March 24, 2001
 * V 1.0
 *
 * Stripped down version of the OurSinglyLinkedList used in class with the
 * addition of getHead() and getSize()
 */

import SinglyLinkedListElement2;

public class OurSinglyLinkedList2 {

    protected SinglyLinkedListElement2 head; // first elt
    protected int size;

    public Object getHead() {
        return head;
    }

    public OurSinglyLinkedList2()
    // post: generates an empty list.
    {
        head = null;
        size = 0;
    }

    public void add(Object value)
    // post: adds value to beginning of list.
    {
        // note the order that things happen:
        // head is parameter, then assigned
        head = new SinglyLinkedListElement2(value, head);
        size++;
    }

    public Object removeFromHead()
    // pre: list is not empty
    // post: removes and returns value from beginning of list
    {
        SinglyLinkedListElement2 temp = head;
        head = head.next(); // move head down the list
        size--;
        return temp.value();
    }

    public boolean contains(Object value)
    // pre: value is not null
    // post: returns true iff value is found in list.
    {
        SinglyLinkedListElement2 finger = head;
        while (finger != null && !finger.value().equals(value)) {
            finger = finger.next();
        }
        return finger != null;
    }

    public Object remove(Object value)
    // pre: value is not null
    // post: removes first element with matching value, if any.
    {
        SinglyLinkedListElement2 finger = head;
        SinglyLinkedListElement2 previous = null;
        size--;

        while (finger != null && !finger.value().equals(value)) {
            previous = finger;
            finger = finger.next();
        }
        // finger points to target value
        if (finger != null) {
            // we found the element to remove
            if (previous == null) // it is first
            {
                head = finger.next();
            } else {              // it's not first
                previous.setNext(finger.next());
            }
            return finger.value();
        }
        // didn't find it, return null
        return null;
    }

    public boolean isEmpty()
    // post: returns true iff the list is empty
    {
        return head == null;
    }
    
    public String toString()
    // post: returns a string representing list
    {
        StringBuffer s = new StringBuffer();
        s.append("<OurSinglyLinkedList2:");
        SinglyLinkedListElement2 temp = head;
        while (temp != null)
        {
            s.append(" "+temp.value());
            temp = temp.next();
        }
        s.append(">");
        return s.toString();
    }

    public int getSize() {
        return size;
    }
}
