package org.eclipse.jst.jsf.common.internal.policy;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;

/**
 * 
 * @author cbateman
 *
 * @param <ITERATORTYPE>
 */
public class IdentifierOrderedIteratorPolicy<ITERATORTYPE> implements
        IIteratorPolicy<ITERATORTYPE>
{
    private final Iterable<ITERATORTYPE>   _policyOrder;
    // controls whether the policy iterator will return items that are
    // not explicitly listed in policyOrder.
    private boolean                        _excludeNonExplicitValues = false;
    
    /**
     * @param policyOrder
     */
    public IdentifierOrderedIteratorPolicy(final Iterable<ITERATORTYPE> policyOrder)
    {
        _policyOrder = policyOrder;
    }
    
    /**
     * Default value is <b>false</b>.
     * 
     * @return if true, the iterator will not return values in the forCollection
     * passed to getIterator whose identifier are not explicitly listed in
     * the policyOrder,  If false, these values will be return after all
     * the policyOrder values have been returned.
     */
    public boolean isExcludeNonExplicitValues()
    {
        return _excludeNonExplicitValues;
    }

    /**
     * @param excludeNonExplicitValues
     */
    public void setExcludeNonExplicitValues(boolean excludeNonExplicitValues)
    {
        _excludeNonExplicitValues = excludeNonExplicitValues;
    }

    public Iterator<ITERATORTYPE> getIterator(
            final Collection<ITERATORTYPE> forCollection)
    {
        return new MyIterator<ITERATORTYPE>(forCollection, _excludeNonExplicitValues, _policyOrder);
    }

    private static class MyIterator<ITERATORTYPE> implements Iterator<ITERATORTYPE>
    {
        private final List<ITERATORTYPE>         _items;
        private final Iterator<ITERATORTYPE>    _policyIterator;
        private ITERATORTYPE                    _next;
        
        MyIterator(final Collection<ITERATORTYPE> collection,
                final boolean excludeNonExplicitValues,
                final Iterable<ITERATORTYPE> policyOrder)
        {
            _items = new ArrayList();
            _items.addAll(collection);

            _policyIterator = policyOrder.iterator();
            _next = findNext();
        }
        
        public boolean hasNext()
        {
            return _next != null;
        }

        public ITERATORTYPE next()
        {
            if (_next != null)
            {
                ITERATORTYPE next = _next;
                //calculate next one before returning
                _next = findNext();
                return next;
            }
            
            throw new NoSuchElementException("No more elements");
        }

        public void remove()
        {
            throw new UnsupportedOperationException();
        }
        
        private ITERATORTYPE findNext()
        {
            while (_policyIterator.hasNext())
            {
                ITERATORTYPE next = _policyIterator.next();
                if (_items.contains(next))
                {
                    _items.remove(next);
                    return next;
                }
            }
            
            // we have exhausted the _items that are in the policy iterator
            // now return any further _items in the order they are in the list
            if (_items.size() > 0)
            {
                return _items.remove(0);
            }
            
            return null;
        }
    }
}
