/*
 * DistributorHistoryValue.java
 * Created on May 11, 2005 
 * Author: 	L�szl� Felf�ldi, Etixpert GmbH
 * mail:	laszlo.felfoldi@etixpert.com		
 */
package com.etixpert.evolution.app.bonus;

import java.math.BigDecimal;
import java.sql.Connection;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.jdom2.Element;

import com.etixpert.evolution.ObjectSearch;
import com.etixpert.evolution.PersistableObject;
import com.etixpert.evolution.value.DistributorValue;

public class BonusDataNew {
	//static DateFormat dateformat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, Locale.GERMAN);		
	static DateFormat dateformat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMAN);		
	
	private DistributorValue distributor;
	private Integer activeSponsor;
	
	private double personalNetto;
	private double personalTradeMargin;
	private double personalBonus;
	
	private double totalNetto;
	private double totalTradeMargin;
	private double totalBonus;
	
	private double totalNettoLevel1;
	private double totalNettoLevel2;
	private double totalNettoLevel3;
	
	private double totalBonusLevel1;
	private double totalBonusLevel2;
	private double totalBonusLevel3;
	
	private double distributorBonus;
	private double teamBonusLevel1;
	private double teamBonusLevel2;
	private double teamBonusLevel3;
	
	// limits
	private double db0;
	private double db1;
	private double db2;
	private double db3;
	private double db4;
	
	private double tbq;
	private double t2_level1_criteria;
	private double t3_level1_criteria;
	private double t3_level2_criteria;
	
	
	public BonusDataNew(DistributorValue aDistributor, Integer aActiveSponsor,
			double aPersonalNetto, double aPersonalTradeMargin, double aPersonalBonus,
			double aTotalNetto, double aTotalTradeMargin, double aTotalBonus,
			double aTotalNettoLevel1, double aTotalNettoLevel2, double aTotalNettoLevel3,
			double aTotalBonusLevel1, double aTotalBonusLevel2, double aTotalBonusLevel3,  
			double aDistributorBonus, double aTeamBonusLevel1, double aTeamBonusLevel2, double aTeamBonusLevel3,
			double aDb0, double aDb1, double aDb2, double aDb3, double aDb4,
			double aTbq, double aT2_level1_criteria, double aT3_level1_criteria, double aT3_level2_criteria) {
		
		distributor = aDistributor;
		activeSponsor = aActiveSponsor;
		
		personalNetto = aPersonalNetto;
		personalTradeMargin = aPersonalTradeMargin;
		personalBonus = aPersonalBonus;
		
		totalNetto = aTotalNetto;
		totalTradeMargin = aTotalTradeMargin;
		totalBonus = aTotalBonus;
		
		totalNettoLevel1 = aTotalNettoLevel1;
		totalNettoLevel2 = aTotalNettoLevel2;
		totalNettoLevel3 = aTotalNettoLevel3;

		totalBonusLevel1 = aTotalBonusLevel1;
		totalBonusLevel2 = aTotalBonusLevel2;
		totalBonusLevel3 = aTotalBonusLevel3;
		
		distributorBonus = aDistributorBonus;
		teamBonusLevel1 = aTeamBonusLevel1;
		teamBonusLevel2 = aTeamBonusLevel2;
		teamBonusLevel3 = aTeamBonusLevel3;

		db0 = aDb0;
		db1 = aDb1;
		db2 = aDb2;
		db3 = aDb3;
		db4 = aDb4;
		
		tbq = aTbq;
		t2_level1_criteria = aT2_level1_criteria;
		t3_level1_criteria = aT3_level1_criteria;
		t3_level2_criteria = aT3_level2_criteria;
		
	    distributor.setActBonusNew(this);
        //System.err.println("BonusData created for " + distributor.getId());
	}
	
	public DistributorValue getSponsor() {
		return distributor.getSponsor();
	}
	
	public DistributorValue getDistributor() {
		return distributor;
	}
	
	public double getTotalBonus() {
		return totalBonus;
	}
	
	private void toXML(Element target) {
		NumberFormat nf = NumberFormat.getIntegerInstance(Locale.ENGLISH);
		nf.setMaximumFractionDigits(3);
		nf.setGroupingUsed(false);
		
		Element e = new Element("item");
		
		e.setAttribute("Id",      "" + distributor.getId());
		e.setAttribute("LevelId", "" + distributor.getLevelId());
		
		e.setAttribute("ActiveSponsor", "" + activeSponsor);
			
		e.setAttribute("PersonalNetto", nf.format(personalNetto));
		e.setAttribute("PersonalTradeMargin", nf.format(personalTradeMargin));
		e.setAttribute("PersonalBonus", nf.format(personalBonus));
		
		e.setAttribute("TotalNetto", nf.format(totalNetto));
		e.setAttribute("TotalTradeMargin", nf.format(totalTradeMargin));
		e.setAttribute("TotalBonus", nf.format(totalBonus));
		
		e.setAttribute("TotalNettoLevel1", nf.format(totalNettoLevel1));
		e.setAttribute("TotalNettoLevel2", nf.format(totalNettoLevel2));
		e.setAttribute("TotalNettoLevel3", nf.format(totalNettoLevel3));
		
		e.setAttribute("TotalBonusLevel1", nf.format(totalBonusLevel1));
		e.setAttribute("TotalBonusLevel2", nf.format(totalBonusLevel2));
		e.setAttribute("TotalBonusLevel3", nf.format(totalBonusLevel3));
		
		e.setAttribute("DistributorBonus", nf.format(distributorBonus));
		e.setAttribute("TeamBonusLevel1", nf.format(teamBonusLevel1));
		e.setAttribute("TeamBonusLevel2", nf.format(teamBonusLevel2));
		e.setAttribute("TeamBonusLevel3", nf.format(teamBonusLevel3));
		
		e.setAttribute("db0", nf.format(db0));
		e.setAttribute("db1", nf.format(db1));
		e.setAttribute("db2", nf.format(db2));
		e.setAttribute("db3", nf.format(db3));
		e.setAttribute("db4", nf.format(db4));
		
		e.setAttribute("tbq", nf.format(tbq));
		e.setAttribute("t2_level1_criteria", nf.format(t2_level1_criteria));
		e.setAttribute("t3_level1_criteria", nf.format(t3_level1_criteria));
		e.setAttribute("t3_level2_criteria", nf.format(t3_level2_criteria));
		
		target.addContent(e);
		
		for (Iterator it = distributor.getChildren().iterator(); it.hasNext();) {
			DistributorValue child = (DistributorValue) it.next();
			if (child.getActBonusNew() != null) {
				child.getActBonusNew().toXML(e);
			}
		}
	}

	public static Element toXML(Map environment) {
		Element ret = new Element("bonus");
		DistributorValue bv = ((DistributorValue) environment.get(""));
		if (bv.getActBonusNew() != null) 
			bv.getActBonusNew().toXML(ret);
		return ret;
	}
	
	protected static double getDouble(Map values, String name, double def) {
		try {
			Object val = values.get(name);
			if (val instanceof BigDecimal) 
				return ((BigDecimal) val).doubleValue();
			if (val instanceof Integer)
				return ((Integer) val).doubleValue();
		} catch (Exception e) {}
		return def;
	}

	protected static int getInteger(Map values, String name, int def) {
		try {
			Object val = values.get(name);
			if (val instanceof BigDecimal) 
				return ((BigDecimal) val).intValue();
			if (val instanceof Integer)
				return ((Integer) val).intValue();
		} catch (Exception e) {}
		return def;
	}
	
	public static BonusDataNew getFromPO(PersistableObject po, DistributorValue dv) {
		Map values = po.getValues();
		
		Integer activeSponsor = getInteger(values, "active_sponsor", 0);
		
		double personalNetto       = getDouble(values, "personal_netto", 0);
		double personalTradeMargin = getDouble(values, "personal_trade_margin", 0);
		double personalBonus       = getDouble(values, "personal_bonus", 0);

		double totalNetto       = getDouble(values, "total_netto", 0);
		double totalTradeMargin = getDouble(values, "total_trade_margin", 0);
		double totalBonus       = getDouble(values, "total_bonus", 0);
		
		double totalNettoLevel1 = getDouble(values, "total_netto1", 0);
		double totalNettoLevel2 = getDouble(values, "total_netto2", 0);
		double totalNettoLevel3 = getDouble(values, "total_netto3", 0);
		
		double totalBonusLevel1 = getDouble(values, "total_bonus1", 0);
		double totalBonusLevel2 = getDouble(values, "total_bonus2", 0);
		double totalBonusLevel3 = getDouble(values, "total_bonus3", 0);

		double distributorBonus = getDouble(values, "distributor_bonus", 0);
		double teamBonusLevel1 = getDouble(values, "team_bonus_level1", 0);
		double teamBonusLevel2 = getDouble(values, "team_bonus_level2", 0);
		double teamBonusLevel3 = getDouble(values, "team_bonus_level3", 0);
		
		double db0 = getDouble(values, "db0", 0);
		double db1 = getDouble(values, "db1", 0);
		double db2 = getDouble(values, "db2", 0);
		double db3 = getDouble(values, "db3", 0);
		double db4 = getDouble(values, "db4", 0);
		
		double tbq = getDouble(values, "tbq", 0);
		double t2_level1_criteria = getDouble(values, "t2_level1_criteria", 0);
		double t3_level1_criteria = getDouble(values, "t3_level1_criteria", 0);
		double t3_level2_criteria = getDouble(values, "t3_level2_criteria", 0);
		
		return new BonusDataNew(dv, activeSponsor,
				personalNetto, personalTradeMargin, personalBonus, 
				totalNetto, totalTradeMargin, totalBonus,
				totalNettoLevel1, totalNettoLevel2, totalNettoLevel3,
				totalBonusLevel1, totalBonusLevel2, totalBonusLevel3, 
				distributorBonus, teamBonusLevel1, teamBonusLevel2, teamBonusLevel3,
				db0, db1, db2, db3, db4,
				tbq, t2_level1_criteria, t3_level1_criteria, t3_level2_criteria);
	}
		
	public static BonusDataNew getFromDB(Connection con, Date month, Map environment, boolean fromHistory, DistributorValue dv) {
	    String table = "t_worker_bonus";
	    
	    if (fromHistory) table += "_history";
	    
	    Object id = dv != null ? dv.getId() : null;
	    String where = id != null ? "where id=?" : "";
	    if (fromHistory) {
	    	where += id == null ? " where " : " and ";
			where += "month=?";
	    }
	    
	    Integer monthValue = null;
	    if (fromHistory) {
		    Calendar c = Calendar.getInstance();
			c.setTime(month);
			monthValue = new Integer(c.get(Calendar.YEAR) * 100 + c.get(Calendar.MONTH) + 1);
	    }

	    Object[] params = id != null ? 
	    		monthValue == null ? new Object[] {id} : new Object[] {id, monthValue} :
	    		monthValue == null ? new Object[] {} : new Object[] {monthValue};
	    				
	    
		List items = null;
		ObjectSearch os = new ObjectSearch();
	    try {
	    	items = os.search(con, 
	    			"select * from " + table + " " + where, 
	    			params);
	    } catch (Exception e) {
	    	e.printStackTrace(System.err);
	    }
	    
	    BonusDataNew ret = null;
		if (items != null){
	    	for (Iterator it = items.iterator(); it.hasNext(); ) {
	    		PersistableObject po = (PersistableObject) it.next();
	    		
	    		DistributorValue adv = dv;
	    		if (adv == null) {
	    			Map val = po.getValues();
	    			Integer aid = new Integer("" + val.get("id"));
	    			adv = (DistributorValue) environment.get(aid);
	    		}
	    		BonusDataNew res = adv != null ? getFromPO(po, adv) : null;
	    		if (ret == null) ret = res;
	    	}
		}
		return ret;
	}

	public static BonusDataNew get(DistributorValue src, Date date, boolean fromHistory, Connection con) {
		if (src == null) return null;
		BonusDataNew ret = src.getActBonusNew();

		if (ret == null) { 
			ret = getFromDB(con, date, null, fromHistory, src);
		}
		return ret;
	}
}
