package de.renew.unify;

import java.util.Iterator;

/**
 * A custom Iterator for a {@link List}.
 */
public class ListIterator implements Iterator<Object> {
    private Object _current;

    /**
     * Creates a new {@code ListIterator} that can be used to traverse the given list.
     *
     * @param list the {@link List} to be iterated
     */
    public ListIterator(List list) {
        _current = list;
    }

    private static boolean hasMoreElements(Object list) {
        return list instanceof List && !((List) list).isNull();
    }

    @Override
    public boolean hasNext() {
        return hasMoreElements(_current);
    }

    @Override
    public Object next() {
        List list = (List) _current;


        // has to be a non-empty List, otherwise hasMoreElements()==false
        _current = list.tail();
        return list.head();
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }

    /**
     * Returns the open tail of a list element enumeration.
     * This method may only be called when all other elements
     * of this ListIterator have already been queried.
     *
     * @return the open tail of the list if it's the end,
     *         else an error is thrown or null is returned.
     * @throws IllegalStateException if getOpenTail() is called before
     *         ListEnumeration was over.
     */
    public Object getOpenTail() {
        if (hasNext()) {
            throw new IllegalStateException(
                "getOpenTail() called before ListEnumeration was over.");
        }
        if (_current instanceof List) {
            return null;
        } else {
            return _current;
        }
    }
}