RemMinLRS.java
package lrs.visitor;

import lrs.*;

/**
 * Removes the minimum Integer element from an LRStruct containing Integers.
 * What should be done in the case the list is empty?
 * @author DXN
 */
public class RemMinLRS implements IAlgo {

    public static final RemMinLRS Singleton = new RemMinLRS();
    private RemMinLRS() {
    }

    /**
     * There is nothing to remove: throw an exception!
     * Another sensible specification is to return null (i.e. do nothing).
     */
    public Object emptyCase(LRStruct host, Object... nu) {
        throw new IllegalArgumentException("Empty host has no data.");
    }

    /**
     * Calculates the minimum and passes the list that contains the accumulated
     * minimum down to the rest for it to "help" find the minimum.
     * The input parameter for the anonymous helper is the list whose first is
     * the smallest element that precedes the host parameter.
     */
    public Object nonEmptyCase(LRStruct host, Object... nu) {
        return host.getRest().execute(new IAlgo() {
            /**
             * We are at the end of the list.  Since acc is the LRStruct whose
             * first is the smallest element that precedes the host h, just
             * tell acc to remove its first.
             * @param acc acc[0] an LRStruct whose first is the smallest element that
             * precedes the host h.
             */
            public Object emptyCase(LRStruct h, Object... acc) {
                return ((LRStruct)acc[0]).removeFront();
            }

            /**
             * We still need to traverse the list to find the minimum.
             * Update the list containing the minimum, pass it down to the rest
             * and recurse.
             * @param acc acc[0] is an LRStruct whose first is the smallest element that
             * precedes the host h.
             */
            public Object nonEmptyCase(LRStruct h, Object... acc) {
                int f = (Integer)h.getFirst();
                int m = (Integer)((LRStruct)acc[0]).getFirst();
                return f < m ?
                    h.getRest().execute(this, h):
                    h.getRest().execute(this, acc[0]);
            }
        }
        , host);
    }
}