#include <iostream>
#include <opencv2/opencv.hpp>

#include "dataunit.hpp"
#include "changedetection.hpp"
#include "preprocess.hpp"
#include "register.hpp"
#include "normalize.hpp"
#include "detectdiff.hpp"
#include "detectratio.hpp"
#include "detectshading.hpp"
#include "detectcorr.hpp"
#include "detectdiffcorr.hpp"
#include "evaluate.hpp"
#include "readdata.hpp"
#include "writeunit.hpp"
#include "detectldd.hpp"
#include "detectltp.hpp"

using namespace std;
using namespace cv;

int main(int argc, char **argv) {

  if( argc < 2 ){
    std::cerr << "Database configuration file (data.xml) is an obligatory \
                  argument.";
    return 1;
  }
  
  ChangeDetection detection;
 
  // Preprocessing pipe
  Preprocess preprocess(3, false);
  detection.addPipe(&preprocess);
  
  // Registration pipe
  Register reg(false);
  detection.addPipe(&reg);
  
  // Normalization pipe
//   Normalize norm;
//   detection.addPipe(&norm);
  
  // Detection pipe
  //DetectCorr detect(16, 16+6, 0.5, CV_TM_SQDIFF_NORMED);
  //DetectDiff detect(0.2);
//   DetectRatio detect(0.5);
//   DetectShading detect(0.04, 21);
//   DetectDiffCorr detect(16, 16+6, 0.35, CV_TM_CCORR_NORMED, 0.25);
//   DetectLDD detect(20, 0.1);
//   DetectLBP detect(11, 130);
  DetectLTP detect(21, 400, 8, 2, 0.07); //11, 155, 195, 220
  // rack04 - 21, 440
  detection.addPipe(&detect);
  
  // Evaluate 
  Evaluate eval;
  eval.setInc(true);
  detection.addPipe(&eval);

  // Write output
  WriteUnit writer;
  detection.addPipe(&writer);
  
  ReadData reader = ReadData( argv[1] );
  ReadData::iterator it = reader.begin();
  for( it; it != reader.end(); ++it ){
    DataUnit unit = *it;
    std::cout << "Temp: " << unit.mPath[TEMP] << " "
              << "Inpu: " << unit.mPath[INPU] << std::endl;
    
    detection.setData( unit );
    DataUnit out = detection.detect();
  }
  
  float precision, recall, fmeas;
  eval.calculate(precision, recall, fmeas);
  
  std::cout << "Precision: " << precision << std::endl;
  std::cout << "Recall: " << recall << std::endl;
  std::cout << "F-measure: " << fmeas << std::endl;
//   
  return 0;
}
