package rules;



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.io.Writer;

import java.util.List;



import org.codelutin.math.matrix.*;

import fr.ifremer.isisfish.simulator.PopulationMonitor;

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;



/**

 * SurvieRejetClasseLangoustine.java

 *

 * Created: 13 f�vrier 2007

 *

 * @author stephanie MAHEVAS <smahevas@ifremer.fr>

 * @version $Revision: 1.23 $

 *

 * REPRISE DE LA REGLE SURVIEREJETCLASSE Magali V2.3.2

 * Last update: $Date: 2006/11/30 13:56:42 $

 * by : $Author: bpoussin $

 */

public class SurvieRejetClasseLangoustine extends AbstractRule {

    /** to use log facility, just put in your code: log.info("..."); */

    static private Log log = LogFactory.getLog(SurvieRejetClasseLangoustine.class);



    public Date param_beginDate = new Date(0);

    public Date param_endDate = new Date(119);

    public Species param_species = null;


    public double param_propSurvie = 0.3;

    public double param_propRejet56_71=0.96;

    public double param_propRejet71_84=0.75;

    public double param_propRejet84_95=0.28;

    public double param_propRejet95_101=0.7;

    public double param_propRejet101_110=0.4;

    public double param_propRejet110_117=0.1;



    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 _("TODO description rule");

    }



    /**

     * 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 {

        // TODO

    }

    /**

     * @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 = target != null;



        return result;

    }



    /**

     * 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

     */

    /** meme condition que pour taille minimale 

     */

    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;

    }      





    /**

     * 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 {

        // nothing

        // comme dans taille minimale

    }



    /**

     * 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 {

        log.info("*$*$*$* SurvieRejetClasse.actionApres:" + date + " metapop:" + param_species + " metier:" + metier);

        if(isCaptureDate(date, param_species, metier)){    

            log.info("*$*$*$* ok affecte capture inf�?rieure �? TailleMin au rejet");

            // 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 discard = popMon.getCatch(pop).copy();

                        MatrixND eff = popMon.getN(pop);



                        for (MatrixIterator i=discard.iterator(); i.next();) {

                            Object [] coordonnees = i.getSemanticsCoordinates();

                            PopulationGroup group = (PopulationGroup)coordonnees[2];



                            if (group.getLength() >= 56 && group.getLength()<71) {

                                eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+i.getValue()*param_propRejet56_71);

                            }   else if (group.getLength() >=71 && group.getLength()<84){

                                eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+i.getValue()*param_propRejet71_84);

                            }   else if (group.getLength() >=84 && group.getLength() <95){

                                eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+i.getValue()*param_propRejet84_95);

                            }   else if (group.getLength()>=95 && group.getLength()<101){

                                eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+i.getValue()*param_propRejet95_101);

                            }   else if (group.getLength()>=101 && group.getLength()<110){

                                eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+i.getValue()*param_propRejet101_110);

                            }   else if (group.getLength()>=110 && group.getLength()<117){

                                eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+i.getValue()*param_propRejet110_117);

                            }

                            else{ 

                                i.setValue(0);

                            }



                        }

                        discard.setName(ResultName.MATRIX_DISCARDS_PER_STR_MET);

                        popMon.addDiscard(date, pop, discard);

                    }

                }

            }



            log.info("fin de affecterCaptureRejetSurvieClasse");



            //on a affecte une fois cette meta pop au rejet il ne faut pas le refaire

        }

        // fin



        /*







writeln("*$*$*$* SurvieRejetClasse.actionApres:"+p.date+" metapop:"+p.metapop+" metier:"+p.metier);

if(Regle_libUtil.isCaptureDate(p.date,p.metapop, p.metier)){    

  writeln("*$*$*$* ok affecte capture inf��rieure �� TailleMin au rejet");

  // 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)

  //////

writeln("deb de affecterCaptureSURVIEREJETCLASSE");

var suivi = null;





//recherche du suivi pour les pop qui ont une certaine meta pop

for(var i=0; i<suiviePop.size(); i++){

	if(suiviePop.get(i).getPop().getMetaPopulation().equals(metapop)){

		suivi = suiviePop.get(i);

		var populations=suivi.getPop();

    //si on a pas deja creer le rejet on le cree et on en fait un resultat

		var matRejet = suivi.getRejet(date);

		if (matRejet==null){      

			var matRejetBis = MatrixFactory.create(suivi.getCapture());

			var  eff=suivi.getN();

//on encapsule les objets des 4 dimensions de la matrice capture

			for (var iiterateur=matRejetBis.iterator();iiterateur.next();){

				var coordonnees=iiterateur.getSemanticsCoordinates();

				var classe=coordonnees[2];

				if (classe.getLongueur()>=56 && classe.getLongueur()<71){

					iiterateur.setValue(iiterateur.getValue()*(propRejet56_71));

                                        eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+iiterateur.getValue()*proportion);

				}

                                else if (classe.getLongueur()>=71 && classe.getLongueur()<84){

					iiterateur.setValue(iiterateur.getValue()*(propRejet71_84));

                                        eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+iiterateur.getValue()*proportion);

				}

                                else if (classe.getLongueur()>=84 && classe.getLongueur()<95){

					iiterateur.setValue(iiterateur.getValue()*(propRejet84_95));

                                        eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+iiterateur.getValue()*proportion);

				}

                                else if (classe.getLongueur()>=95 && classe.getLongueur()<101){

					iiterateur.setValue(iiterateur.getValue()*(propRejet95_101));

                                        eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+iiterateur.getValue()*proportion);

				}

                                else if (classe.getLongueur()>=101 && classe.getLongueur()<110){

					iiterateur.setValue(iiterateur.getValue()*(propRejet101_110));

                                        eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+iiterateur.getValue()*proportion);

				}

                                else if (classe.getLongueur()>=110 && classe.getLongueur()<117){

					iiterateur.setValue(iiterateur.getValue()*(propRejet110_117));

                                        eff.setValue(coordonnees[2],coordonnees[3],eff.getValue(coordonnees[2],coordonnees[3])+iiterateur.getValue()*proportion);

				}

				else{

					iiterateur.setValue(0);

				}

			}

			matRejetBis.setName('Rejet par metier');		

			suivi.addRejet(date,matRejetBis);

		}	

	}

}

writeln("fin de affecterCaptureSURVIEREJETCLASSE");

  //on a affecte une fois cette meta pop au rejet il ne faut pas le refaire

}

return p.gestionMetier;

         */

    }

}

