package ac.essex.gp.ooechs.novelty1;

import ac.essex.ooechs.imaging.commons.ColourChannels;
import ac.essex.ooechs.imaging.commons.StatisticsSolver;
import ac.essex.ooechs.imaging.commons.PixelLoader;
import ac.essex.ooechs.imaging.commons.fast.FastStatistics;
import ac.essex.ooechs.imaging.commons.signal.SignalDefinition;
import ac.essex.gp.Evolve;
import ac.essex.gp.individuals.Individual;
import ac.essex.gp.interfaces.console.ConsoleListener;

import java.util.Vector;
import java.io.File;

/**
 * Creates a novelty detector.
 *
 * @author Olly Oechsle, University of Essex, Date: 21-Apr-2008
 * @version 1.0
 */
public class NoveltyDetectorFinder {

    public static final String TRUE_DIRECTORY = "/home/ooechs/Desktop/pipe-images3/foreground/";
    public static final String FALSE_DIRECTORY = "/home/ooechs/Desktop/pipe-images3/background/";
    public static final String UNUSUAL_DIRECTORY = "/home/ooechs/Desktop/pipe-images3/background/";


    public static void main(String[] args) {

        Vector<SignalDefinition> signalDefinitions = new Vector<SignalDefinition>();

        signalDefinitions.add(new SignalDefinition(ColourChannels.GREYSCALE, StatisticsSolver.MEAN));
        signalDefinitions.add(new SignalDefinition(ColourChannels.RED, StatisticsSolver.MEAN));
        signalDefinitions.add(new SignalDefinition(ColourChannels.GREEN, StatisticsSolver.MEAN));
        signalDefinitions.add(new SignalDefinition(ColourChannels.BLUE, StatisticsSolver.MEAN));

        NoveltyDetector n = new NoveltyDetector(signalDefinitions);

        long start = System.currentTimeMillis();

        for (int signalID = 0; signalID < signalDefinitions.size(); signalID++) {
            SignalDefinition s1 = signalDefinitions.elementAt(signalID);

            NovelGPProblem problem = new NovelGPProblem(s1.getChannel(), s1.getStatistic());
            problem.load(TRUE_DIRECTORY, NovelGPProblem.TRUE);
            problem.load(FALSE_DIRECTORY, NovelGPProblem.FALSE);

            for (int i = 0; i < 3; i++) {

                System.out.println("Evolving solution " + signalID + "." + i);

                Evolve e = new Evolve(problem, new ConsoleListener(ConsoleListener.SILENT));

                e.run();

                Individual ind = e.getBestIndividual();

                n.addClassifier(ind, signalID, 1);

                System.out.println("Added classifier, hits=" + ind.getHits() + ", mistakes=" + ind.getMistakes());

                test(n);

                long time = System.currentTimeMillis() - start;

                System.out.println(time + "ms elapsed.");

            }

        }

    }

    public static void test(NoveltyDetector d) {

        System.out.println("Testing detector with " + d.classifiers.size() + " classifiers");

        System.out.println("TRUE: " + getOutput(d, TRUE_DIRECTORY));
        System.out.println("FALSE: " + getOutput(d, FALSE_DIRECTORY));
        System.out.println("UNSUAL: " + getOutput(d, UNUSUAL_DIRECTORY));

    }

    public static String getOutput(NoveltyDetector d, String directoryPath) {

        FastStatistics stats = new FastStatistics();

        File directory = new File(directoryPath);
        if (directory.exists() && directory.isDirectory()) {

            File[] files = directory.listFiles();

            for (int i = 0; i < files.length; i++) {
                File imageFile = files[i];
                try {
                    PixelLoader image = new PixelLoader(imageFile);

                    stats.addData((float) d.execute(image));

                } catch (Exception err) {
                    // don't worry too much
                }
            }

        }

        return "mean=" + stats.getMean() + ", +-" + stats.getStandardDeviation() + " Range=" + stats.getMin() + "-" + stats.getMax();

    }



}
