package lrs.visitor;



import lrs.*;

import counter.*;

import fp.*;



public class LRSSumLambdaN implements IAlgo {

  public static final LRSSumLambdaN Singleton = new LRSSumLambdaN();

  

  private LRSSumLambdaN(){ }

  

//  private final ICounterAlgo helper = new ICounterAlgo() {

//    public Object zeroCase(ICounter cHost, Object... h) {

//      return 0.0;

//    }

//    

//    public Object nonZeroCase(ICounter cHost, Object... h){

//      return ((Number)((ILambda)((LRStruct)h[0]).getFirst()).apply(h[1])).doubleValue() + ((Double)((LRStruct)h[0]).getRest().execute(LRSSumLambdaN.this, cHost.decrement(), h[1]));

//    }

//  };

  

  

  public Object emptyCase(LRStruct host, Object... param) {

    return 0.0;

  }

  

  public Object nonEmptyCase(LRStruct host, final Object... param){

    

    return  ((ICounter) param[0]).execute(new ICounterAlgo() {

      ICounterAlgo counterHelper = this;

      

      IAlgo listHelper = new IAlgo() {

        public Object emptyCase(LRStruct h, Object... c) {

          return c[1];

        }

        public Object nonEmptyCase(LRStruct h, final Object... c){

          return ((ICounter) c[0]).execute(counterHelper, h, c[1]);

        }

      };

      

      public Object zeroCase(ICounter cHost, Object... h) {

        return h[1];

      }      

      public Object nonZeroCase(ICounter cHost, Object... h){

        return  ((LRStruct)h[0]).getRest().execute(listHelper, cHost.decrement(), 

                                                   ((Number)((ILambda)((LRStruct)h[0]).getFirst()).apply(param[1])).doubleValue()

                                                     +((Number)h[1]).doubleValue());

      }

    }, host, 0.0);

  }  

}

