package salesQuota2;

import java.util.HashMap;
import java.util.function.BiFunction;
import java.util.function.Function;

public class QuotaCalculator {
	
	/**
	 * inner enum to identify the way to calculate
	 * 
	 * @author myersjac
	 */
	public static enum Operation {
		ADD, MULTIPLY 
	}
	
	public static BiFunction<Double, Double, Double> add = (a, b) -> a + b;
	public static BiFunction<Double, Double, Double> multiply = (a, b) -> a * b;

	public static Function<SalesStatistics, Double> useAverage = ss -> ss.getAverage();
	public static Function<SalesStatistics, Double> useMedian = ss -> ss.getMedian();
	public static Function<SalesStatistics, Double> useMax = ss -> ss.getMax();
	public static Function<SalesStatistics, Double> useMin = ss -> ss.getMin();
	public static Function<SalesStatistics, Double> useYTDaverage = ss -> ss.getYtd_average();
	public static Function<SalesStatistics, Double> useYTDmedian = ss -> ss.getYtd_median();
	public static Function<SalesStatistics, Double> useYTDmax = ss -> ss.getYtd_max();
	public static Function<SalesStatistics, Double> useYTDmin = ss -> ss.getYtd_min();

	// A HashMap to use StatType enum as key for lambda functions
	
	@SuppressWarnings("serial")
	public static HashMap<SalesStatistics.StatType, Function<SalesStatistics, Double>> fetchBehaviors =
	   new HashMap<SalesStatistics.StatType, Function<SalesStatistics, Double>>() {{
		   put(SalesStatistics.StatType.AVERAGE, useAverage);
		   put(SalesStatistics.StatType.MEDIAN, useMedian);
		   put(SalesStatistics.StatType.MIN, useMin);
		   put(SalesStatistics.StatType.MAX, useMax);
		   put(SalesStatistics.StatType.YTD_AVERAGE, useYTDaverage);
		   put(SalesStatistics.StatType.YTD_MEDIAN, useYTDmedian);
		   put(SalesStatistics.StatType.YTD_MIN, useYTDmin);
		   put(SalesStatistics.StatType.YTD_MAX, useYTDmax);
	   }};
	   
		// A HashMap to use Operation enum as key for lambda functions
		
		@SuppressWarnings("serial")
		public static HashMap<Operation, BiFunction<Double, Double, Double>> operations =
		   new HashMap<Operation, BiFunction<Double, Double, Double>>() {{
			   put(Operation.ADD, add);
			   put(Operation.MULTIPLY, multiply);
		   }};
	  

}
