/*
 * @(#)ListIterator.java
 *
 * Copyright (c) 2002-2003 JSCAPE
 * 1147 S. 53rd Pl., Mesa, Arizona, 85206, U.S.A.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * JSCAPE. ("Confidential Information").  You shall not disclose such
 * Confidential Information and shall use it only in accordance with
 * the terms of the license agreement you entered into with JSCAPE.
 */

package com.jscape.util;

import java.util.*;

import static com.jscape.util.Parameters.assertInRangeInclusive;

/**
 * Random access iterator.
 *
 * @author Alex
 */
public class ListIterator<T>
        implements Iterator<T> {

    private static final int START_POS = -1;

    private List<T> objects;
    private int index;

    public ListIterator(Collection<T> collection) {
        this.objects = collection instanceof ArrayList ? (ArrayList<T>) collection : new ArrayList<T>(collection);
        this.index = START_POS;
    }

    public int index() {
        return this.index;
    }

    public void index(int position) {
        assertInRangeInclusive(position, START_POS, this.objects.size(), "Bad index value.");
        this.index = position;
    }

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

    public boolean hasNext() {
        return (this.index == START_POS && this.objects.size() > 0) || this.index < (this.objects.size() - 1);
    }

    public T next() {
        assertHasNext();

        ++this.index;

        return value();
    }

    public T value() {
        return this.objects.get(this.index);
    }

    public void reset() {
        index(START_POS);
    }

    @Override
    public String toString() {
        return "ListIterator {"
                + "objects=" + this.objects
                + ", index=" + this.index
                + '}';
    }

    private void assertHasNext() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
    }

}
