package org.prgtest.settings;

import org.gui.settings.KernelGUIAbstract;
import org.ga.kernel.KernelGA;
import org.jgap.*;
import org.jgap.event.*;
import org.jgap.impl.*;
import org.prgtest.gui.*;
import org.prganalysis.settings.KernelPGAnalyzer;
import org.prganalysis.walker.NonRuntimeFunc;
import org.prganalysis.walker.ProgramNonRuntimeResults;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;

import org.prgtest.genetic.*;
import org.prgtest.common.AVar;
import org.prgtest.common.VarRepositar;
import org.ga.imp.SPEATournamentSelector;
import org.prganalysis.graph.*;

import java.util.HashMap;
import java.util.Vector;
import org.prgtest.randomgen.MultivariateFunctionImpl;
import org.prgtest.randomgen.ConjugateGradientSearch;
import org.prgtest.genetic.FitnesssFSymbolic;

public class KernelTG extends KernelGUIAbstract implements KernelGA,
        KernelPGAnalyzer {

    private static KernelTG _instance;
    private static Configuration conf;


    private Population paretoSet = new Population();
    private GeneticOperator[] geneticOperatorArray;

    private RandomGenerator rGenerator;
    private EventManager eventManager;
    private ChromosomePool chromosomePool;
    private FitnessEvaluator fEvaluator;
    private int evolNo;
    private int popSize;
    private boolean eliteSel;
    private boolean stopWhenCriteriaCovered;
    private boolean keepPopulationSizeConstant;
    private int minimumPopSizePercent;
    private FitnessFunction fitnessFunction;
    private DynamicBulkFitnessFunction dynamicBulkFitnessFunction;
    private static String settingsXmlDoucment = "c:/LocalD/JavaWorkSpace/TGSettings.xml";
    private static String imgLoc =
            "c:/LocalD/JavaWorkSpace/GUI/src/org/gui/main/img/";
    private File testFile;
    private ProgramNonRuntimeResults programNonRuntimeResults;
    private NaturalSelector nSelector;
    private boolean hasCoverCriteria = false;
    public HashMap edgeCoveredChromo = new HashMap(); //store edge covered
    public HashMap conditionCoveredChromoTrue = new HashMap(); //store conditionTrue covered
    public HashMap conditionCoveredChromoFalse = new HashMap(); //store conditionFalse covered
    public HashMap edgeToGraphAssoci = new HashMap(); //store Tgraph with edge as key
    public Vector vectorGeneStorage = new Vector();
    
    private boolean domainEnable = true;
    //private boolean domainEnable = false;
    
    KernelTG(String settingsXmlDoucment, String imgstrLoc) {
        super(settingsXmlDoucment, imgstrLoc);
    }

    public static synchronized KernelTG getInstance() {
        if (_instance == null) {

            if (settingsXmlDoucment == null) {
                System.out.println(
                        "call setSettingsXmlDoucment at least once before calling that method");
                return null;
            }
            if (imgLoc == null) {
                System.out.println(
                        "call setImgLoc at least once before calling that method");
                return null;
            }
            _instance = new KernelTG(settingsXmlDoucment, imgLoc);
            _instance.configure();
        }
        return _instance;
    }

    public File getTestFile() {
        return testFile;
    }
    
    public void setTestFile(String strFile){
    	testFile= new File(strFile);
    }

    public ProgramNonRuntimeResults getProgramNonRuntimeResults() {
        return programNonRuntimeResults;
    }

    public void setProgramNonRuntimeResults(ProgramNonRuntimeResults
                                            programNonRuntimeResults) {
        this.programNonRuntimeResults = programNonRuntimeResults;
    }

    public int getActiveThreads() {
        System.out.println("getActiveThreads/KernelTG");
        return 1;
    }

    public void setGenotype(Genotype population) {
        //System.out.println("Not implemented - setGenotype(Genotype population)");
    }

    public Chromosome getTemplateChromosome() {
    	
    	
    	
    	//AVar avar=new AVar();
    	// GeneVar compoGene = new GeneVar(avar);
       //  RandomGenerator generator =
           //      getConfiguration().getRandomGenerator();
         
         java.util.Vector <GeneVar> vecVar=new java.util.Vector <GeneVar>();
         try {
             ProgramNonRuntimeResults prgNonRunRe =
                     this.getProgramNonRuntimeResults();
             for (int y = 0; y < prgNonRunRe.getGraph().sizeVertices(); y++) {
                 TVertex tvertex = (TVertex) prgNonRunRe.getGraph().vertexAt(y);
                 if (!(tvertex.getNodeElement() instanceof barat.parser.
                       ParameterImpl)) {
                     continue;
                 }
                 barat.parser.ParameterImpl param = (barat.parser.ParameterImpl)
                         tvertex.getNodeElement();
                 if (param.getType() instanceof barat.reflect.PrimitiveType) {
                     barat.reflect.PrimitiveType primitType = (barat.reflect.
                             PrimitiveType) param.getType();
                     if (primitType.isInt()) {
                         AVar avar=new AVar(param.getName(),
                                 new Integer(300));/////////////////tas
                         GeneVar geneVar = new GeneVar(avar);
                         vecVar.add(geneVar);
                     } else {
                         throw new Exception("Not Implemented - new gene");
                     }
                 } else if (param.getType() instanceof barat.reflect.Array) {
                     barat.reflect.Array arrayType = (barat.reflect.Array) param.
                             getType();
                     if (arrayType.getElementType() instanceof barat.reflect.
                         PrimitiveType) {
                         barat.reflect.PrimitiveType primitElemType = (barat.
                                 reflect.
                                 PrimitiveType) arrayType.getElementType();
                         if (primitElemType.isInt()) {
                             int[] intArr = new int[1];
                             intArr[0] = 1;
                             AVar avar=new AVar(param.getName(),
                                     intArr);
                             GeneVar geneVar = new GeneVar(avar);
                             vecVar.add(geneVar);
                         } else {
                             throw new Exception("Not Implemented - new gene");
                         }
                     } else {
                         throw new Exception("Not Implemented - new gene");
                     }
                 }
             }
         } catch (Exception ex) {
             ex.printStackTrace();
         }
         
         
         
         GeneVar[] geneVarArray=new GeneVar[  vecVar.size()];
         
         for (int x=0;x<geneVarArray.length;x++){
        	 geneVarArray[x]=vecVar.get(x);
         }
         
    	
        Chromosome chromo = new Chromosome(geneVarArray);
        return chromo;
    }


    public void configure() {

        try {
            String returnStr;
            int returnAsInt;
            returnAsInt = Integer.parseInt(readSetting("GAOperators"));
            if (returnAsInt == 3) {
                geneticOperatorArray = new GeneticOperator[2];
                returnAsInt = Integer.parseInt(readSetting("CrossoverRate"));
                if (returnAsInt == 100) {
                    geneticOperatorArray[0] = new org.prgtest.genetic.
                                              CrossoverSpecial();
                } else {
                    geneticOperatorArray[0] = new org.prgtest.genetic.
                                              CrossoverSpecial(
                            returnAsInt);
                }
                returnAsInt = Integer.parseInt(readSetting("MutationRate"));
                if (returnAsInt == 100) {
                    geneticOperatorArray[1] = new org.prgtest.genetic.
                                              MutationSpecial();
                } else {
                    geneticOperatorArray[1] = new org.prgtest.genetic.
                                              MutationSpecial(
                            returnAsInt);
                }
            } else if (returnAsInt == 2) {
                geneticOperatorArray = new GeneticOperator[1];
                returnAsInt = Integer.parseInt(readSetting("MutationRate"));
                if (returnAsInt == 100) {
                    geneticOperatorArray[0] = new org.prgtest.genetic.
                                              MutationSpecial();
                } else {
                    geneticOperatorArray[0] = new org.prgtest.genetic.
                                              MutationSpecial(
                            returnAsInt);
                }
            } else if (returnAsInt == 1) {
                geneticOperatorArray = new GeneticOperator[1];
                returnAsInt = Integer.parseInt(readSetting("CrossoverRate"));
                if (returnAsInt == 100) {
                    geneticOperatorArray[0] = new org.prgtest.genetic.
                                              CrossoverSpecial();
                } else {
                    geneticOperatorArray[0] = new org.prgtest.genetic.
                                              CrossoverSpecial(
                            returnAsInt);
                }

            }

            popSize = Integer.parseInt(readSetting("PopulationSize"));

            returnAsInt = Integer.parseInt(readSetting("NaturalSelector"));
            if (returnAsInt == 1) {

                nSelector = new WeightedRouletteSelector();
                System.out.println("WeightedRouletteSelector");
            } else if (returnAsInt == 2) {
                returnAsInt = Integer.parseInt(readSetting("TournamentSize"));
                nSelector = new TournamentSelector(returnAsInt,
                        Double.parseDouble(readSetting(
                                "TournamentProbability")) / 100);
            } else if (returnAsInt == 3) {
                returnAsInt = Integer.parseInt(readSetting("TournamentSize"));
                nSelector = new SPEATournamentSelector(this
                        ,
                        returnAsInt,
                        Double.parseDouble(readSetting(
                                "TournamentProbability")) / 100);
            }

            else {
                printDebug(this, "Error Setting other nselector", 3);
            }
            returnAsInt = Integer.parseInt(readSetting("RandomGenerator"));
            if (returnAsInt == 1) {
                rGenerator = new org.jgap.impl.StockRandomGenerator();
            } else {
                printDebug(this, "Error Setting other RandomGenerator", 3);
            }

            eventManager = new EventManager();
            chromosomePool = new ChromosomePool();

            // a defect rate (the lower the better).
            //fEvaluator = new DeltaFitnessEvaluator(); //DefaultFitnessEvaluator();
            fEvaluator = new DefaultFitnessEvaluator();
            //   parBulkFitnessFunction = new ParetoBulkFitnessFunction();
            evolNo = Integer.parseInt(readSetting("Evolutions"));
            eliteSel = Boolean.parseBoolean(readSetting("elitism"));
            stopWhenCriteriaCovered = true;
            keepPopulationSizeConstant = true;
            minimumPopSizePercent = Integer.parseInt(readSetting(
                    "minimumPopSizePercent"));
            fitnessFunction = new FitnesssFSymbolic();
           // dynamicBulkFitnessFunction = new DynamicBulkFitnessFunction();
            conf = new org.ga.imp.SimpleConfiguration(this); //always last sinces it used the aboved data

            testFile = new File(readSetting("testFile"));

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    protected void iniBtnArray() {
        arrayOfBtnIterface = new BtnAction[5];
        
        BtnAction btnCreateSymbGraph = new BtnAction(imgLoc + "graph.png", 1, true);
        arrayOfBtnIterface[0] = btnCreateSymbGraph;
        
        BtnAction btnRun = new BtnAction(imgLoc + "Run.png", 2, false);
        arrayOfBtnIterface[1] = btnRun;
        //BtnAction btnCreateConstraintGraph = new BtnAction(imgLoc + "Run.png", 3, false);
        
        BtnAction btnCreateConstraintGraph = new BtnAction(imgLoc + "graph.png", 3, false);
        arrayOfBtnIterface[2] = btnCreateConstraintGraph;
        
        BtnAction btnGArun = new BtnAction(imgLoc + "Run.png", 4, false);
        arrayOfBtnIterface[3] = btnGArun;
        
        BtnAction btnResults = new BtnAction(imgLoc + "Run.png", 5, false);
        arrayOfBtnIterface[4] = btnResults;
    }


    public GeneticOperator[] getOperator() {
        return geneticOperatorArray;
    }


    public NaturalSelector getSelector() {
        return this.nSelector;
    }

    public Population getExternalParetoSet() {
        return paretoSet; //remember to reset
    }

    public void setExternalParetoSet(Population paretoSet) {
        this.paretoSet = paretoSet;
    }

    public RandomGenerator getRandomGenerator() {
        return rGenerator;
    }

    public EventManager getEventManager() {
        return eventManager;
    }

    public ChromosomePool getChromosomePool() {
        return chromosomePool;
    }

    public FitnessEvaluator getFitnessEvaluator() {
        return fEvaluator;
    }

    public Configuration getConfiguration() {
        return conf;
    }

    public BulkFitnessFunction getBulkFitnessFunction() {
        return dynamicBulkFitnessFunction;
    	//return new FitnesssFSymbolic();
    }

    public FitnessFunction getFitnessfunction() {
        return fitnessFunction; //fitnessFunction; //Since we set the bulk - new sof.mpeg21.genetic.SimpleFitnessFunction();
    }

    public void setHasCoverCriteria(boolean isCovered) {
        //   System.out.println("Covered - Criteria ");
        hasCoverCriteria = isCovered;
    }

    public boolean getHasCoverCriteria() {
        return hasCoverCriteria;
    }


    //For Random Generator
    public Gene getGeneRandom() {
        CompoGene compoGene = new CompoGene();
        RandomGenerator generator =
                getConfiguration().getRandomGenerator();
        compoGene.setToRandomValue(generator);
        TFitnessFunc2.numberofpredicates = 0;

        return compoGene;
    }


    public double evaluateGeneGradientDescent(double arguments[]) {
        CompoGene compoGene = new CompoGene();
        double fVal;

        for (int x = 0; x < compoGene.size(); x++) {
            CompoGeneItem gompoGeneItem = (CompoGeneItem) compoGene.geneAt(x);
            AVar avarOld = (AVar) gompoGeneItem.getAllele();
            int iz = (int) Math.round(arguments[x]);
            AVar avarNew = new AVar(avarOld.getVariableName(), new Integer(iz));
            gompoGeneItem.setAllele(avarNew);

        }

        compoGene.getCoverageDataChecked();

        CoverageData cData = compoGene.getCoverageDataChecked();
        fVal = (cData.getEdgeCovered().size() +
                (cData.getDF() != 0 ? 1 / (1 + cData.getDF()) : 0));
        //cData.getDF();// cData.getEdgeCovered().size() + (cData.getDF()!=0?1 / (1 + cData.getDF()):0);
        System.out.println("fVal=" + fVal + " compoGene=" + compoGene +
                           " arguments=" + arguments[0] + "," + arguments[1] +
                           "," + arguments[2]);
        Object[] objArray = cData.getEdgeCovered().keySet().toArray();
        boolean breakAll = false;
        for (int z = 0; z < objArray.length; z++) {
            if (!edgeCoveredChromo.containsKey(objArray[z])) { //if there is an gene that has new edges
                edgeCoveredChromo.putAll(cData.getEdgeCovered()); //put all edges
                conditionCoveredChromoTrue.putAll(cData.
                                                  getConditionTrueCovered());
                conditionCoveredChromoFalse.putAll(cData.
                        getConditionFalseeCovered());
                vectorGeneStorage.add(compoGene);
                breakAll = true;
                break;
            }
        }
        if (!breakAll) {
            objArray = cData.getConditionTrueCovered().keySet().toArray();
            for (int z = 0; z < objArray.length; z++) {
                if (!conditionCoveredChromoTrue.containsKey(objArray[z])) {
                    conditionCoveredChromoTrue.putAll(cData.
                            getConditionTrueCovered());
                    conditionCoveredChromoFalse.putAll(cData.
                            getConditionFalseeCovered());
                    vectorGeneStorage.add(compoGene);
                    breakAll = true;
                    break;
                }
            }
        }
        if (!breakAll) {
            objArray = cData.
                       getConditionFalseeCovered().keySet().toArray();
            for (int z = 0; z < objArray.length; z++) {
                if (!conditionCoveredChromoFalse.containsKey(objArray[z])) {
                    conditionCoveredChromoFalse.putAll(cData.
                            getConditionFalseeCovered());
                    vectorGeneStorage.add(compoGene);
                    breakAll = true;
                    break;
                }
            }
        }

        return fVal;
    }

    public void runGradientDescent() {
        domainEnable = false;
        boolean needfurther = true;

        while (needfurther) {
            needfurther = false;
            CompoGene compoGene = (CompoGene) getGeneRandom();
            double[] xxy = new double[compoGene.size()];
            double tolfx = 0.000000000001;
            double tolx = 1;

            for (int x = 0; x < compoGene.size(); x++) {
                CompoGeneItem gompoGeneItem = (CompoGeneItem) compoGene.geneAt(
                        x);
                AVar avarNew = (AVar) gompoGeneItem.getAllele();
                Integer dod = (Integer) avarNew.getValue();
                xxy[x] = dod.doubleValue();
            }

            MultivariateFunctionImpl multivariateFunctionImpl = new
                    MultivariateFunctionImpl(compoGene.size());
            ConjugateGradientSearch conjugateGradientSearch = new
                    ConjugateGradientSearch(1);
            System.out.println("888888888888888888888888888888888888 edge=" +
                               edgeCoveredChromo.size());
            conjugateGradientSearch.optimize(multivariateFunctionImpl, xxy,
                                             tolfx,
                                             tolx);

            getProgramNonRuntimeResults().resetGraph();
            int maxTMP = getProgramNonRuntimeResults().
                         getGraph().
                         sizeEdges();
            for (int iz = 0;
                          iz < getProgramNonRuntimeResults().
                          getGraph().
                          sizeEdges(); iz++) {
                TEdge edge = (TEdge)
                             getProgramNonRuntimeResults().getGraph().
                             edgeAt(
                                     iz);
                if (!edgeCoveredChromo.containsKey(edge)) {
                    Object[] tgraphArray;
                    if (!edgeToGraphAssoci.containsKey(edge)) {
                        tgraphArray =
                                getProgramNonRuntimeResults().
                                exctractPaths(edge);
                        edgeToGraphAssoci.put(edge, tgraphArray);
                    } else {
                        tgraphArray = (Object[]) edgeToGraphAssoci.get(edge);
                    }

                    for (int yx = 0; yx < tgraphArray.length; yx++) {
                        if (tgraphArray[yx] != null) {
                            TGraph tgraph = (TGraph) tgraphArray[yx];
                            this.programNonRuntimeResults.setGraph(tgraph);
                            tgraphArray[yx] = null;
                            needfurther = true;
                            break;
                        }
                    }
                    if (needfurther) {
                        break;
                    }

                }
            }

        }
        /* if (needfurther) {
             System.out.println("" + edgeToGraphAssoci);
             //     if (true) return;
             System.out.println("maxEdges=" + maxTMP + " edgeCovered.size" +
                                edgeCoveredChromo.size() + " Associ.size=" +
                                edgeToGraphAssoci.size() + " trueCond=" +
                                conditionCoveredChromoTrue.size() +
         " falseCond=" + conditionCoveredChromoFalse.size());
             setHasCoverCriteria(false);
             configure();
             getBtnArray()[1].performAction(null);
             return;
         }*/







        System.out.println("Edges[" +
                           this.getProgramNonRuntimeResults().getGraph().
                           sizeEdges() + "]");
        System.out.println("covered[edge=" + edgeCoveredChromo.size() +
                           " ]");
        System.out.println("coveredTrue[true=" +
                           conditionCoveredChromoTrue.size() +
                           " ]");
        System.out.println("coveredFalse[false=" +
                           conditionCoveredChromoFalse.size() +
                           " ]");
        System.out.println("edgeToGraphAssoci[" + edgeToGraphAssoci.size() +
                           "]");

    }

    public void runRandomGen() {
        domainEnable = false;
        boolean needfurther = false;
        getProgramNonRuntimeResults().resetGraph();

        for (int x = 0; x < 200000; x++) {

            CompoGene compoGene = (CompoGene) getGeneRandom();
            if (x % 50 == 0) {
                System.out.println("x=" + x);
                System.out.println("compoGene=" + compoGene);
            }

            CoverageData cData = compoGene.getCoverageDataChecked();
            Object[] objArray = cData.getEdgeCovered().keySet().toArray();
            boolean breakAll = false;
            for (int z = 0; z < objArray.length; z++) {
                if (!edgeCoveredChromo.containsKey(objArray[z])) { //if there is an gene that has new edges
                    edgeCoveredChromo.putAll(cData.getEdgeCovered()); //put all edges
                    conditionCoveredChromoTrue.putAll(cData.
                            getConditionTrueCovered());
                    conditionCoveredChromoFalse.putAll(cData.
                            getConditionFalseeCovered());
                    vectorGeneStorage.add(compoGene);
                    breakAll = true;
                    break;
                }
            }
            if (!breakAll) {
                objArray = cData.getConditionTrueCovered().keySet().toArray();
                for (int z = 0; z < objArray.length; z++) {
                    if (!conditionCoveredChromoTrue.containsKey(objArray[z])) {
                        conditionCoveredChromoTrue.putAll(cData.
                                getConditionTrueCovered());
                        conditionCoveredChromoFalse.putAll(cData.
                                getConditionFalseeCovered());
                        vectorGeneStorage.add(compoGene);
                        breakAll = true;
                        break;
                    }
                }
            }
            if (!breakAll) {
                objArray = cData.
                           getConditionFalseeCovered().keySet().toArray();
                for (int z = 0; z < objArray.length; z++) {
                    if (!conditionCoveredChromoFalse.containsKey(objArray[z])) {
                        conditionCoveredChromoFalse.putAll(cData.
                                getConditionFalseeCovered());
                        vectorGeneStorage.add(compoGene);
                        breakAll = true;
                        break;
                    }
                }
            }

        }
        System.out.println("Edges[" +
                           this.getProgramNonRuntimeResults().getGraph().
                           sizeEdges() + "]");
        System.out.println("covered[edge=" + edgeCoveredChromo.size() +
                           " ]");
        System.out.println("coveredTrue[true=" +
                           conditionCoveredChromoTrue.size() +
                           " ]");
        System.out.println("coveredFalse[false=" +
                           conditionCoveredChromoFalse.size() +
                           " ]");
        System.out.println("edgeToGraphAssoci[" + edgeToGraphAssoci.size() +
                           "]");
    }

    public Gene[] getNewSampleGenes(int geneNo) { //initialize array, initialize genes/set to random value

        if (vectorGeneStorage.size() > 0) {
            Gene[] sampleGenes = new CompoGene[1];
            sampleGenes[0] = new CompoGene();
            RandomGenerator generator =
                    getConfiguration().getRandomGenerator();
            sampleGenes[0].setToRandomValue(generator);
            TFitnessFunc2.numberofpredicates = 0;
            //    TFitnessFunc2.m_targetAmount = -1;
            //    TFitnessFunc2.lastgood = 0;
            //    TFitnessFunc2.lastPrint = -1;
            paretoSet = new Population();
            return sampleGenes;
        }

        int numofpredicateds = 0;

        //count predicates
        //
        for (int y = 0; y < programNonRuntimeResults.getGraph().sizeVertices();
                     y++) {
            TVertex tVertex = (TVertex) programNonRuntimeResults.getGraph().
                              vertexAt(y);
            try {
                if (tVertex.getNodeElement() != null) {
                    if (tVertex.getNodeElement() instanceof barat.parser.
                        BinaryOperationImpl) {
                        numofpredicateds++;

                        barat.parser.BinaryOperationImpl binaryOperationImpl = (
                                barat.parser.BinaryOperationImpl) tVertex.
                                getNodeElement();

                        /*   if (binaryOperationImpl.getLeftOperand() instanceof
                               barat.parser.
                               BinaryOperationImpl) {
                               numofpredicateds++;
                               barat.parser.BinaryOperationImpl
                                       binaryOperationImpl2 = (barat.parser.
                         BinaryOperationImpl) binaryOperationImpl.
                                       getLeftOperand();
                         if (binaryOperationImpl2.getLeftOperand() instanceof
                                   barat.parser.
                                   BinaryOperationImpl) {
                                   numofpredicateds++;
                         } else if (binaryOperationImpl2.getLeftOperand() instanceof
                                          barat.parser.ParenExpressionImpl) {
                                   barat.parser.ParenExpressionImpl
                                           parenExpressionImpl = (
                                                   barat.
                                                   parser.ParenExpressionImpl)
                         binaryOperationImpl2.getLeftOperand();
                                   if (parenExpressionImpl.
                                       getOperand() instanceof
                                       barat.parser.
                                       BinaryOperationImpl) {
                                       numofpredicateds++;
                                   }
                               }
                           }*/
                        numofpredicateds = numofpredicateds +
                                           calculateBin(binaryOperationImpl);
                    }
                }
            } catch (Exception ex) {
                System.out.println("exception - kernel -creating the genes ");
            }
        }

        //System.out.println("PROSOXI IPOLOGIZEI LATHOS numofpredicateds");
        //  numofpredicateds = 17;
        int numberoftestcases = programNonRuntimeResults.
                                getCComplexity() + (2 ^ (numofpredicateds - 1)) +
                                1 -
                                2;
        System.out.println("WAS numofpredicates=" + numofpredicateds +
                           "  numberoftestcases=" + numberoftestcases);



        numberoftestcases = programNonRuntimeResults.getCComplexity() + (int)(Math.pow(2,(numofpredicateds - 1)) -2);


        System.out.println("NOW numofpredicates=" + numofpredicateds +
                           "  numberoftestcases=" + numberoftestcases);

        TFitnessFunc2.numberofpredicates = numofpredicateds;
        Gene[] sampleGenes = new CompoGene[numberoftestcases];
        for (int x = 0; x < sampleGenes.length; x++) {
            sampleGenes[x] = new CompoGene();
            RandomGenerator generator =
                    getConfiguration().getRandomGenerator();
            sampleGenes[x].setToRandomValue(generator);
        }
        return sampleGenes;
    }

    private int calculateBin(barat.parser.BinaryOperationImpl bin) {
        barat.parser.BinaryOperationImpl bin2 = null;
        int howmany = 0;
        if (bin.operator().equals("&&") ||
            bin.operator().equals("||")) {
            //do nothing
        } else {
            return 0;
        }
        if (bin.getLeftOperand() instanceof
            barat.parser.
            BinaryOperationImpl) {
            bin2 = (barat.parser.
                    BinaryOperationImpl) bin.getLeftOperand();
        } else if (bin.getLeftOperand() instanceof
                   barat.parser.ParenExpressionImpl) {
            barat.parser.ParenExpressionImpl
                    parenExpressionImpl = (
                            barat.
                            parser.ParenExpressionImpl)
                                          bin.getLeftOperand();
            if (parenExpressionImpl.
                getOperand() instanceof
                barat.parser.
                BinaryOperationImpl) {
                bin2 = (barat.parser.
                        BinaryOperationImpl) parenExpressionImpl.
                       getOperand();
            }
        }
        if (bin2 != null) {
            return calculateBin(bin2) + 1;
        } else {
            return 0;
        }
    }

    public int getEvolNo() {
        return evolNo;
    }

    public int getPopulSize() {
        return popSize;
    }

    public boolean getEliteSelection() {
        return eliteSel;
    }

    public boolean getStopWhenCoverCriteria() {
        return stopWhenCriteriaCovered;
    }

    //do something before each ga run
    public void doProGAProcess() {

        try {
            // loadUED.readAll();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    public boolean getKeepPopulationSizeConstant() {
        printDebug(this, "getKeepPopulationSizeConstant", 1);
        return keepPopulationSizeConstant;
    }

    public int getMinimumPopSizePercent() {
        printDebug(this, "getMinimumPopSizePercent", 1);
        return minimumPopSizePercent;
    }

    public void doAfterGAProcess(Chromosome bestSolutionSoFar)
    {
 
    	org.prgtest.common.VarRepositar VR = new org.prgtest.common.VarRepositar();
		org.prgtest.common.AVar avar;

    	for (int i=0; i<bestSolutionSoFar.size();i++)
    	{
    		GeneVar gene = (GeneVar)bestSolutionSoFar.getGene(i);
    		avar = (org.prgtest.common.AVar)gene.getAllele();
		 	VR.add(avar);
    	}
    	CoverageData CD = new CoverageData(VR);
		CD.execute();
	
		//edgeCoveredChromo.putAll(CD.getEdgeCovered());
		//conditionCoveredChromoTrue.putAll(CD.getConditionTrueCovered());
		//conditionCoveredChromoFalse.putAll(CD.getConditionFalseeCovered());
		
		Object[] objArray = CD.getEdgeCovered().keySet().toArray();
		
		 for (int z = 0; z < objArray.length; z++) {
			 if (!edgeCoveredChromo.containsKey(objArray[z]))
			 {
				 //edgeCoveredChromo.putAll(CD.getEdgeCovered());
				 edgeCoveredChromo.put(objArray[z], null);
				 //conditionCoveredChromoTrue.putAll(CD.getConditionTrueCovered());
				 //conditionCoveredChromoFalse.putAll(CD.getConditionFalseeCovered());
			 }
		 }
		 
		//System.out.println("a: "+CD.getEdgeCovered().get(i).hashCode());// .hashCode());
		//System.out.println("b: "+conditionCoveredChromoTrue.size());
		//System.out.println("c: "+conditionCoveredChromoFalse.size());
    }
    
    public void doAfterGAProcess(Chromosome bestSolutionSoFar,
                                 Genotype population) {

        boolean needfurther = false;
        getProgramNonRuntimeResults().resetGraph();
        Chromosome chromoPareto = this.paretoSet.determineFittestChromosome();
        Gene[] geneArray = chromoPareto.getGenes(); // bestSolutionSoFar.getGenes();
        System.out.println("");
        for (int i = 0; i < geneArray.length; i++) {
            CompoGene compoGene = (CompoGene) geneArray[i];

            CoverageData cData = compoGene.getCoverageDataChecked();
            Object[] objArray = cData.getEdgeCovered().keySet().toArray();
            boolean breakAll = false;
            for (int z = 0; z < objArray.length; z++) {
                if (!edgeCoveredChromo.containsKey(objArray[z])) { //if there is an gene that has new edges
                    edgeCoveredChromo.putAll(cData.getEdgeCovered()); //put all edges
                    conditionCoveredChromoTrue.putAll(cData.
                            getConditionTrueCovered());
                    conditionCoveredChromoFalse.putAll(cData.
                            getConditionFalseeCovered());
                    vectorGeneStorage.add(compoGene);
                    breakAll = true;
                    break;
                }
            }
            if (!breakAll) {
                objArray = cData.getConditionTrueCovered().keySet().toArray();
                for (int z = 0; z < objArray.length; z++) {
                    if (!conditionCoveredChromoTrue.containsKey(objArray[z])) {
                        //   edgeCoveredChromo.putAll(cData.getEdgeCovered()); //put all edges
                        conditionCoveredChromoTrue.putAll(cData.
                                getConditionTrueCovered());
                        conditionCoveredChromoFalse.putAll(cData.
                                getConditionFalseeCovered());
                        vectorGeneStorage.add(compoGene);
                        breakAll = true;
                        break;

                    }
                }
            }
            if (!breakAll) {
                objArray = cData.
                           getConditionFalseeCovered().keySet().toArray();
                for (int z = 0; z < objArray.length; z++) {
                    if (!conditionCoveredChromoFalse.containsKey(objArray[z])) {
                        //   edgeCoveredChromo.putAll(cData.getEdgeCovered()); //put all edges
                        //  conditionCoveredChromoTrue.putAll(cData.
                        //          getConditionTrueCovered());
                        conditionCoveredChromoFalse.putAll(cData.
                                getConditionFalseeCovered());
                        vectorGeneStorage.add(compoGene);
                        breakAll = true;
                        break;
                    }
                }
            }
        }

        int maxTMP = getProgramNonRuntimeResults().
                     getGraph().
                     sizeEdges();

        for (int iz = 0;
                      iz < getProgramNonRuntimeResults().
                      getGraph().
                      sizeEdges(); iz++) {
            TEdge edge = (TEdge)
                         getProgramNonRuntimeResults().getGraph().
                         edgeAt(
                                 iz);
            if (!edgeCoveredChromo.containsKey(edge)) {
                Object[] tgraphArray;
                if (!edgeToGraphAssoci.containsKey(edge)) {
                    tgraphArray =
                            getProgramNonRuntimeResults().
                            exctractPaths(edge);
                    edgeToGraphAssoci.put(edge, tgraphArray);
                } else {
                    tgraphArray = (Object[]) edgeToGraphAssoci.get(edge);
                }

                for (int yx = 0; yx < tgraphArray.length; yx++) {
                    if (tgraphArray[yx] != null) {
                        TGraph tgraph = (TGraph) tgraphArray[yx];
                        this.programNonRuntimeResults.setGraph(tgraph);
                        tgraphArray[yx] = null;
                        needfurther = true;
                        break;
                    }
                }
                if (needfurther) {
                    break;
                }

            }
        }
        if (needfurther) {
            System.out.println("" + edgeToGraphAssoci);
            //     if (true) return;
            System.out.println("maxEdges=" + maxTMP + " edgeCovered.size" +
                               edgeCoveredChromo.size() + " Associ.size=" +
                               edgeToGraphAssoci.size() + " trueCond=" +
                               conditionCoveredChromoTrue.size() +
                               " falseCond=" + conditionCoveredChromoFalse.size());
            setHasCoverCriteria(false);
            configure();
            getBtnArray()[1].performAction(null);
            return;
        }

        /*  this.setToPanel(this.PANEL_STATUSBAR,
                          new org.prgtest.gui.
         PanelDisplayTestCases(this.getExternalParetoSet().
         determineFittestChromosome()));*/
        System.out.println("Edges[" +
                           this.getProgramNonRuntimeResults().getGraph().
                           sizeEdges() + "]");
        System.out.println("covered[edge=" + edgeCoveredChromo.size() +
                           " ]");
        System.out.println("coveredTrue[true=" +
                           conditionCoveredChromoTrue.size() +
                           " ]");
        System.out.println("coveredFalse[false=" +
                           conditionCoveredChromoFalse.size() +
                           " ]");
        System.out.println("edgeToGraphAssoci[" + edgeToGraphAssoci.size() +
                           "]");

        for (int x = 0; x < vectorGeneStorage.size(); x++) {
            CompoGene compoGene = (CompoGene) vectorGeneStorage.elementAt(x);
            System.out.println("TC#" + x + "\n");
            for (int y = 0; y < compoGene.size(); y++) {
                System.out.print("" + compoGene.geneAt(y).toString());
            }
        }

        /*for (int y = 0; y < this.getExternalParetoSet().size(); y++) {
            for (int i = 0;
                         i <
         this.getExternalParetoSet().getChromosome(y).getGenes().length;
                         i++) {
         SGene sgene = (SGene) this.getExternalParetoSet().getChromosome(y).getGene(i);
                System.out.println("***************************");

         for (int x = 0; x < sgene.geneCoverage.m_value.size(); x++) {
         System.out.println(sgene.geneCoverage.m_value.elementAt(x));
                }
         for (int x = 0; x < sgene.geneCoverage.tVertexVector.size(); x++) {
         org.prganalysis.graph.TVertex tvertex = (org.prganalysis.
         graph.TVertex) sgene.geneCoverage.tVertexVector.
                            elementAt(x);
                    System.out.println(tvertex.toString());
                }

            }

         for (int x=0;x<population.getPopulation().getChromosomes().size() ;x++ ) {
                  System.out.println(" Chromosome "+   population.getPopulation().getChromosome(x));
                }


                 }*/

    }

    public int getIntDomain() {
        if (domainEnable) {
            return (conf.getGenerationNr() + 1) * 2;
        } else {
            return 10000;
        }
    }

    public String getAppTitle() {
        return "Test Case Generator";
    }

    public String getSplashImgLoc() {
        return "" + "c:/LocalD/ProgramAnalysis/TestCaseGenerator/src/org/prgtest/gui/splashTCGen.png";
    }

}
