/*
 * Copyright (C) 2011 jandre
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package rules;

import static org.nuiton.i18n.I18n._;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import scripts.ResultName;
import scripts.SiMatrix;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import java.io.Writer;

import org.nuiton.math.matrix.*;

import fr.ifremer.isisfish.util.Doc;
import fr.ifremer.isisfish.*;
import fr.ifremer.isisfish.simulator.SimulationContext;
import fr.ifremer.isisfish.types.Date;
import fr.ifremer.isisfish.entities.*;
import fr.ifremer.isisfish.rule.AbstractRule;
import fr.ifremer.isisfish.datastore.SimulationStorage;
import fr.ifremer.isisfish.datastore.ResultStorage;
import fr.ifremer.isisfish.IsisFishDAOHelper;
import fr.ifremer.isisfish.simulator.MetierMonitor;
import fr.ifremer.isisfish.simulator.SimulationContext;
import fr.ifremer.isisfish.types.Date;
import fr.ifremer.isisfish.types.Month;
import fr.ifremer.isisfish.entities.*;
import fr.ifremer.isisfish.rule.AbstractRule;

/**
 * Recruit_distribution_BMW.java
 *
 * Created: 11 mai 2011
 *
 * @author jandre <user.name@vcs.hostName>
 * @version $Revision: 1545 $
 * Last update: $Date: 11 mai 2011 $
 * by : $Author: jandre $
 */
public class Recruit_distribution_BMW extends AbstractRule {

    /** to use log facility, just put in your code: log.info("..."); */
    private static Log log = LogFactory.getLog(Recruit_distribution_BMW.class);

	@Doc("Recruitment 1998")
    	public double param_recruit1998 = 28242;
    	@Doc("Recruitment 1999")
    	public double param_recruit1999 = 30735;
    	@Doc("Recruitment 2000")
    	public double param_recruit2000 = 128069;
    	@Doc("Recruitment 2001")
    	public double param_recruit2001 = 133271;
    	@Doc("Recruitment 2002")
    	public double param_recruit2002 = 66466;
    	@Doc("Recruitment 2003")
    	public double param_recruit2003 = 136641;
    	@Doc("Recruitment 2004")
    	public double param_recruit2004 = 97484;
    	@Doc("Recruitment 2005")
    	public double param_recruit2005 = 118732;
    	@Doc("Recruitment 2006")
    	public double param_recruit2006 = 51677;
    	@Doc("Recruitment 2007")
    	public double param_recruit2007 = 57565;
    	@Doc("Recruitment 2008")
    	public double param_recruit2008 = 40947;

    	@Doc("Month for begining of reproduction")
    	public Month param_beginrepro = Month.FEBRUARY;
    	@Doc("Month for end of reproduction")
    	public Month param_endrepro = Month.MAY;

    	public Population param_Population = null;
    	boolean dejaFait = false;   //pour ne pas le faire pour chaque metier

    	//protected PopulationMonitor popMon;
    	
//*************************************************************************************************
    public String [] necessaryResult = {
        // put here all necessary result for this rule
	    // example: 
	    // ResultName.MATRIX_BIOMASS,
	    // ResultName.MATRIX_NET_VALUE_OF_LANDINGS_PER_STRATEGY_MET,
    };

    public String[] getNecessaryResult() {
        return this.necessaryResult;
    }

//*************************************************************************************************
    /**
     * Permet d'afficher a l'utilisateur une aide sur la regle.
     * @return L'aide ou la description de la regle
     */
    public String getDescription() throws Exception {
        // TODO
        return _("Allow to distribute the recruits between males (age0-Age14) and females (Age15-Age29. Recruits" + 
        "for the year are distributed 50% towrads Age0 and 50% towards Age15. Because reproduction takes place over 4 months,"+
        "each reproduction month receive 1/4 of recruits");
    }

//*************************************************************************************************
    /**
     * Appele au demarrage de la simulation, cette methode permet d'initialiser
     * des valeurs
     * @param simulation La simulation pour lequel on utilise cette regle
     */
    public void init(SimulationContext context) throws Exception {
    	
    }
    
//*************************************************************************************************
    /**
     * La condition qui doit etre vrai pour faire les actions
     * @param simulation La simulation pour lequel on utilise cette regle
     * @return vrai si on souhaite que les actions soit faites
     */
    public boolean condition(SimulationContext context, Date date, Metier metier) throws Exception {
       
        log.info("Finds out if the rule applies (i.e. if we are in the reproductive months");
        boolean result = true;
        if (date.getMonth().before(param_beginrepro)) {
            return false;
        } else if (date.getMonth().after(param_endrepro)) {
            return false;
        }
          
 	return result;
      
    }

//*************************************************************************************************
    /**
     * Si la condition est vrai alors cette action est executee avant le pas
     * de temps de la simulation.
     * @param simulation La simulation pour lequel on utilise cette regle
     */
    public void preAction(SimulationContext context, Date date, Metier metier) throws Exception {
    
    		System.out.println("already done ? "+ dejaFait);
		if (dejaFait == false){
    		log.info("Pre-simulation: applies the rule to the month of reproduction");
    		int currentYear = context.getSimulationControl().getDate().getYear();

		PopulationMonitor popMon = context.getPopulationMonitor();
		//popMon = context.getPopulationMonitor();
		MatrixND eff = popMon.getN(param_Population);
		//recruitment zone for the population - can be a list of zone of presence
		List<Zone> zoneRecru = popMon.getRecruitmentZone();

    			for (MatrixIterator i = eff.iterator(); i.hasNext();){
				i.next();
				Object[] sems = i.getSemanticsCoordinates();
				PopulationGroup group = (PopulationGroup) sems[0];
				Zone zone = (Zone) sems[1];
				System.out.println("zone :"+ zone+ " group:"+group.getId());
				if ((zoneRecru.contains(zone) & ((group.getId() == 0 || (group.getId() == 15))))){
    					if (currentYear==0){// Year = 1998
    						i.setValue(param_recruit1998/8);
    					}else if (currentYear==1){// Year1 =1999
    						i.setValue(param_recruit1999/8);
    					}else if (currentYear==2){// Year2 =2000
    						i.setValue(param_recruit2000/8);
    					}else if (currentYear==3){// Year3 =2001
    						i.setValue(param_recruit2001/8);
    					}else if (currentYear==4){// Year4 =2002
    						i.setValue(param_recruit2002/8);
    					}else if (currentYear==5){// Year5 =2003
    						i.setValue(param_recruit2003/8);
    					}else if (currentYear==6){// Year6 =2004
    						i.setValue(param_recruit2004/8);
    					}else if (currentYear==7){// Year7 =2005
    						i.setValue(param_recruit2005/8);
    					}else if (currentYear==8){// Year8 =2006
    						i.setValue(param_recruit2006/8);
    					}else if (currentYear==9){// Year9 =2007
    						i.setValue(param_recruit2007/8);
    					}else {// Year10 =2008
    						i.setValue(param_recruit2008/8);
    					}// end if year
    					
    				}// end if zone recrutment
    		
    		
    			}//end for Matrix iterator
		dejaFait = true ; //pour ne pas le refaire au metier suivant
		}
		
    //return result;		
    }

//*************************************************************************************************
    /**
     * Si la condition est vrai alors cette action est executee apres le pas
     * de temps de la simulation.
     * @param simulation La simulation pour lequel on utilise cette regle
     */
    public void postAction(SimulationContext context, Date date, Metier metier) throws Exception {
    dejaFait = false;    
    }
}