/*
 * Copyright (C) 2018 chatellier
 *
 * 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 3 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, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 */
package optimizations;

import java.util.List;

import org.nuiton.math.matrix.*;
import resultinfos.*;

import fr.ifremer.isisfish.annotations.Doc;
import fr.ifremer.isisfish.simulator.SimulationContext;
import fr.ifremer.isisfish.types.TimeStep;
import fr.ifremer.isisfish.entities.*;
import fr.ifremer.isisfish.simulator.Optimization;
import fr.ifremer.isisfish.simulator.OptimizationContext;
import fr.ifremer.isisfish.datastore.SimulationStorage;
import fr.ifremer.isisfish.datastore.ResultStorage;

/**
 * ExampleOptimization.java
 */
public class ExampleOptimization implements Optimization {

    protected boolean stopped = false;

    protected String[] necessaryResult = {};

    @Override
    public String[] getNecessaryResult() {
        return necessaryResult;
    }

    /**
     * Permet d'afficher a l'utilisateur une aide sur le plan.
     * @return L''aide ou la description du plan
     */
    @Override
    public String getDescription() throws Exception {
        return "Compute 2 simulation for each iteration defined by associated objective function";
    }

    /**
     * Appele lors de l'initialisation.
     *
     * @param context
     */
    public void init(OptimizationContext context) throws Exception {
    
    }

    /**
     * La premiere generation doit etre construite dans cette methode
     * dans l'init.
     *
     * @param context
     */
    public void firstSimulation(OptimizationContext context) throws Exception {
        for (int i = 0; i < 2; i++) {
           SimulationStorage storage = context.newSimulation();
           // modify simulation storage
        }
    }

    /**
     * Génère une nouvelle série de simulation suivant le context d'optimisation.
     * 
     * @param context context
     */
    public void nextSimulation(OptimizationContext context) throws Exception {
        if (!stopped) {
            for (int i = 0; i < 2; i++) {
                SimulationStorage storage = context.newSimulation();
                // modify simulation storage
            }
        }
    }

    /**
     * Cette methode est appelee après chaque serie de simulation soit apres firstSimulation et
     * nextSimulation.
     * 
     * @param context
     */
    public void endSimulation(OptimizationContext context) throws Exception {
        List<SimulationStorage> lastGeneration = context.getLastSimulations();
        for (SimulationStorage simulation : lastGeneration) {
            double objective = simulation.getObjective();
            if (objective <= -1) {
                stopped = true;
            }
        }
    }

    /**
     * Cette methode est appelee lorsqu'il n'y a plus de simulation a faire
     * (init ou nextSimulation n'ont pas fait appel a context.addSimulation)
     * @param context
     */
    public void finish(OptimizationContext context) throws Exception {
    
    }
}
