package org.prgtest.genetic;

import org.jgap.*;
import org.jgap.eval.*;
import org.prgtest.settings.KernelTG;
import java.util.*;
import org.prganalysis.graph.*;

public class DynamicBulkFitnessFunction extends BulkFitnessFunction {

    public PopulationHistory popHistory = new PopulationHistory(100);
    TFitnessFunc2 tfitnessFunc2;
    KernelTG kernel;
    double lowF = 100;
    private double lowerFitnessValue = 100;
    private int lastEvol = 0;
    //private static Vector VectorStorage = new Vector();
    //private static HashMap edgeCoveredChromo = new HashMap();
    //   private static HashMap genesCompoHashMap = new HashMap();
    // private static HashMap conditionTrueCoveredChromo = new HashMap();
    //   private static HashMap conditionFalseCoveredChromo = new HashMap();

    public DynamicBulkFitnessFunction() {
        kernel = KernelTG.getInstance();
        tfitnessFunc2 = new TFitnessFunc2(1);

    }

    public double evaluate(Population pop_Pt) {

        for (int x = 0; x < pop_Pt.size(); x++) {
            Chromosome chromo = pop_Pt.getChromosome(x);
            chromo.setFitnessValue(tfitnessFunc2.evaluate(chromo));
            //System.out.println("ChromoID"+chromo.DELTA+ " F="+chromo.getFitnessValue());
        }
        /* EVALUEATES THE UNIQUE
                Population popToCompare = new Population();
                popToCompare.addChromosomes(kernel.getExternalParetoSet());
                popToCompare.addChromosomes(pop_Pt);

                kernel.setExternalParetoSet(getUnigue(popToCompare));



         popHistory.addPopulation(new Population(pop_Pt.toChromosomes()));*/
        Population popToCompare = new Population();

        Chromosome chomo1 = kernel.getExternalParetoSet().
                            determineFittestChromosome();
        Chromosome chromo2 = pop_Pt.determineFittestChromosome();
        if (chomo1 != null) {
            popToCompare.addChromosome(chomo1);
            if (lowerFitnessValue < chomo1.getFitnessValue()) {
                lowerFitnessValue = chomo1.getFitnessValue();
                lastEvol = kernel.getConfiguration().getGenerationNr();
            }
            if (lastEvol + 1000 < (kernel.getConfiguration().getGenerationNr())) {
                kernel.setHasCoverCriteria(true);
                System.out.println("lets stop it at evol_Numb="+kernel.getConfiguration().getGenerationNr());
            }

        }
        popToCompare.addChromosome(chromo2);
        kernel.setExternalParetoSet(popToCompare);

    }

    private Population getUnigue(Population popToCompare) {
        Population fittestPop = new Population();
        fittestPop.addChromosome(popToCompare.determineFittestChromosome());
        for (int x = 0; x < popToCompare.size(); x++) {
            Chromosome chromoComp = popToCompare.getChromosome(x);
            if (!isChromoInPopulation(chromoComp, fittestPop)) {
                fittestPop.addChromosome(chromoComp);
            }
        }
        /* for (int x=0;x<fittestPop.size() ;x++ ) {
         System.out.println("F+["+x+"]="+fittestPop.getChromosome(x).getFitnessValue());
         }*/
        //  System.out.println("PopSize="+fittestPop.size());
        return fittestPop;
    }

    private boolean isChromoInPopulation(Chromosome chromo, Population pop) {

        for (int i = 0; i < pop.size(); i++) {
            boolean ischromoFound = false;
            for (int x = 0; x < chromo.size(); x++) {
                ischromoFound = (isInChromo((CompoGene) chromo.getGene(x),
                                            pop.getChromosome(i)));
                if (!ischromoFound) {
                    break;
                }
            }
            if (ischromoFound) {
                return true;
            }
        }
        return false;
    }

    private boolean isInChromo(CompoGene sgene, Chromosome chromo) {
        for (int x = 0; x < chromo.size(); x++) {
            CompoGene sGene2 = (CompoGene) chromo.getGene(x);
            if (sgene.getCoverageData().equals(sGene2.
                                               getCoverageData())) {
                return true;
            }
        }
        return false;
    }
}
