package ac.ooechs.oil.util;

import ac.essex.ooechs.imaging.commons.PixelLoader;
import ac.essex.ooechs.imaging.commons.util.panels.ImageFrame;
import ac.essex.ooechs.imaging.commons.window.data.Window;
import ac.essex.ooechs.imaging.commons.window.util.WindowFeatures;
import ac.essex.ooechs.imaging.gp.problems.classification.distance.DistanceClassifier;
import ac.essex.gp.multiclass.BetterDRS;
import ac.essex.gp.multiclass.PCM;
import ac.ooechs.oil.pipeclassification.PipelineClassifier;

import java.io.File;
import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * Analyses the output of the classifier on a particular image.
 *
 * @author Olly Oechsle, University of Essex, Date: 10-Apr-2008
 * @version 1.0
 */
public class ClassifierAnalyser {

    public static void main(String[] args) throws Exception {
        File f = new File("/home/ooechs/Desktop/pipes/pipes1a.bmp");
        new ClassifierAnalyser(f);
    }

    public ClassifierAnalyser(File f) throws Exception {

        PixelLoader subImage = new PixelLoader(f);

        BufferedImage copy = new BufferedImage(subImage.getWidth(), subImage.getHeight(), BufferedImage.TYPE_INT_ARGB);

        BufferedImage copy2 = new BufferedImage(subImage.getWidth(), subImage.getHeight(), BufferedImage.TYPE_INT_ARGB);

        Graphics g = copy.getGraphics();
        Graphics g2 = copy2.getGraphics();

        try {

            int windowWidth = subImage.getWidth();
            int windowHeight = 5;

            // create the windows we want to test
            for (int y = 0; y < subImage.getHeight() - windowHeight; y++) {
                Window window = new Window(windowWidth, windowHeight, 0, y, null);

                double[] features = WindowFeatures.getFeatures(subImage, window);

                double mean = -17.83;
                double maxDist = 71.17;

                double dist = Math.abs(eval(features) - mean);

                // set a colour
                int red = (int) ((dist / maxDist) * 255);
                if (red > 255) red = 255;
                int green = 255 - red;

                g.setColor(new Color(red, green, 0));

                g.fillRect(0, y, subImage.getWidth(), 1);

                g2.setColor(classify(features) != -1? Color.GREEN : eval3(features) != -1? Color.YELLOW : Color.RED);

                g2.fillRect(0, y, subImage.getWidth(), 1);

            }

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

        new ImageFrame(subImage);
        new ImageFrame(copy);
        new ImageFrame(copy2);

    }

    final int correctClassID = 1;
    final double threshold = 10.0;
    final double mean = -17.834495544433594;

    public int classify(double[] feature) {
      if (Math.abs(eval(feature) - mean) < threshold) return 1;
      else return -1;
    }


public double eval(double[] feature) {
    double node8 = feature[3] * 0.45445273909203254;
    double node6 = feature[16] * node8;
    double node5 = node6 / -0.6493517511388426;
    double node3 = 0.0 + node5;
    double node2 = feature[26] != 0 ? node3 / feature[26] : 0;
    double node1 = node2 - feature[18];
    return (node1 + feature[25]) / 2;
}

final int correctClassID2 = 3;
final double threshold2 = 10.0;
final double mean2 = 34.19425582885742;

public int classify2(double[] feature) {
  if (Math.abs(eval2(feature) - mean2) < threshold2) return 3;
  else return -1;
}

protected double eval2(double[] feature) {
    double node2 = feature[20] + feature[9];
    double node1 = node2 * 0.8046773944705619;
    return node1 * 0.31573217884465715;
}

PCM pcm = new BetterDRS(79.13582277297974,281.37593841552734,new int[]{3,3,3,3,-1,3,3,3,-1,-1,-1,-1,-1,3,-1,-1,3,3,3,3,3,-1,-1,3,-1,-1,3,3,0,0,3,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,0,0,-1,0});;
public double eval3(double[] feature) {
    return pcm.getClassFromOutput(feature[18] + feature[27]);
}

}
