package lrs.lazyLRSEvaluators;

import fp.*;
import lrs.*;

/**
 * Lazily creates a possibly infinite list that sums groups of Integers
 * in the input list. Initially it adds two Integers, then three Integers,
 * then four, etc.
 * If the list becomes empty at any time, the generated list ends.
 */
public class LazyIncreasingAdderEval extends LazyLambdaApplyEval {
    // FOR STUDENT TO COMPLETE: add fields and methods here
    static class AdderLambda implements ILambda {
        int num;
        public AdderLambda(int n) { num = n; }
        public Object apply(Object... p) {
            final LRStruct l = (LRStruct)p[0];
            return l.execute(new IAlgo() {
                public Object emptyCase(LRStruct host, Object... inp) {
                    return 0;
                }
                public Object nonEmptyCase(LRStruct host, Object... inp) {
                    if (num--==0) { return 0; }
                    Integer i = (Integer)l.removeFront();
                    return i+(Integer)(l.execute(this));
                }
            });
        }
    }

    public LazyIncreasingAdderEval(LRStruct src) {
        super(new ALazyEval() {
            int num = 2;
            public LRStruct makeLRS() {
                return makeLazyLRS(new AdderLambda(num++));
            }
            public LRStruct nextLRS() {
                return makeLRS();
            }
        }.makeLRS(),src);
    }
}

