/** 
* @file FPCDecisionTree.cpp
* @brief simple decision tree classifier
* @author Erik Rodner
* @date 04/21/2008

*/
#include <iostream>

#include "vislearning/classifier/fpclassifier/randomforest/FPCDecisionTree.h"
#include "vislearning/features/fpfeatures/HaarFeature.h"

#include "vislearning/classifier/fpclassifier/randomforest/DTBStandard.h"
#include "vislearning/classifier/fpclassifier/randomforest/DTBRandom.h"
#include "vislearning/classifier/fpclassifier/randomforest/DTBPruning.h"

using namespace OBJREC;

using namespace std;

using namespace NICE;


FPCDecisionTree::FPCDecisionTree( const Config *_conf, std::string section ) : conf(_conf), dt(NULL)
{
    std::string builder_method = conf->gS(section, "builder", "standard" );
    std::string builder_section = conf->gS(section, "builder_section" );

    if ( builder_method == "standard" )
	builder = new DTBStandard ( conf, builder_section );
    else if (builder_method == "random" )
	builder = new DTBRandom ( conf, builder_section );
    else {
	fprintf (stderr, "DecisionTreeBuilder %s not yet implemented !\n",
	    builder_method.c_str() );
	exit(-1);
    }
    
    double minimum_entropy = conf->gD(section, "minimum_entropy", 0.0 );
    if ( minimum_entropy != 0.0 )
	builder = new DTBPruning ( _conf, section, builder );
}

FPCDecisionTree::~FPCDecisionTree()
{
    delete builder;
    if ( dt != NULL )
	delete dt;
}

ClassificationResult FPCDecisionTree::classify ( Example & pce )
{
    FullVector distribution;
    dt->traverse ( pce, distribution );
    
    int classno = distribution.maxElement();

    distribution.normalize();

    return ClassificationResult ( classno, distribution );

}

void FPCDecisionTree::train ( FeaturePool & fp,
			      Examples & examples )
{
    maxClassNo = examples.getMaxClassNo();
    if ( dt != NULL )
	delete dt;
    dt = new DecisionTree ( conf, maxClassNo );
    builder->build ( *dt, fp, examples, maxClassNo );
}