#ifndef SCRIPTS_H_INCLUDED
#define SCRIPTS_H_INCLUDED

#include <vector>
#include <fstream>

#include "analysis/analysis.h"
#include "analysis/ParameterOptimizer.h"

class CrossoverProbaOptimizer : public ParameterOptimizer {
    public:
        CrossoverProbaOptimizer(int n_init, double obj, std::default_random_engine& randomizer) : ParameterOptimizer(randomizer), n_initial{n_init}, objective{obj} {};
        SearchHeuristic* get_context(unsigned int i, double parameter, std::default_random_engine& randomizer) {
            GA* algo = new GA(5, 5, PLUS, 1./(n_initial+i), parameter, UNIFORM_CROSSOVER, GA_V1, randomizer);
            MasterMind* mm = new MasterMind(n_initial+i, n_initial+i, randomizer);
            algo->set_problem(mm);
            algo->set_objective(objective);
            return algo;
        }
        std::string display_context(unsigned int context) {
           std::stringstream ss;
           ss << "n=" << n_initial+context;
           return ss.str();
        }
        std::string get_context_for_csvfile(unsigned int num_context) {
           return std::to_string(n_initial+num_context);
        }

    private:
        int n_initial;
        double objective;
};

void script_crossover_proba_optim(std::default_random_engine& randomizer) {
    std::string namefile = "crossover-proba.csv";
    std::ofstream savefile(namefile);
    {
        int n_init=3, n_final=21;
        double p_init=0.01, p_final=0.99, p_step=0.02;
        CrossoverProbaOptimizer cpo(n_init, 1.00, randomizer);
        cpo.set_nb_contexts(n_final - n_init);
        cpo.set_study_interval(p_init, p_final, p_step);
        cpo.add_test_wave(40, 2.5419828669, 0);
        cpo.add_test_wave(400, 2.4429370465, 1);
        cpo.add_test_wave(2000, 2.4344837209, 2);
        cpo.save_run(namefile);
        cpo.run();
    }{
        int n_init=21, n_final=40;
        double p_init=0.01, p_final=0.3, p_step=0.02;
        CrossoverProbaOptimizer cpo(n_init, 1.00, randomizer);
        cpo.set_nb_contexts(n_final - n_init);
        cpo.set_study_interval(p_init, p_final, p_step);
        cpo.add_test_wave(80, 2.4860491262, 0);
        cpo.add_test_wave(200, 2.4535822177, 1);
        cpo.add_test_wave(400, 2.4429370465, 2);
        cpo.save_run(namefile);
        cpo.run();
    }
}

#endif // SCRIPTS_H_INCLUDED
