package listFW.factory;

import listFW.*;
import listFW.visitor.*;

/**
 * Manufactures concrete IMTList<E> and INEList<E> objects.  
 * The INEList object is implemented as a private anonymous inner object.
 * The implementations for MTList and NEList are 
 * completely invisible to the outside of this factory.
 * @author Dung X. Nguyen and Stephen Wong
 * @since Copyright 2004 by SBW & DXN - All rights reserved
 */
public class CompositeListFactory<E> implements IListFactory<E> {
    
    /**
     * Note: A parametrized IMTList(E> cannot be static.
     */
    private final IMTList<E> mtList = new IMTList<E>() {
        final public <R,P>  R execute(IListAlgo<? super E , R, P> algo, P ... inp) {
            return algo.emptyCase(this, inp);
        }
        
        public String toString() {
            return toStringAlgo.emptyCase(this);
        }
    };
    
    private static final IListAlgo<Object, String, ?> toStringAlgo = ToStringAlgo.Singleton;
    
    /**
     * Creates an empty list.
     * @return an IMTList object.
     */
    public IMTList<E> makeEmptyList() {
        return mtList;
    }
    
    /**
     * Creates a non-empty list containing a given first and a given rest.
     * @param first a data object.
     * @param rest != null, the rest of the non-empty list to be manufactured.
     * @return an INEList object containing first and rest
     */
    public INEList<E> makeNEList(final E first, final IList<? extends E> rest) {
        return new INEList<E>(){
            final public E getFirst() {
                return first;
            }
            
            final public IList<? extends E> getRest() {
                return rest;
            }
            
            final public <R,P> R execute(IListAlgo<? super E, R , P> algo, P ... inp) {
                return algo.nonEmptyCase(this, inp);
            }
            
            public String toString() {
                return toStringAlgo.nonEmptyCase(this);
            }
        };
    }
}