package rules;

import static org.codelutin.i18n.I18n.n_;
import static org.codelutin.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.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.codelutin.math.matrix.*;

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.datastore.RegionStorage;
import fr.ifremer.isisfish.entities.*;
import fr.ifremer.isisfish.rule.AbstractRule;

import fr.ifremer.isisfish.util.Doc; // pour pouvoir afficher une aide contextuelle (BUG#1605)

/**
 * Cantonnement.java
 *
 * Created: 30 novembre 2006
 *
 * @author anonymous <anonymous@labs.libre-entreprise.org>
 * @version $Revision: 1.2 $
 *
 * Last update: $Date: 2007-01-24 18:25:34 $
 * by : $Author: bpoussin $
 */
public class CantonnementPreSimu extends AbstractRule {

    /** to use log facility, just put in your code: log.info("..."); */
    static private Log log = LogFactory.getLog(CantonnementPreSimu.class);

    @Doc(value="do the doc of param zone")
    public Zone param_zone = null;
    @Doc(value="do the doc of param gear")
    public Gear param_gear = null;
    @Doc(value="do the doc of param enginSelective")
    public boolean param_enginSelective = true;
    @Doc(value="do the doc of param beginMonth")
    public Month param_beginMonth = Month.JANUARY;
    @Doc(value="do the doc of param endMonth")
    public Month param_endMonth = Month.DECEMBER;

    protected Map<Month, MatrixND> tableNonActivite = new HashMap<Month, MatrixND>();
    protected boolean affectNonActivite = false;
    
    public String [] necessaryResult = {
    // put here all necessary result for this rule
    // example: 
    // ResultName.MATRIX_BIOMASS,
    // ResultName.MATRIX_NET_VALUE_OF_LANDINGS_PER_STRATEGY_MET,
            ResultName.MATRIX_NO_ACTIVITY,
    };

    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 {
        return _("Cantonnement: can be used to Cantonnement with gear if you put gear in parameter");
    }
 
    private void reportNonActivite(SimulationContext context,
            List<Strategy> listestrategies, List<Metier> metiers,
            Metier metier, List<Month> chomageMonth) {
        for(Strategy strategy : listestrategies) {
            SetOfVessels SetOfBateau = strategy.getSetOfVessels();
            EffortDescription effort = SetOfBateau.getPossibleMetiers(metier);
            if (effort != null){
                for (Month month : chomageMonth) {
                    StrategyMonthInfo InfoMois = strategy.getStrategyMonthInfo(month);
//this.p.tableNonActivite=Regle_action_lib.reportNonActivite(this.p.tableNonActivite, listestrategies.get(i), metier, mois, InfoMois.getProportionMetier(metier));                                                 
                     
                    log.info("debut reportNonActivite");
                    // on regarde si on a déjà une entrée pour le mois courant
                    MatrixND matNonActiviteMois=tableNonActivite.get(month);
                    if (matNonActiviteMois == null){
                        matNonActiviteMois = MatrixFactory.getInstance().create(
                                ResultName.MATRIX_NO_ACTIVITY,
                                new List[]{listestrategies, metiers},
                                new String[]{n_("Strategies"), n_("Metiers")});
                        tableNonActivite.put(month, matNonActiviteMois);
                    }

                    matNonActiviteMois.setValue(strategy, metier, InfoMois.getProportionMetier(metier));
                    log.info("fin reportNonActivite");
                     
                    InfoMois.setProportionMetier(metier, 0);
                    MetierMonitor metierMon = context.getMetierMonitor();
                    metierMon.isLimited(metier, month);
                    metierMon.addforbiddenMetier(metier, month);
                }
            }
        }
    }
    
    /**
     * Appelé au démarrage de la simulation, cette méthode permet d'initialiser
     * des valeurs
     * @param simulation La simulation pour lequel on utilise cette regle
     */
    public void init(SimulationContext context) throws Exception {
        SiMatrix siMatrix = SiMatrix.getSiMatrix(context);
        
//        MetierDAO metierDao = IsisFishDAOHelper.getMetierDAO(context.getDB());
        ZoneDAO zoneDao = IsisFishDAOHelper.getZoneDAO(context.getDB());
        MetierSeasonInfoDAO metierSeasonInfoDao = IsisFishDAOHelper.getMetierSeasonInfoDAO(context.getDB());
        
//        List<Metier> metiers = metierDao.findAll();
        List<Month> SaisonFermee = Month.getMonths(param_beginMonth, param_endMonth);
        List<Cell> maillefermee = param_zone.getCell();
        
        FisheryRegion region = RegionStorage.getFisheryRegion(context.getDB());
        List<Strategy> listestrategies= region.getStrategy();
        List<Metier> metiers = region.getMetier();

//        var SaisonFermee= new Packages.fr.ifremer.nodb.Saison(moisDeb,moisFin);


        for (Metier metier : metiers) {
            log.info("metier examiné " + metier.getName());
            if (param_gear != null && !metier.getGear().equals(param_gear)){
                log.info("l engin du métier n est pas concerné");
            }
            else {
                log.info("l engin du métier est bien concerné");
                List<MetierSeasonInfo> saisons = metier.getMetierSeasonInfo();
                for (MetierSeasonInfo saisonmetier: saisons){
                    int inter = siMatrix.nbCellInter(saisonmetier.getZone(), param_zone);
                    if (inter != 0){
                        List<Cell> MailleMetier = siMatrix.getCells(saisonmetier.getZone());
                        
                        // les mailles qui reste dans la zone metier
                        List<Cell> newCellMetier = new ArrayList<Cell>(MailleMetier);
                        newCellMetier.removeAll(maillefermee);
                        
                        List<Month> saison=saisonmetier.getMonths();
                        if (saison.containsAll(SaisonFermee)){
                            log.info("il y a bien intersection entre la zone métier et le cantonnement pour la saison "+saison.toString());
                            // calcule de la zone restante:     
                            boolean ToutFerme=false;
                            boolean DebInclus=saison.contains(param_beginMonth);
                            boolean FinInclus=saison.contains(param_endMonth);
                            
                            //creation du nouveau secteur de metier
                            Zone secteurResult = zoneDao.create();
                            secteurResult.setName("MetaCantonnement-" + metier.getName() + "-" + saison.toString());
                            secteurResult.setComment("Secteur créé durant la simulation.");                            
                            // on ajoute les mailles restants de la zone metier dans la zone resultante
                            secteurResult.addAllCell(newCellMetier);

                            
                            // test pour savoir si toute la zone de pratique du metier
                            // (reunion de toutes les zones metiers  de metier a date)
                            // est totalement incluse dans la zone Cantonnement                            
                            if (newCellMetier.size() != 0){ //le cas intersection.length==mailleMetier est dans condition
                              // si toute la zone de pratique du metier n'est pas incluse dans zone Cantonnement            
                                ToutFerme=false;
                            } else {
                                log.info("Toute la zone metier est ferme");
                                ToutFerme=true;
                            }

//        1er cas: la saison métier est identique (ou totalement incluse dans la saison fermée, dans ce cas là, on change juste
//        le secteur
                            if (SaisonFermee.containsAll(saison)){
                                log.info("toute la saison metier est incluse dans la saison de fermeture");
                                //si tout est fermé, on met le metier au chômage
                                
                                if (ToutFerme==true) {
                                    log.info ("toute la zone est fermée, le metier passe donc à chômage pour cette saison");
                                    reportNonActivite(context, listestrategies, metiers, metier, saison);

                                } else {                                    
                                    log.info("tout n'est pas fermée, le secteur de pêche devient " + secteurResult);
                                    for (Month month : SaisonFermee){
                                        metier.getMetierSeasonInfo(month).clearZone();
                                        metier.getMetierSeasonInfo(month).addZone(secteurResult);
                                    }
                                }
                            

//        2ème cas de figure: moisDeb est inclus mais pas moisFin (ou alors c'est le dernier mois)
                            if  (DebInclus && ((!FinInclus) || param_endMonth.equals(saison.get(saison.size()-1)))) {
                                log.info ("il y a intersection de la saison de fermeture avec la saison métier de " + param_beginMonth + " à " + saison.get(saison.size()-1));
                                //si tout est fermé on met les proportions à 0 pour les mois fermes
                                 if(ToutFerme==true){
                                    log.info ("toute la zone métier est fermée");
                                    List<Month> chomageMonth = new ArrayList<Month>(SaisonFermee);
                                    chomageMonth.retainAll(saison);
                                    log.info ("de "+chomageMonth.get(0)+" a "+ chomageMonth.get(chomageMonth.size()-1)+ ", le metier est donc mis au chomage");
                                    
                                    reportNonActivite(context, listestrategies, metiers, metier, chomageMonth);
                                } else {
                                    //on commence par crée les nouvelles saisons
//                                    var NouvelleSaison2= new Packages.fr.ifremer.nodb.Saison(moisDeb,saison.getLastMois().getNumMois());        
//                                    var NouvelleSaison1= new Packages.fr.ifremer.nodb.Saison(saison.getFirstMois().getNumMois(),moisDeb-1);
                                    saisonmetier.setLastMonth(param_beginMonth.previous());
                                    //on crée un nouveau  infoSaisonMetier
                                    MetierSeasonInfo NouvelInfoSaison= metierSeasonInfoDao.create();
                                    NouvelInfoSaison.setMetier(metier);
                                    NouvelInfoSaison.setFirstMonth(param_beginMonth);
                                    NouvelInfoSaison.setLastMonth(saison.get(saison.size()-1));
                                    NouvelInfoSaison.addZone(secteurResult);
                                    NouvelInfoSaison.setComment("saison crée pendant la simulation") ;
                                    
                                    metier.addMetierSeasonInfo(NouvelInfoSaison);
                                    log.info ("de "+saison.get(0)+" à "+param_beginMonth.previous()+" le metier peche en "+saisonmetier.getZone());
                                    log.info ("de "+param_beginMonth+" à "+saison.get(saison.size()-1)+" le metier peche en "+secteurResult);
                                }
                            }
//        3ème cas de figure: moisFin est inclus mais pas moisDeb (ou alors il est égal au premier mois)
                            else if (((!DebInclus) || param_beginMonth.equals(saison.get(0))) && FinInclus) {
                                log.info ("il y a intersection de la saison de fermeture avec la saison métier de "+param_beginMonth+" à "+saison.get(saison.size()-1));
                                //si tout est fermé on met les proportions à 0 pour les mois fermes
                                if (ToutFerme==true){
                                    log.info ("toute la zone est fermee");
                                    List<Month> chomageMonth = new ArrayList<Month>(SaisonFermee);
                                    chomageMonth.retainAll(saison);
                                    reportNonActivite(context, listestrategies, metiers, metier, chomageMonth);
                                }
                                else {
                                    //on commence par crée les nouvelles saisons
                                    saisonmetier.setFirstMonth(param_endMonth.next());
                                    //on crée un nouveau  infoSaisonMetier
                                    MetierSeasonInfo NouvelInfoSaison= metierSeasonInfoDao.create();
                                    NouvelInfoSaison.setMetier(metier);
                                    NouvelInfoSaison.setFirstMonth(saison.get(0));
                                    NouvelInfoSaison.setLastMonth(param_endMonth);
                                    NouvelInfoSaison.addZone(secteurResult);
                                    NouvelInfoSaison.setComment("saison crée pendant la simulation") ;
                                    
                                    metier.addMetierSeasonInfo(NouvelInfoSaison);                                    
                                    log.info ("de "+saison.get(0)+" à "+param_endMonth+" le metier peche en "+secteurResult);
                                    log.info ("de "+param_endMonth.next()+" à "+saison.get(saison.size()-1)+" le metier peche en "+saisonmetier.getZone());
                                }
                            }

//        dernier cas de figure: les deux sont inclus et sont différents des bornes
                            else {
                                //si tout est fermé on met les proportions à 0 pour les mois fermes
                                if (ToutFerme==true){
                                    log.info("toute la zone métier est fermée");
                                    reportNonActivite(context, listestrategies, metiers, metier, SaisonFermee);
                                }
                                else {
                                    //on commence par crée les nouvelles saisons
//                                    var NouvelleSaison1= new Packages.fr.ifremer.nodb.Saison(saison.getFirstMois().getNumMois(),moisDeb-1);     
//                                    var NouvelleSaison2= new Packages.fr.ifremer.nodb.Saison(moisDeb,moisFin);
//                                    var NouvelleSaison3=new Packages.fr.ifremer.nodb.Saison(moisFin+1,saison.getLastMois().getNumMois());
//                                    
                                    saisonmetier.setFirstMonth(param_beginMonth.previous());
                                    //on crée un nouveau  infoSaisonMetier
                                    MetierSeasonInfo NouvelInfoSaison = metierSeasonInfoDao.create();
                                    NouvelInfoSaison.setMetier(metier);
                                    NouvelInfoSaison.setFirstMonth(param_beginMonth);
                                    NouvelInfoSaison.setLastMonth(param_endMonth);
                                    NouvelInfoSaison.addZone(secteurResult);
                                    NouvelInfoSaison.setComment("saison crée pendant la simulation") ;                                    
                                    metier.addMetierSeasonInfo(NouvelInfoSaison);

                                    //on crée un nouveau  infoSaisonMetier
                                    MetierSeasonInfo NouvelInfoSaison2 = metierSeasonInfoDao.create();
                                    NouvelInfoSaison2.setMetier(metier);
                                    NouvelInfoSaison2.setFirstMonth(param_endMonth.next());
                                    NouvelInfoSaison2.setLastMonth(saison.get(saison.size()-1));
                                    NouvelInfoSaison2.setZone(saisonmetier.getZone());
                                    NouvelInfoSaison2.setComment("saison crée pendant la simulation") ;                                    
                                    metier.addMetierSeasonInfo(NouvelInfoSaison2);
                                    
                                    log.info ("de "+saison.get(0)+" à "+param_beginMonth.previous()+" le metier peche en "+saisonmetier.getZone());
                                    log.info ("de "+param_beginMonth+" à "+param_endMonth+" le metier peche en "+secteurResult);
                                    log.info ("de "+param_endMonth.next()+" à "+saison.get(saison.size()-1)+" le metier peche en "+saisonmetier.getZone());
                                }
                            }
                        }
                    }
                }
            }
        }

        /*
        this.p = new Object();
        this.p.paramRegle = this.param;
        this.p.tableNonActivite=new Packages.java.util.HashMap();
        this.p.affectNonActivite=false;


        var enginselectif=this.param.getValue("EnginSelective");//entrez le nom de l'engin fermée ou non si pas de sélection sur engin
        var moisDeb=this.param.getValue("moisDeb"); //entrez le mois debut de fermeture
        var moisFin=this.param.getValue("moisFin");//entrez le mois de fin de fermeture



        var ZoneFermee=this.param.getValue("zone");
        writeln("bla");
        if (enginselectif) {var EnginInterdit=this.param.getValue("engin");} else {var EnginInterdit=MetierFactory.findByNom("nonActivite").getEngin();}
        var RegionSimu=ZoneFermee.getRegion();
        var ListeMetiers=MetierFactory.findAllByRegion(RegionSimu);
        var MoisDeb=new Packages.fr.ifremer.nodb.Mois(moisDeb);
        var MoisFin=new Packages.fr.ifremer.nodb.Mois(moisFin);
        var SaisonFermee= new Packages.fr.ifremer.nodb.Saison(moisDeb,moisFin);



        for (var imetier = ListeMetiers.iterator() ; imetier.hasNext();){
            var metier=imetier.next();
            writeln ("metier examiné "+metier.getNom());
            if ((!metier.getEngin().equals(EnginInterdit)) && enginselectif){
                writeln("l engin du métier n est pas concerné");
            }
            else {
                writeln("l engin du métier est bien concerné");
                var ListeSaisons = metier.getInfoSaison();
                for (var isaisonmetier = ListeSaisons.iterator() ; isaisonmetier.hasNext();){
                    var saisonmetier=isaisonmetier.next();
                    var maillefermee=ZoneFermee.getMaille();
                    var MailleMetier=saisonmetier.getSecteur().getMaille().copy();
                    MailleMetier.retainAll(maillefermee);
                    
                    if (MailleMetier.size()!=0){
                        MailleMetier=saisonmetier.getSecteur().getMaille().copy();
                        var saison=saisonmetier.getSaison();
                        if (saison.contains(SaisonFermee)){
                            writeln("il y a bien intersection entre la zone métier et le cantonnement pour la saison "+saison.toString());
//         calcule de la zone restante:     
                            var ToutFerme=false;
                            var DebInclus=saison.contains(MoisDeb);
                            var FinInclus=saison.contains(MoisFin);
                            MailleMetier.removeAll(maillefermee);
                            writeln("inter maille:"+MailleMetier.size());
                            // test pour savoir si toute la zone de pratique du metier
                            // (reunion de toutes les zones metiers  de metier a date)
                            // est totalement incluse dans la zone Cantonnement
                            
                            if (MailleMetier.size() != 0){ //le cas intersection.length==mailleMetier est dans condition
                              // si toute la zone de pratique du metier n'est pas incluse dans zone Cantonnement
            
                                ToutFerme=false;

                                //creation du nouveau secteur de metier
                                //on vérifie si le secteur a pas déjà été modifié par une autre règle afin de ne pas avoir de problème d'ID
                                var ListeSecteur=MetaSecteurFactory.findAllByKey("MetaCantonnement-"+metier.getNom()+saison.toString(), RegionSimu);
                                if (ListeSecteur.size()!=0){
                                    var secteurResult = MetaSecteurFactory.create(saisonmetier.getSecteur().getNom()+"Modif", RegionSimu, "Secteur créé durant la simulation.");
                                }
                                else{
                                    var secteurResult = MetaSecteurFactory.create("MetaCantonnement-"+metier.getNom()+saison.toString(),RegionSimu, "Secteur créé durant la simulation.");
                                }
                                
                                writeln("nouveau secteur cree:"+secteurResult);
                                var zonesMetier = saisonmetier.getSecteur().getAllSecteur();
                                writeln("zonesMetier:"+zonesMetier);
                                writeln("zonesMetier.size:"+zonesMetier.size());

                                for(var i=0; i<zonesMetier.size(); i++){
                                    var zonemet = zonesMetier.get(i);
                                    writeln("zonemet:"+zonemet);
                                    // intersection entre la zeme zone metier a date et zone de Cantonnement
                                    var listemailleszonemetier = zonemet.getMaille().copy();
                                    var nbMailleZoneMetier = listemailleszonemetier.size();
                                    writeln("maille metier:"+listemailleszonemetier);
                                    writeln("maille Cantonnement:"+maillefermee);
                                    listemailleszonemetier.removeAll(maillefermee);
                                    if(0==listemailleszonemetier.size()){
                                        //si completement inclus on le supprime
                                        //donc on ne le met pas dans le nouveau
                                        writeln("on supprime la zone"+zonemet);
                                    }
                                    else if (listemailleszonemetier.size() != nbMailleZoneMetier) {
                                        // si la zone metier n'est pas totalement incluse dans zone de Cantonnement
                                        // on reduit  la zeme zone metier de cette intersection
                                        // pas de modif de la matrice de proportion strmet
                                        writeln("on cree une nouvelle zone a partir de:"+zonemet+" avec "+listemailleszonemetier);
                                        var simpleSecteur = SecteurSimpleFactory.create("Cantonnement-"+metier.getNom()+"-"+zonemet+saison.toString(), RegionSimu, "Secteur creer durant la simulation.");
                                        simpleSecteur.addAllMaille(listemailleszonemetier);
                                        secteurResult.addSecteur(simpleSecteur);
                                        writeln("apres addSecteur");  
                                    }
                                    else {
                                        //sinon on le met dans le nouveau
                                        writeln("On remet tel quelle la zone:"+zonemet);
                                        secteurResult.addSecteur(zonemet);
                                    }
                                }// fin du for sur les zone metier de la zone de pratique du metier
                            }  
            
                            else {
                                var secteurResult=saisonmetier.getSecteur().getAllSecteur();
                                writeln("Toute la zone metier est ferme");
                                ToutFerme=true;
                            }

//        1er cas: la saison métier est identique (ou totalement incluse dans la saison fermée, dans ce cas là, on change juste
//        le secteur
                            if (SaisonFermee.toListMois().containsAll(saison.toListMois())){
                                writeln("toute la saison metier est incluse dans la saison de fermeture");
                                //si tout est fermé, on met le metier au chômage
                                
                                if (ToutFerme==true){
                                    writeln ("toute la zone est fermée, le metier passe donc à chômage pour cette saison");
                                    var listestrategies=StrategyFactory.findAllByRegion(RegionSimu);
                                    var ListeMois=saison.toListMois();
                                    for(var i=0; i<listestrategies.size(); i++){
                                        var SetOfBateau=listestrategies.get(i).getSetOfVessels();
                                        var MetiersPosibles=SetOfBateau.getMetiers();
                                        if (MetiersPosibles.contains(metier)){
                                            for (imois=ListeMois.iterator();imois.hasNext();){
                                                var mois=imois.next();
                                                var InfoMois=listestrategies.get(i).getStrategyMonthInfo(mois);
                                                //this.p.tableNonActivite=Regle_action_lib.reportNonActivite(this.p.tableNonActivite, listestrategies.get(i), metier, mois, InfoMois.getProportionMetier(metier));
                                                 
                                                 
                                                 
writeln("debut reportNonActivite");
//on regarde si on a déjà une entrée pour le mois courant
var matNonActiviteMois=table.get(mois);
var nonactivite=matNonActiviteMois!=null;

if (!nonactivite){
    matNonActiviteMois=MatrixFactory.create("nonActivite",new Array(SiMatrice.getListStrategies(),SiMatrice.getListMetiers())
    ,new Array("Strategies", "Metiers"));
    table.put(mois,matNonActiviteMois);
}

matNonActiviteMois.setValue(strategie,metier,proportion);
writeln("fin reportNonActivite");
                                                 
                                                  
                                                  
                                                InfoMois.setProportionMetier(metier,new Packages.java.lang.Float(0));
                                                MetiersInterditsPresimu.put(new Chaine(metier.getNom()+"-"+mois.getNumMois()),true);
                                            }
                                        }
                                    }
                                }
                                else {
                                    writeln("tout n'est pas fermée, le secteur de pêche devient "+secteurResult);
                                    var ListeMois=SaisonFermee.toListMois();
                                    for (imois=ListeMois.iterator();imois.hasNext();){
                                        mois=imois.next();
                                        metier.setSecteurMois(secteurResult, mois);
                                    }
                                }
                            }

//        2ème cas de figure: moisDeb est inclus mais pas moisFin (ou alors c'est le dernier mois)
                            else if (DebInclus && ((!FinInclus) || moisFin==saison.getLastMois().getNumMois())){
                                writeln ("il y a intersection de la saison de fermeture avec la saison métier de "+moisDeb+" à "+saison.getLastMois().getNumMois());
                                //si tout est fermé on met les proportions à 0 pour les mois fermes
                                if (ToutFerme==true){
                                    writeln ("toute la zone métier est fermée");
                                    var listestrategies=StrategyFactory.findAllByRegion(RegionSimu);
                                    var ListeMois=SaisonFermee.toListMois().retainAll(saison.toListMois());
                                    writeln ("de "+ListeMois.get(0)+" a "+ ListeMois.get(ListeMois.size())+ ", le metier est donc mis au chomage");
                                    for(var i=0; i<listestrategies.size(); i++){
                                        var SetOfBateau=listestrategies.get(i).getSetOfVessels();
                                        var MetiersPosibles=SetOfBateau.getMetiers();
                                        if (MetiersPosibles.contains(metier)){
                                            for (imois=ListeMois.iterator();imois.hasNext();){
                                                var mois=imois.next();
                                                var InfoMois=listestrategies.get(i).getStrategyMonthInfo(mois);
                                                //this.p.tableNonActivite=Regle_action_lib.reportNonActivite(this.p.tableNonActivite, listestrategies.get(i), metier, mois, InfoMois.getProportionMetier(metier));
                                                 
                                                 
                                                 
writeln("debut reportNonActivite");
//on regarde si on a déjà une entrée pour le mois courant
var matNonActiviteMois=table.get(mois);
var nonactivite=matNonActiviteMois!=null;

if (!nonactivite){
    matNonActiviteMois=MatrixFactory.create("nonActivite",new Array(SiMatrice.getListStrategies(),SiMatrice.getListMetiers())
    ,new Array("Strategies", "Metiers"));
    table.put(mois,matNonActiviteMois);
}

matNonActiviteMois.setValue(strategie,metier,proportion);
writeln("fin reportNonActivite");
                                                 
                                                 
                                                 
                                                 
                                                InfoMois.setProportionMetier(metier,new Packages.java.lang.Float(0));
                                                MetiersInterditsPresimu.put(new Chaine(metier.getNom()+"-"+mois.getNumMois()),true);
                                            }
                                        }
                                    }
                                }
                                else {
                                    //on commence par crée les nouvelles saisons
                                    var NouvelleSaison2= new Packages.fr.ifremer.nodb.Saison(moisDeb,saison.getLastMois().getNumMois());        
                                    var NouvelleSaison1= new Packages.fr.ifremer.nodb.Saison(saison.getFirstMois().getNumMois(),moisDeb-1);
                                    saisonmetier.setSaison(NouvelleSaison1);        
                                    //on crée un nouveau  infoSaisonMetier
                                    var NouvelInfoSaison=InfoSaisonMetierFactory.create(metier, NouvelleSaison2, secteurResult, "saison crée pendant la simulation") ;
                                    metier.addInfoSaison(NouvelInfoSaison);
                                    writeln ("de "+saison.getFirstMois().getNumMois()+" à "+moisDeb-1+" le metier peche en "+saisonmetier.getSecteur());
                                    writeln ("de "+moisDeb+" à "+saison.getLastMois().getNumMois()+" le metier peche en "+secteurResult);
                                }
                            }
//        3ème cas de figure: moisFin est inclus mais pas moisDeb (ou alors il est égal au premier mois)
                            else if (((!DebInclus) || moisDeb==saison.getFirstMois().getNumMois()) && FinInclus){
                                writeln ("il y a intersection de la saison de fermeture avec la saison métier de "+moisDeb+" à "+saison.getLastMois().getNumMois());
                                //si tout est fermé on met les proportions à 0 pour les mois fermes
                                if (ToutFerme==true){
                                    writeln ("toute la zone est fermee");
                                    var listestrategies=StrategyFactory.findAllByRegion(RegionSimu);
                                    var ListeMois=SaisonFermee.toListMois().retainAll(saison.toListMois());
                                    writeln ("de "+ListeMois.get(0)+" a "+ ListeMois.get(ListeMois.size())+ ", le metier est donc mis au chomage");
                                    for(var i=0; i<listestrategies.size(); i++){
                                        var SetOfBateau=listestrategies.get(i).getSetOfVessels();
                                        var MetiersPosibles=SetOfBateau.getMetiers();
                                        if (MetiersPosibles.contains(metier) ){
                                            for (imois=ListeMois.iterator();imois.hasNext();){
                                                var mois=imois.next();
                                                var InfoMois=listestrategies.get(i).getStrategyMonthInfo(mois);
                                                //this.p.tableNonActivite=Regle_action_lib.reportNonActivite(this.p.tableNonActivite, listestrategies.get(i), metier, mois, InfoMois.getProportionMetier(metier));
                                                
                                                
writeln("debut reportNonActivite");
//on regarde si on a déjà une entrée pour le mois courant
var matNonActiviteMois=table.get(mois);
var nonactivite=matNonActiviteMois!=null;

if (!nonactivite){
    matNonActiviteMois=MatrixFactory.create("nonActivite",new Array(SiMatrice.getListStrategies(),SiMatrice.getListMetiers())
    ,new Array("Strategies", "Metiers"));
    table.put(mois,matNonActiviteMois);
}

matNonActiviteMois.setValue(strategie,metier,proportion);
writeln("fin reportNonActivite");                                                
                                                
                                                
                                                
                                                
                                                InfoMois.setProportionMetier(metier,new Packages.java.lang.Float(0));
                                                MetiersInterditsPresimu.put(new Chaine(metier.getNom()+"-"+mois.getNumMois()),true);
                                            }
                                        }
                                    }
                                }
                                else {
                                    //on commence par crée les nouvelles saisons 
                                    var NouvelleSaison1= new Packages.fr.ifremer.nodb.Saison(saison.getFirstMois().getNumMois(),moisFin);       
                                    var NouvelleSaison2= new Packages.fr.ifremer.nodb.Saison(moisFin+1,saison.getLastMois.getNumMois());
                                    saisonmetier.setSaison(NouvelleSaison2);        
                                    //on crée un nouveau  infoSaisonMetier
                                    var NouvelInfoSaison=InfoSaisonMetierFactory.create(metier, NouvelleSaison1, secteurResult, "saison crée pendant la simulation") ;
                                    metier.addInfoSaison(NouvelInfoSaison);
                                    writeln ("de "+saison.getFirstMois().getNumMois()+" à "+moisFin+" le metier peche en "+secteurResult);
                                    writeln ("de "+moisFin+1+" à "+saison.getLastMois().getNumMois()+" le metier peche en "+saisonmetier.getSecteur());
                                }
                            }

//        dernier cas de figure: les deux sont inclus et sont différents des bornes
                            else {
                                //si tout est fermé on met les proportions à 0 pour les mois fermes
                                if (ToutFerme==true){
                                    writeln("toute la zone métier est fermée");
                                    var listestrategies=StrategyFactory.findAllByRegion(metier.getRegion());
                                    var ListeMois=SaisonFermee.toListMois();
                                    writeln("le métier passe à chômage de "+moisDeb+" à "+moidFin);
                                    for(var i=0; i<listestrategies.size(); i++){
                                        var SetOfBateau=listestrategies.get(i).getSetOfVessels();
                                        var MetiersPosibles=SetOfBateau.getMetiers();
                                        if (MetiersPosibles.contains(metier) ){
                                            for (imois=ListeMois.iterator();imois.hasNext();){
                                                var mois=imois.next();
                                                var InfoMois=listestrategies.get(i).getStrategyMonthInfo(mois);
                                                //this.p.tableNonActivite=Regle_action_lib.reportNonActivite(this.p.tableNonActivite, listestrategies.get(i), metier, mois, InfoMois.getProportionMetier(metier));
                                                
                                                
writeln("debut reportNonActivite");
//on regarde si on a déjà une entrée pour le mois courant
var matNonActiviteMois=table.get(mois);
var nonactivite=matNonActiviteMois!=null;

if (!nonactivite){
    matNonActiviteMois=MatrixFactory.create("nonActivite",new Array(SiMatrice.getListStrategies(),SiMatrice.getListMetiers())
    ,new Array("Strategies", "Metiers"));
    table.put(mois,matNonActiviteMois);
}

matNonActiviteMois.setValue(strategie,metier,proportion);
writeln("fin reportNonActivite");                                                
                                                
                                                
                                                
                                                InfoMois.setProportionMetier(metier,new Packages.java.lang.Float(0));
                                                MetiersInterditsPresimu.put(new Chaine(metier.getNom()+"-"+mois.getNumMois()),true);
                                            }
                                        }
                                    }
                                }
                                else {
                                    //on commence par crée les nouvelles saisons
                                    var NouvelleSaison1= new Packages.fr.ifremer.nodb.Saison(saison.getFirstMois().getNumMois(),moisDeb-1);     
                                    var NouvelleSaison2= new Packages.fr.ifremer.nodb.Saison(moisDeb,moisFin);
                                    var NouvelleSaison3=new Packages.fr.ifremer.nodb.Saison(moisFin+1,saison.getLastMois().getNumMois());
                                    saisonmetier.setSaison(NouvelleSaison1);        
                                    //on crée 2 nouveau  infoSaisonMetier
                                    var NouvelInfoSaison2=InfoSaisonMetierFactory.create(metier, NouvelleSaison2, secteurResult, "saison crée pendant la simulation") ;
                                    var NouvelInfoSaison3=InfoSaisonMetierFactory.create(metier, NouvelleSaison3, saisonmetier.getSecteur(), "saison crée pendant la simulation") ;
                                    metier.addInfoSaison(NouvelInfoSaison2);
                                    metier.addInfoSaison(NouvelInfoSaison3);                            
                                    writeln ("de "+saison.getFirstMois().getNumMois()+" à "+(moisDeb-1)+" le metier peche en "+saisonmetier.getSecteur());
                                    writeln ("de "+moisDeb+" à "+moisFin+" le metier peche en "+secteurResult);
                                    writeln ("de "+(moisFin+1)+" à "+saison.getLastMois().getNumMois()+" le metier peche en "+saisonmetier.getSecteur());
                                }
                            }
                        }
                    }
                }
            }
        }
        */
        
  }  

    /**
     * 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 {
     
     	boolean result = false;

        MatrixND mat = tableNonActivite.get(date.getMonth());
        
if (mat != null && affectNonActivite == false) {
            result = true;
        }

        return result;

 		
        // fin

        /*
        var mat=p.tableNonActivite.get(p.date.getMois());
        writeln(p.affectNonActivite);

        if(oldValue != undefined)
          return oldValue;
        else if (mat!=null && p.affectNonActivite==false){
            return true;
        }
        else {return false;}        
        */
    }
 
    /**
     * Si la condition est vrai alors cette action est executée 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 {
        // on ne doit le faire qu'une seul fois quelque soit le nombre de metier
        affectNonActivite=true;
        MatrixND mat = tableNonActivite.get(date.getMonth());
        
        MetierMonitor metierMon = context.getMetierMonitor();
        MatrixND noActivity = metierMon.getNoActivity(date);

        if (noActivity == null){
            metierMon.setNoActivity(date, mat.copy());
        }
        else{
            noActivity = noActivity.add(mat);
        }
        
    /*
     p.affectNonActivite=true;
var mat=p.tableNonActivite.get(p.date.getMois());
var matNonActivite=nonActivite.get(p.date);
var nonactivite=matNonActivite!=null;
if (!nonactivite){
    nonActivite.put(p.date,mat);
}
else{
    matNonActivite=matNonActivite.add(mat);
}
return p.gestionMetier;

     */
    }
 
    /**
     * Si la condition est vrai alors cette action est executée 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 {
        affectNonActivite = false;
        
        /*
         p.affectNonActivite=false;
return p.gestionMetier;
         */
    }

}
