package ac.essex.ooechs.facedetection.util.evaluation;

import ac.essex.gp.multiclass.PCM;
import ac.essex.gp.multiclass.BetterDRS;
import ac.essex.ooechs.imaging.commons.PixelLoader;
import ac.essex.ooechs.imaging.commons.HaarRegions;
import ac.essex.ooechs.imaging.commons.fast.HaarlikeFeatures;
import ac.essex.ooechs.facedetection.singlestage.nodes.FeatureUtils;
import ac.essex.ooechs.adaboost.AdaBoostSolution;
import ac.essex.ooechs.adaboost.AdaBoostSample;

import java.io.File;

/**
 * Detects non-smiling mouths in a window.
 *
 * @author Olly Oechsle, University of Essex, Date: 07-Jul-2008
 * @version 1.0
 */
public class MouthDetector extends ObjectDetector {

    PCM pcm0 = new BetterDRS(-42.355694078885904, 13.284232126998397, new int[]{0, 0, -1, 0, 0, 0, -1, 0, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0});

    public static void main(String[] args) throws Exception {
        //MouthDetector d = new MouthDetector();
        ObjectDetector d = getDetector(AdaBoostSolution.load(new File("/home/ooechs/Desktop/boosteddetectionproblem.solution")));
        d.test(new File("/home/ooechs/Data/me/mouth/mouth"));
        d.test(new File("/home/ooechs/Data/me/mouth/neither"));
    }

    public static ObjectDetector getDetector(final AdaBoostSolution s) {
        return new ObjectDetector() {
            public double calculate(int x, int y, int windowWidth, int windowHeight, PixelLoader img) {
                try {
                    FeatureUtils.windowX = x;
                    FeatureUtils.windowY = y;
                    FeatureUtils.windowWidth = windowWidth;
                    FeatureUtils.windowHeight = windowHeight;
                    return s.classify(new AdaBoostSample(img.getIntegralImage()), null);
                } catch (ArrayIndexOutOfBoundsException e) {
                    return ObjectDetector.NOT_OBJECT;
                }
            }
        };
    }

    public double calculate(int x, int y, int windowWidth, int windowHeight, PixelLoader img) {

        HaarlikeFeatures image = img.getIntegralImage().getHaarlikeFeatures();
        HaarlikeFeatures varianceimage = img.getIntegralImage().getHaarlikeFeaturesVariance();

        double node3 = image.getThreeRectangleFeature(x + FeatureUtils.getX(0.6163741048922656, windowWidth), y + FeatureUtils.getY(0.5940488829639966, windowHeight), FeatureUtils.getWidth(0.19830593481932512, windowWidth), FeatureUtils.getHeight(0.7183713917997199, windowHeight), HaarRegions.HORIZONTALLY_ADJACENT);
        double node8 = Math.pow(0.0, 8.0);
        double node2 = Math.min(node3, node8);
        double node11 = varianceimage.getFourRectangleFeature(x + FeatureUtils.getX(0.0, windowWidth), y + FeatureUtils.getY(0.0, windowHeight), FeatureUtils.getWidth(0.0, windowWidth), FeatureUtils.getHeight(0.0, windowHeight), HaarRegions.VERTICALLY_ADJACENT);
        double node17 = varianceimage.getFourRectangleFeature(x + FeatureUtils.getX(0.0690592262004962, windowWidth), y + FeatureUtils.getY(0.09151450499667191, windowHeight), FeatureUtils.getWidth(0.21547848337764985, windowWidth), FeatureUtils.getHeight(0.286501482625369, windowHeight), HaarRegions.VERTICALLY_ADJACENT);
        double node24 = image.getTwoRectangleFeature(x + FeatureUtils.getX(0.7463843764235815, windowWidth), y + FeatureUtils.getY(0.39544271662453034, windowHeight), FeatureUtils.getWidth(0.6437957338427405, windowWidth), FeatureUtils.getHeight(0.8935038281895208, windowHeight), HaarRegions.HORIZONTALLY_ADJACENT);
        double node30 = varianceimage.getTwoRectangleFeature(x + FeatureUtils.getX(0.5094481337252965, windowWidth), y + FeatureUtils.getY(0.08183367939613417, windowHeight), FeatureUtils.getWidth(0.26023679268817956, windowWidth), FeatureUtils.getHeight(0.7394701211982279, windowHeight), HaarRegions.VERTICALLY_ADJACENT);
        double node29 = node30 - 0.5748749548284215;
        double node23 = node29 != 0 ? node24 / node29 : 0;
        double node37 = varianceimage.getThreeRectangleFeature(x + FeatureUtils.getX(0.0, windowWidth), y + FeatureUtils.getY(0.0, windowHeight), FeatureUtils.getWidth(0.0, windowWidth), FeatureUtils.getHeight(0.0, windowHeight), HaarRegions.HORIZONTALLY_ADJACENT);
        double node42 = varianceimage.getFourRectangleFeature(x + FeatureUtils.getX(0.0, windowWidth), y + FeatureUtils.getY(0.0, windowHeight), FeatureUtils.getWidth(0.0, windowWidth), FeatureUtils.getHeight(0.0, windowHeight), HaarRegions.HORIZONTALLY_ADJACENT);
        double node36 = node37 + node42;
        double node50 = 0.01708290015290226 - 0.35327848159006503;
        double node54 = varianceimage.getFourRectangleFeature(x + FeatureUtils.getX(0.0, windowWidth), y + FeatureUtils.getY(0.0, windowHeight), FeatureUtils.getWidth(0.0, windowWidth), FeatureUtils.getHeight(0.0, windowHeight), HaarRegions.HORIZONTALLY_ADJACENT);
        double node53 = node54 * 8.0;
        double node60 = varianceimage.getThreeRectangleFeature(x + FeatureUtils.getX(0.620633893599036, windowWidth), y + FeatureUtils.getY(0.26619338580772733, windowHeight), FeatureUtils.getWidth(0.8108946598964837, windowWidth), FeatureUtils.getHeight(0.8184914572731952, windowHeight), HaarRegions.HORIZONTALLY_ADJACENT);
        double node49 = node50 > 0 ? node53 : node60;
        double node65 = image.getThreeRectangleFeature(x + FeatureUtils.getX(0.0918884591336413, windowWidth), y + FeatureUtils.getY(0.8448968977760692, windowHeight), FeatureUtils.getWidth(0.23140321033680333, windowWidth), FeatureUtils.getHeight(0.49825662514141156, windowHeight), HaarRegions.VERTICALLY_ADJACENT);
        double node48 = Math.pow(node49, node65);
        double node47 = Math.min(node48, 1.0);
        double node22 = node23 > 0 ? node36 : node47;
        double node75 = 1.0 > 0 ? 0.09142156947521107 : 0.06105868500258316;
        double node79 = 0 - 3.0;
        double node74 = node75 > 0 ? node79 : 3.0;
        double node85 = image.getTwoRectangleFeature(x + FeatureUtils.getX(0.14634525170485135, windowWidth), y + FeatureUtils.getY(0.7247833413656248, windowHeight), FeatureUtils.getWidth(0.9257519014402844, windowWidth), FeatureUtils.getHeight(0.1681209667414857, windowHeight), HaarRegions.VERTICALLY_ADJACENT);
        double node84 = Math.pow(node85, 0);
        double node95 = image.getThreeRectangleFeature(x + FeatureUtils.getX(0.9956353475212784, windowWidth), y + FeatureUtils.getY(0.5131736242404181, windowHeight), FeatureUtils.getWidth(0.6211611458242713, windowWidth), FeatureUtils.getHeight(0.6888070283705918, windowHeight), HaarRegions.HORIZONTALLY_ADJACENT);
        double node100 = image.getFourRectangleFeature(x + FeatureUtils.getX(0.015355430586733942, windowWidth), y + FeatureUtils.getY(0.1134438606374365, windowHeight), FeatureUtils.getWidth(0.3989607022808961, windowWidth), FeatureUtils.getHeight(0.1612375135906915, windowHeight), HaarRegions.HORIZONTALLY_ADJACENT);
        double node94 = node100 != 0 ? node95 / node100 : 0;
        double node106 = varianceimage.getThreeRectangleFeature(x + FeatureUtils.getX(0.9027152207834868, windowWidth), y + FeatureUtils.getY(0.43648673074462274, windowHeight), FeatureUtils.getWidth(0.0172374981543576, windowWidth), FeatureUtils.getHeight(0.34622630144516564, windowHeight), HaarRegions.VERTICALLY_ADJACENT);
        double node111 = image.getFourRectangleFeature(x + FeatureUtils.getX(0.7839456520719608, windowWidth), y + FeatureUtils.getY(0.3838770968354842, windowHeight), FeatureUtils.getWidth(0.7874349173932171, windowWidth), FeatureUtils.getHeight(0.27585934843334325, windowHeight), HaarRegions.VERTICALLY_ADJACENT);
        double node105 = Math.pow(node106, node111);
        double node93 = Math.min(node94, node105);
        double node83 = Math.pow(node84, node93);
        double node73 = Math.max(node74, node83);
        double node116 = 4.0 - 0;
        double node72 = Math.max(node73, node116);
        double node71 = node72 + 0;
        double node16 = node17 > 0 ? node22 : node71;
        double node1 = node2 > 0 ? node11 : node16;
        double node120 = varianceimage.getTwoRectangleFeature(x + FeatureUtils.getX(0.16772553881962984, windowWidth), y + FeatureUtils.getY(0.27219575904360543, windowHeight), FeatureUtils.getWidth(0.07820326762657288, windowWidth), FeatureUtils.getHeight(0.2943909969786083, windowHeight), HaarRegions.VERTICALLY_ADJACENT);
        return pcm0.getClassFromOutput(node1 - node120);
    }

}