package aalg.algebra;

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


/**
 * Implementation of Iterator that uses underlying Iterator for getting elements and filters them.
 * Filtering is done by calling method containsElement on filtering structure.
 * @author Ing. Petr Ležák
 *
 * @param <T> type of elements
 */
public class FilteringIterator<T extends IElement> implements Iterator<T> {
	
	private final Iterator<T> baseIterator;
	private final IAlgebraicStructure<T> filteringStructure;
	
	private T nextElement;
	private boolean nextValid;
	
	/**
	 * Creates filtering iterator.
	 * @param baseIterator underlying iterator
	 * @param filteringStructure structure that is used as element filter
	 */
	public FilteringIterator(final Iterator<T> baseIterator, final IAlgebraicStructure<T> filteringStructure) {
		this.baseIterator = baseIterator;
		this.filteringStructure = filteringStructure;
		
		findNextElement();
	}

	/**
	 * Moves baseIterator to next element contained in filteringStructure.
	 * This element is stored in variable nextElement. Variable nextValid is updated,
	 * it is set to true if there is next element, false if not.
	 */
	private void findNextElement() {
		while (baseIterator.hasNext()) {
			nextElement = baseIterator.next();
			
			if (filteringStructure.containsElement(nextElement)) {
				nextValid = true;
				return;
			}
		}
		
		nextValid = false;
	}

	@Override
	public boolean hasNext() {
		return nextValid;
	}

	@Override
	public T next() {
		if (!nextValid)
			throw new NoSuchElementException();
		
		final T result = nextElement;
		findNextElement();
		
		return result;
	}

	@Override
	public void remove() {
		baseIterator.remove();
	}
	
	
}
