#ifndef JDETEVC2006_H
#define JDETEVC2006_H

class jDEtevc2006 {
public:
    typedef void (*EvaluateFun)(double*x, double *evals);
    jDEtevc2006(EvaluateFun evaluate, int D, int NP, int maxNFEVALs, double *xmin,
                double *xmax, unsigned int RNi=1);
    virtual ~jDEtevc2006();
    virtual void optimize(double *result, double *evaluation);

protected:
    virtual double random();
    virtual void createRuntimeStorage();
    virtual bool isBetterFirst(const double *first, const double *second) const;
    virtual void replaceFirstVectorIntoSecond(const double *first, double *second) const;
    virtual void initPop();
    virtual void optimizeOneGeneration(int &NFevals, int g);
    virtual void onBeforeOptimizeOneGeneration(int &NFevals, int g);
    virtual void onAfterOptimizeOneGeneration(int &NFevals, int g);
    virtual void onBeforeOptimizeOneVector(int NFevals, int g, int i);
    virtual void onAfterOptimizeOneVector(int NFevals, int g, int i);

    virtual void selfadaptControlParameters(int targetIdx);
    virtual void computeMutationVector(int i);
    virtual void computeCrossoverTrialVector(int targetIdx);
    virtual bool selectionTrialVsTarget(int i);
    virtual void checkUpdateBest(double *best);


    EvaluateFun evaluate;

    int D;
    int NP;
    int maxNFEVALs;

    double *xmin;
    double *xmax;

    unsigned long long RNi;
    long rnd_uni_init;

    int L;
    int NFevals;

    double *best;//role of "best" is a utility tmp for final printout & bestit computation only!
    double *trial;
    double *pop;
    double *newPop;

    const int idxFE, idxF, idxCR;

    friend class UnitTestDE;
};

#endif // JDETEVC2006_H
