package rules;

import static org.nuiton.i18n.I18n._;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.math.matrix.MatrixIterator;
import org.nuiton.math.matrix.MatrixND;

import scripts.ResultName;
import scripts.SiMatrix;
import fr.ifremer.isisfish.entities.Metier;
import fr.ifremer.isisfish.entities.MetierSeasonInfo;
import fr.ifremer.isisfish.entities.Population;
import fr.ifremer.isisfish.entities.PopulationGroup;
import fr.ifremer.isisfish.entities.Species;
import fr.ifremer.isisfish.entities.TargetSpecies;
import fr.ifremer.isisfish.rule.AbstractRule;
import fr.ifremer.isisfish.simulator.PopulationMonitor;
import fr.ifremer.isisfish.simulator.SimulationContext;
import fr.ifremer.isisfish.types.Date;
import fr.ifremer.isisfish.util.Doc;

/**
 * Cette methode remplace aussi TailleMinSurvieRejet si propSurvie est > 0
 * 
 * Created: 30 novembre 2006
 *
 * @author anonymous <anonymous@labs.libre-entreprise.org>
 * @version $Revision: 1.1 $
 *
 * Last update: $Date: 2007-01-24 18:25:34 $
 * by : $Camille de la Vega $
 */
public class Ogive_de_Trie extends AbstractRule {

    /** to use log facility, just put in your code: log.info("..."); */
    static private Log log = LogFactory.getLog(Ogive_de_Trie.class);

    @Doc(value = "Begin date")
    public Date param_beginDate = new Date(0);

    @Doc(value = "End date")
    public Date param_endDate = new Date(119);

    @Doc(value = "Affected species")
    public Species param_species = null;

    @Doc(value = "param_Retention_L50")
    public double param_Retention_L50 = 29.4307;

    @Doc(value = "param_Retention_slope")
    public double param_Retention_slope = 2.02485;

    @Doc(value = "Proportion de survie")
    public double param_propSurvie = 0;
    
    public String[] necessaryResult = {
    // put here all necessary result for this rule
    // example: 
    // ResultName.MATRIX_BIOMASS,
    // ResultName.MATRIX_NET_VALUE_OF_LANDINGS_PER_STRATEGY_MET,
    };

    @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() throws Exception {
        return _("l'abondance de poissons captur" +
             " ne seront pas captur" +  " suivant la proportion de survie.");
    }

    /**
      * des valeurs
     * 
     * @param context La simulation pour lequel on utilise cette regle
     */
    @Override
    public void init(SimulationContext context) throws Exception {
    }

    /**
     * @param context
     * @param date
     * @param param_species
     * @param metier
     * @return
     */
///    private boolean isCaptureDate(Date date, Species species, Metier metier) {
///        MetierSeasonInfo info = metier.getMetierSeasonInfo(date.getMonth());
///        TargetSpecies target = info.getSpeciesTargetSpecies(species);

//        boolean result;
//        if (target != null) {
//            result = true;
//        } else {
//            result = false;
//        }

//        return result;
//    }

    /**
     * La condition qui doit etre vrai pour faire les actions
     * 
     * @param context La simulation pour lequel on utilise cette regle
     * @return vrai si on souhaite que les actions soit faites
     */
    @Override
    public boolean condition(SimulationContext context, Date date, Metier metier)
            throws Exception {
        //log.info("Recherche si la taille Minimale s'applique");
        boolean result = true;
        if (date.before(param_beginDate)) {
            result = false;
        } else if (date.after(param_endDate)) {
            result = false;
        } 
        ////else if (isCaptureDate(date, param_species, metier) != true) {
            ////result = false;
        ////}

        log.info("fin de condition TailleMin:" + result);
        return result;

    // fin
    }

    /**
     * Si la condition est vrai alors cette action est execut
          * temps de la simulation.
     * 
     * @param context La simulation pour lequel on utilise cette regle
     */
    @Override
    public void preAction(SimulationContext context, Date date, Metier metier)
            throws Exception {
        // nothing
    }

    /**
     * Si la condition est vrai alors cette action est execut
          * temps de la simulation.
     * @param context La simulation pour lequel on utilise cette regle
     */
    @Override
    public void postAction(SimulationContext context, Date date, Metier metier)
            throws Exception {
        log.info("*$*$*$* TailleMin.actionApres:" + date + " metapop:" +
                param_species + " metier:" + metier);


                    
            // ATTENTION        
            // les captures pour cette metapop ne sont plus du qu'au metier pour qui 
            // l'espece est secondaire: elles sont affectees aux rejets

            //pb : ne se fait pas par metier
            //il faut une matrice pour chaques pas de temps qui stocke les rejets 
            //par metier, par metapop et par classes d'age (comme pour les captures)
            //////
            log.info("deb de affecterCaptureREJETTailleMin");

            PopulationMonitor popMon = context.getPopulationMonitor();
            SiMatrix siMatrix = SiMatrix.getSiMatrix(context);
            List<Population> pops = siMatrix.getPopulations(date);
            for (Population pop : pops) {
                if (pop.getSpecies().equals(param_species)) {
                    ///if (popMon.getDiscard(date, pop) == null) {
                        MatrixND Catch = popMon.getCatch(pop).copy();
                        MatrixND discard = popMon.getCatch(pop).copy();
                        /// MatrixND eff = popMon.getN(pop);
					log.info("metier_selectionnes" + metier.getName());
					List<PopulationGroup> groups = pop.getPopulationGroup();
                        for (PopulationGroup group : groups) {  
                        	   log.info("ICI");                   
                            ///if (metier.getName()=="Langoustinier francais"){ 
 					   double trie = 1/(1+Math.exp(-(group.getLength()-param_Retention_L50)/param_Retention_slope));
 						  ///log.info("trie" + trie);
 						  ///log.info ("longueur" + group.getLength());
 						  ///log.info("rejet" + i.getValue());
 					   log.info("tri" + trie);
 					   double rejet = 1-trie;
 					   log.info("rejet" + rejet);
                		   discard = Catch.mults(rejet);
                		   //log.info("discard" + discard);
                		       ///  log.info("rejet" + i.getValue());
                            //} 
                            ///else if (param_propSurvie > 0) {
                               /// eff.setValue(coordonnees[2], coordonnees[3],
                                ///        eff.getValue(coordonnees[2],
                                  ///      coordonnees[3]) + i.getValue() *
                                  ///      param_propSurvie);
                          //  }
                        }
                        discard.setName(
                                ResultName.MATRIX_DISCARDS_PER_STR_MET_PER_ZONE_POP);
                        log.info("discard" + discard);        
                        popMon.addDiscard(date, pop, discard);
                    //}
                }
            }

            

        //on a affecte une fois cette meta pop au rejet il ne faut pas le refaire

    // fin

    }
}