/*
 * WorldPoolBonus.java
 * Created on Jul 29, 2005 
 * Author: 	László Felföldi, Etixpert GmbH
 * mail:	laszlo.felfoldi@etixpert.com		
 */
package com.etixpert.evolution.app.bonus.handler;

import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jdom2.Element;

import com.etixpert.evolution.app.bonus.BonusData;
import com.etixpert.evolution.app.bonus.Handler;
import com.etixpert.evolution.event.Event;
import com.etixpert.evolution.value.DistributorValue;
import com.etixpert.evolution.value.bonus.BonusDefinitionValue;

public class WorldPoolBonus implements Handler {
	private List values;
	private Map  bonusThresholds;
	private double  threshold;

    public WorldPoolBonus(BonusDefinitionValue src) {
		values = new LinkedList();
		bonusThresholds = new Hashtable();

		// Format is bonus1=threshold1,bonus2=threshold2...?threshold;level1:val1,level2:val2,...
		
		String[] bthresholds_mainvals = src.getData().split("\\?");
		String bthresholds = bthresholds_mainvals.length < 2 ? "" : bthresholds_mainvals[0];
		String mainvals = bthresholds_mainvals[bthresholds_mainvals.length < 2 ? 0 : 1];
		String[] main = mainvals.split(";");

		String[] titems = bthresholds.split(",");
		for (int j = 0; j < titems.length; j++) {
			String[] bonus_val = titems[j].split("=");
			if (bonus_val.length == 2) 
				bonusThresholds.put(bonus_val[0], new Double(bonus_val[1]));
		}
		
		threshold = 0;
		try {threshold = Double.parseDouble(main[0]); } catch (Exception e) {}
		
		String[] items = main[1].split(",");
		for (int j = 0; j < items.length; j++) {
			String[] limit_val = items[j].split(":");
			values.add(new double[] {Double.parseDouble(limit_val[0]), Double.parseDouble(limit_val[1])});
		}
	}
    /* (non-Javadoc)
     * @see com.etixpert.evolution.app.bonus.Handler#handle(com.etixpert.evolution.event.Event, java.util.Map)
     */
    public boolean handle(Event event, Map environment) {
        // get the total bonus for this month
        double total = 0.0;
        DistributorValue dv = (DistributorValue) environment.get(new Integer(0));
        for (BonusData bd = dv.getActBonus(); bd != null; bd = bd.getPrev()) {
            total += bd.getbOV();
        }
        
        // make a map that will contains the salespersons for a BonusPool entry
        Map levels = new Hashtable();
        for (Iterator it = values.iterator(); it.hasNext();) {
            levels.put(it.next(), new HashSet());
        }
        
        // fill the sets
		for (Iterator it = environment.values().iterator(); it.hasNext(); ) {
			DistributorValue adv = (DistributorValue) it.next();
			
			// check that the distributor is qualified or not
			Double ppOV = (Double) adv.getAuxMetric("pOV");
			if (ppOV == null || ppOV.doubleValue() < threshold) continue;
			
			BonusData bd = adv.getActBonus();
			if (bd == null) continue;
			
			// find the corresponding BonusPool entry
			double apOV = bd.getpOV();
			double[] aKey = null;
			for (Iterator it2 = values.iterator(); it2.hasNext(); ) {
			    double[] entry = (double[]) it2.next();
			    if (entry[0] < apOV) aKey = entry;
			    else                 break;
			}
			
			// add the distributor to the entry
			if (aKey != null) {
			    ((Set) levels.get(aKey)).add(adv);
			}
		}
		
		// distribute the bonus
		for (Iterator it = values.iterator(); it.hasNext(); ) {
		    double[] key = (double[]) it.next();
		    Set set = (Set) levels.get(key);
		    double levelVal = total * key[1];
			double itemVal = Math.round(levelVal / set.size()) * .01; 
		    for (Iterator it2 = set.iterator(); it2.hasNext();) {
		        DistributorValue adv = (DistributorValue) it2.next();
		        BonusData bd = adv.getActBonus();
		        if (bd != null) {
					// check the conditions
					boolean enabled = true;
					Double limitPV  = (Double) bonusThresholds.get("PV");
					Double limitEV  = (Double) bonusThresholds.get("EV");
					Double limitPEV = (Double) bonusThresholds.get("PEV");
					Double limitTV  = (Double) bonusThresholds.get("TV");
					Double limitOV  = (Double) bonusThresholds.get("OV");
					if (limitPV  != null) enabled &= limitPV .doubleValue() > bd.getpPV(); 
					if (limitEV  != null) enabled &= limitEV .doubleValue() > bd.getpEV(); 
					if (limitPEV != null) enabled &= limitPEV.doubleValue() > bd.getpPEV(); 
					if (limitTV  != null) enabled &= limitTV .doubleValue() > bd.getpTV(); 
					if (limitOV  != null) enabled &= limitOV .doubleValue() > bd.getpOV(); 
					
					bd.addToSpecialBonus("WPB", (enabled ? "" : "!") + "World Bonus Pool", itemVal);
				}
			}
		}
		return true;
    }

    /* (non-Javadoc)
     * @see com.etixpert.evolution.app.bonus.Handler#toXML(org.jdom.Element)
     */
    public void toXML(Element to) {
        // TODO Auto-generated method stub

    }

}
