package ac.essex.gp.ooechs.novelty2;

import ac.essex.ooechs.imaging.commons.PixelLoader;
import ac.essex.ooechs.imaging.commons.fast.FastStatistics;
import ac.essex.gp.training.TrainingImage;

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

/**
 * <p/>
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version,
 * provided that any use properly credits the author.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details at http://www.gnu.org
 * </p>
 *
 * @author Olly Oechsle, University of Essex, Date: 09-Jun-2008
 * @version 1.0
 */
public class GenerateUnusualData {


    public static void main(String[] args) throws Exception {

        Vector<PixelLoader> trueImages = getImages(NoveltyDetectorFinder.TRUE_TRAINING_DIRECTORY);
        Vector<PixelLoader> falseImages = getImages(NoveltyDetectorFinder.FALSE_DIRECTORY);

        // how many unusual images to create?
        int numImages = 200;


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

            // select a true image at random
            PixelLoader trueImage = trueImages.elementAt((int) (Math.random() * trueImages.size()));

            // select a false image at random
            PixelLoader falseImage = falseImages.elementAt((int) (Math.random() * falseImages.size()));

            Vector<Integer> segmentList = new Vector<Integer>();

            int segments = 0;
            while (segments < 2) {
            // find a random segment in the false image
            int segmentX = (int) (Math.random() * falseImage.getWidth());

                if (segmentList.contains(segmentX)) continue;

                segmentList.add(segmentX);

            double t = analyseSegment(trueImage, segmentX);
            double f = analyseSegment(falseImage, segmentX);

            if (Math.max(t,f) / Math.min(t,f) > 1.2) {
                copySegmentTo(trueImage, falseImage, segmentX);
                segments++;
            }

            }

            trueImage.saveAs(new File(NoveltyDetectorFinder.UNUSUAL_DIRECTORY, "unusual" + i + ".jpg"));

            System.out.println("unusual" + i + ".jpg");

        }



    }

    public static void copySegmentTo(PixelLoader trueImage, PixelLoader falseImage, int x) {
        for (int y = 0; y < trueImage.getHeight(); y++)  {
            trueImage.setRGB(x, y, falseImage.getRGB(x, y));
        }
        if (x < trueImage.getWidth() - 1) {
        for (int y = 0; y < trueImage.getHeight(); y++)  {
            trueImage.setRGB(x+1, y, falseImage.getRGB(x, y));
        }
        }
    }

    public static double analyseSegment(PixelLoader image, int x) {
        FastStatistics f = new FastStatistics();
        for (int y = 0; y < image.getHeight(); y++)  {
            f.addData(image.getGreyValue(x, y));
        }
        return f.getMean();
    }

    public static Vector<PixelLoader> getImages(String directoryPath) {

        Vector<PixelLoader> images = new Vector<PixelLoader>();

        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];

                if (imageFile.isDirectory()) continue;

                try {
                    PixelLoader image = new PixelLoader(imageFile);

                    images.add(image);
                } catch (Exception err) {
                    // don't worry too much
                }
            }

        }

        return images;

    }

}
