package ac.essex.ooechs.facedetection.util;

import ac.essex.ooechs.ecj.haar.solutions.*;
import ac.essex.ooechs.ecj.haar.util.Combination;

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

/**
 * <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-Nov-2006
 * @version 1.0
 */
public class Combiner {

    // allow combination of three detectors.
    // exhaustive combinations

    // for each detector

    // for each detector

    // for each detector

    // at each stage there are the following possibilities:
    // accept False decision
    // accept True decision
    // return false anyway
    // return true anyway
    // use another detector

    Vector<FaceDetector> combinations;
    Vector<FaceDetector> faceDetectors;

    public static void main(String[] args) {
        new Combiner();
    }

    public Combiner() {
        combinations = new Vector<FaceDetector>(100);
        faceDetectors = new Vector<FaceDetector>(100);
        getDetectors2();
        createCombinations();
    }

    public void getDetectors2() {
        faceDetectors.add(new FP2_FaceDetector311());
        faceDetectors.add(new FINAL_FaceDetector001());
        faceDetectors.add(new FP_FaceDetector154());
        faceDetectors.add(new min_max_mean2_FaceDetector283());
        faceDetectors.add(new min_max_mean3_FaceDetector426());
        faceDetectors.add(new SAVED_WEAK_CLASSIFIERS_32x40FaceDetector001());
        faceDetectors.add(new SAVED_WEAK_CLASSIFIERS_32x40FaceDetector005());
        faceDetectors.add(new SAVED_WEAK_CLASSIFIERS_32x40FaceDetector016());
    }

    public void getDetectors() {

        File detectorDirectory = new File("/home/ooechs/ecj-common/classes/ac/essex/ooechs/ecj/haar/solutions/");
        File[] detectors = detectorDirectory.listFiles();

        System.out.println("Loading detectors...");

        for (int i = 0; i < detectors.length && i < 20; i++) {
            File detector = detectors[i];
            String className = detector.getName().substring(0,detector.getName().indexOf(".class"));
            if (className.equals("FaceDetector")) continue;
            if (className.startsWith("Comb")) continue;
            try {
                faceDetectors.add((FaceDetector) Class.forName("ac.essex.ooechs.ecj.haar.solutions." + className).newInstance());
            } catch (ClassCastException e) {
                // no harm done.
                System.out.println(className + " is not a face detector");
            } catch (Exception e) {
                System.out.println("CLASSNAME:" + className);
                e.printStackTrace();
            }
        }

        System.out.println("Loaded " + faceDetectors.size() + " detectors.");

    }

    public Vector<FaceDetector> createCombinations() {

        System.out.println("Creating combinations");

        for (int i = 0; i < faceDetectors.size(); i++) {

            FaceDetector solution1 = faceDetectors.elementAt(i);

            for (int type1 = 1; type1 <= 5; type1++) {

            for (int j = 0; j < faceDetectors.size(); j++) {

                FaceDetector solution2 = faceDetectors.elementAt(j);

                for (int type2 = 1; type2 <= 5; type2++) {

                    for (int k = 0; k < faceDetectors.size(); k++) {

                        FaceDetector solution3 = faceDetectors.elementAt(k);

                        for (int type3 = 1; type3 <= 3; type3++)  {

                            Combination c1 = new Combination(solution1, type1);
                            Combination c2 = new Combination(solution2, type2);
                            Combination c3 = new Combination(solution3, type3);

                            c1.setChild(c2);
                            c2.setChild(c3);

                            combinations.add(new CombinationDetector(c1));

                        }

                    }

                }

            }

            }

        }

        System.out.println("Made " + combinations.size() + " combinations");

        return combinations;

    }




}

