package com.srbenoit.render;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * An iterator over the view vertices in a scene.
 */
public class ViewVertexIterator implements Iterator<ViewVertex> {

    /** the scene being iterated */
    private final transient Scene scene;

    /** the index of the current element, -1 if finished or not yet started */
    private transient int currentElement;

    /** the index of the next element to be returned, -1 if finished */
    private transient int nextElement;

    /**
     * Constructs a new <code>ViewVertexIterator</code>.
     *
     * @param  sourceScene  the scene being iterated
     */
    public ViewVertexIterator(final Scene sourceScene) {

        this.scene = sourceScene;
        this.nextElement = scene.nextViewVertexFilled(0);
        this.currentElement = -1;
    }

    /**
     * Returns <code>true</code> if the iteration has more elements. In other words, returns <code>
     * true</code> if <code>next</code> would return an element rather than throwing an exception.
     *
     * @return  <code>true</code> if the iteration has more elements; <code>false</code> otherwise
     */
    public boolean hasNext() {

        return this.nextElement != -1;
    }

    /**
     * Returns the next element in the iteration.
     *
     * @return  the next element in the iteration
     * @throws  NoSuchElementException  if the iteration has no more elements
     */
    public ViewVertex next() throws NoSuchElementException {

        ViewVertex result;

        if (this.nextElement == -1) {
            throw new NoSuchElementException();
        }

        result = this.scene.getViewVertex(this.nextElement);
        this.currentElement = this.nextElement;
        this.nextElement = this.scene.nextViewVertexFilled(this.currentElement + 1);

        return result;
    }

    /**
     * Removes from the underlying collection the last element returned by the iterator (optional
     * operation). This method can be called only once per call to <code>next</code>.
     *
     * <p>The behavior of an iterator is unspecified if the underlying collection is modified while
     * the iteration is in progress in any way other than by calling this method.
     *
     * @throws  IllegalStateException  if the <code>next</code> method has not yet been called, or
     *                                 the <code>remove</code> method has already been called after
     *                                 the last call to the <code>next</code> method
     */
    public void remove() {

        throw new UnsupportedOperationException("Cannot remove from a view vertex array");
    }
}
