package rules;

import fr.ifremer.isisfish.rule.AbstractRule;
import fr.ifremer.isisfish.IsisFishDAOHelper;
import fr.ifremer.isisfish.simulator.MetierMonitor;
import fr.ifremer.isisfish.simulator.PopulationMonitor;
import fr.ifremer.isisfish.simulator.SimulationContext;
import fr.ifremer.isisfish.types.Month;
import fr.ifremer.isisfish.entities.*;

import java.io.*;
import java.util.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.math.matrix.MatrixIterator;
import org.nuiton.math.matrix.MatrixFactory;
import org.nuiton.math.matrix.MatrixND;
import org.nuiton.util.FileUtil;

import scripts.ResultName;
import scripts.RuleUtil;
import scripts.SiMatrix;
import fr.ifremer.isisfish.simulator.ResultManager;
import fr.ifremer.isisfish.datastore.ResultStorage;
import fr.ifremer.isisfish.entities.EffortDescription;
import fr.ifremer.isisfish.entities.Metier;
import fr.ifremer.isisfish.entities.Zone;
import fr.ifremer.isisfish.entities.Population;
import fr.ifremer.isisfish.entities.PopulationGroup;
import fr.ifremer.isisfish.entities.Species;
import fr.ifremer.isisfish.entities.Strategy;
import fr.ifremer.isisfish.entities.StrategyMonthInfo;
import fr.ifremer.isisfish.entities.TargetSpecies;
import fr.ifremer.isisfish.rule.AbstractRule;
import fr.ifremer.isisfish.simulator.MetierMonitor;
import fr.ifremer.isisfish.simulator.PopulationMonitor;
import fr.ifremer.isisfish.simulator.SimulationContext;
import fr.ifremer.isisfish.types.TimeStep;
import fr.ifremer.isisfish.types.Month;
import fr.ifremer.isisfish.util.Doc;


public class AjustAbondanceWithCapture extends AbstractRule{
	
	/** to use log facility, just put in your code: log.info("..."); */
    static private Log log = LogFactory.getLog(AjustAbondanceWithCapture.class);
    
    @Doc("Affected species")
    public Population param_Population = null;
	public String param_nomEspece = "";
	
    @Doc("Debin date")
    public TimeStep param_beginStep = new TimeStep(0); //2008
    @Doc("End date")
    public TimeStep param_endStep = new TimeStep(36); //2010
    
    public String cheminfichier = "S:/Parametrage/EstimationCoeffFishing/Francois/ChampAbondance/DonneesPropAtAge/Fichier_csv/";
    protected MatrixND matrix;
	protected List<Zone> allZone ;
	protected Map<PopulationGroup , MatrixND> CaptAuxAges;
	protected MatrixND test ;

	
	
    
    boolean affectation = false;

   
    
    protected String[] necessaryResult = {
    	    // put here all necessary result for this rule
    	    // example: 
    	    // ResultName.MATRIX_BIOMASS,
    	    // ResultName.MATRIX_NET_VALUE_OF_LANDINGS_PER_STRATEGY_MET,
    	    };
    
    /**
     * @return the necessaryResult
     */
    @Override
    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
     */
    @Override
    public String getDescription() {
        return ("On retire les captures l'abondance des especes referencer dans Isis pour la Manche Est");
    }
    
    /**
     * Appele au demarrage de la simulation, cette methode permet d'initialiser
     * des valeurs
     * 
     * @param context La simulation pour lequel on utilise cette regle
     */
    @Override
    public void init(SimulationContext context) throws Exception {
    	
    	//Date 2008-2010 => 36 mois
		TimeStep date = new TimeStep(0);
        List<TimeStep> dates = new ArrayList <TimeStep>();
		for (int i=0; i < 36; i++) {
			dates.add(new TimeStep (i));
		}
				
    	//vecteur contenant toutes les classes d'age possibles
    	//String[] age1 = {"0","1","2","3","4","5","6","7","8","9","10","11","12"};

		
    	// vecteur des noms des fichiers csv de chaques especes pour chacunes de leurs classes d'ages
//    	String[] EspeceAgeFileNames = new String[]{"table_sol_age_1_.csv","table_sol_age_2_.csv","table_sol_age_3_.csv","table_sol_age_4_.csv",
//    								"table_sol_age_5_.csv","table_sol_age_6_.csv","table_sol_age_7_.csv","table_sol_age_8_.csv",
//    								"table_sol_age_9_.csv","table_sol_age_10_.csv","table_sol_age_11_.csv","table_sol_age_12_.csv",
//    								"table_ple_age_1_.csv","table_ple_age_2_.csv","table_ple_age_3_.csv","table_ple_age_4_.csv",
//    								"table_ple_age_5_.csv","table_ple_age_6_.csv","table_ple_age_7_.csv","table_ple_age_8_.csv",
//    								"table_ple_age_9_.csv","table_ple_age_10_.csv","table_ple_age_11_.csv","table_ple_age_12_.csv",
//    								"table_cod_age_1_.csv","table_cod_age_2_.csv","table_cod_age_3_.csv","table_cod_age_4_.csv",
//    								"table_cod_age_5_.csv","table_cod_age_6_.csv","table_sce_BS_age_1_.csv","table_sce_BS_age_2_.csv",
//    								"table_sce_BS_age_3_.csv","table_sce_BS_age_4_.csv","table_sce_BS_age_5_.csv","table_sce_BS_age_6_.csv",
//    								"table_sce_PE_age_1_.csv","table_sce_PE_age_2_.csv","table_sce_PE_age_3_.csv","table_sce_PE_age_4_.csv",
//    								"table_sce_PE_age_5_.csv","table_sce_PE_age_6_.csv","table_mur2_age_0_.csv","table_mur2_age_1_.csv",
//    								"table_mur2_age_2_.csv","table_mur2_age_3_.csv","table_mur2_age_4_.csv";"table_sqz_age_1_.csv"};


    	//Zone isis 
    	String[] zoneisis = {"Poly1","Poly2","Poly3","Poly4","Poly5","Poly6","Poly7","Poly9","Poly10","Poly11","Poly12","Poly13",
    			"Poly14","Poly16","Poly17","Poly20","Poly21","Poly22","Poly23","Poly24","Poly25","Poly26","Poly28","Poly31","Poly32",
    			"Poly33","Poly35","Poly36","Poly37","Poly38","RedMullet_spawning","Plaice_spawning","Plaice_nurs","Sole_nurs","BS_offshore",
    			"BS_coast"};
    	
    	//On ranges les zones dans l'ordre de isis
		List<Zone> allZone = new ArrayList<Zone>();
		allZone = param_Population.getPopulationZone() ;
		List<Zone> allZoneOrder = new ArrayList<Zone>();
		for(String z : zoneisis){
			for(Zone zone:allZone){
				if(zone.getName().equals(z)){
					allZoneOrder.add(zone);
				}
			}
		}
		
		// map qui associe chaque age a sa matrice correspondante 
		List<PopulationGroup> mesAgesOrder = param_Population.getPopulationGroup();
		CaptAuxAges = new HashMap<PopulationGroup, MatrixND>();
	  
		String cheminfichiercomplet= new String() ;
		for(PopulationGroup age : mesAgesOrder){
			log.info("Zone="+allZoneOrder);
			//Identification du fichier a importer
			String nomFichier = ("table_"+param_nomEspece+"_age_"+(int)age.getAge()+"_.csv");
			cheminfichiercomplet= cheminfichier + nomFichier;
			File caa = new File(cheminfichiercomplet);
			// creation de la matrice generique dates/zones
			matrix = MatrixFactory.getInstance().create("MatDatZone",		
				new List[]{dates,allZoneOrder},
            		new String[]{"Dates","Zones"});
            	log.info("matrice:"+matrix+age);
			//Importation du csv
			matrix.importCSV(new FileReader(caa),new int []{0,0});
			log.info("matrice:"+matrix+age);
			CaptAuxAges.put(age,matrix);
		}		
    }
    
    
    /**
     * La condition qui doit etre vrai pour faire les actions.
     * 
     * @param context la simulation pour lequel on utilise cette regle
     * @param step le pas de temps courant
     * @param metier le metier concerne
     * @return vrai si on souhaite que les actions soit faites
     */
    @Override
    public boolean condition(SimulationContext context, TimeStep step, Metier metier)
            throws Exception {

    	boolean result = false;
        if (step.before(param_beginStep)) {
            result = false;
        } else if (step.after(param_endStep)) {
            result = false;
        } else {
          result = true; 
        }
    
    	return result;
    }

    /**
     * Si la condition est vrai alors cette action est executee avant le pas
     * de temps de la simulation.
     * 
     * @param context la simulation pour lequel on utilise cette regle
     * @param step le pas de temps courant
     * @param metier le metier concerne
     */
    @Override
    public void preAction(SimulationContext context, TimeStep step, Metier metier)
            throws Exception {
        affectation = false;

    }

    /**
     * Si la condition est vrai alors cette action est execute apres le pas
     * de temps de la simulation.
     * 
     * @param context La simulation pour lequel on utilise cette regle
     * @param step le pas de temps courant
     * @param metier le metier concerne
     */
    @Override
    public void postAction(SimulationContext context, TimeStep step, Metier metier)
            throws Exception {
    	   	
        if (!affectation) {
 			//On recupere la popu du context
        	PopulationMonitor popMon = context.getPopulationMonitor();
        	ResultManager resManager = context.getResultManager();
			Population pop = (Population) context.getDB().findByTopiaId(param_Population.getTopiaId());
			//On place cette popu dans une matrice
			MatrixND abondance = popMon.getN(pop);
		    List<PopulationGroup> groups = (List<PopulationGroup>)abondance.getSemantic(0);
		    log.info("abondance ="+abondance);
		    
		    //on soustrait les captures 
		    for (MatrixIterator i = abondance.iterator(); i.next();) {
		    	
		    	Object[] coord = i.getSemanticsCoordinates();
				Zone zone = (Zone) coord[1];
		    	PopulationGroup grp = (PopulationGroup) coord[0];
				
				double valCapture = CaptAuxAges.get(grp).getValue(step,zone);
				double valAbondance = i.getValue();
				double newValeur = valAbondance - valCapture;
				i.setValue(newValeur);
			}
			resManager.addResult(step, pop, abondance);		
			log.info("abondance="+abondance);		     	    
        }
        affectation = true;
	}
}