/**
 * @file FeatureLearningPrototypes.h
 * @brief compute new histogram entries somehow, represent clusters only based on representatives, no additional information like dimensionwise variances...
 * @author Alexander Freytag
 * @date 17-04-2013 (dd-mm-yyyy)
*/
#ifndef _INCLUDEFEATURELEARNINGPROTOTYPES
#define _INCLUDEFEATURELEARNINGPROTOTYPES

#include "FeatureLearningGeneric.h"


#include <core/vector/Distance.h>
#include <core/vector/VVector.h>

#include <vislearning/cbaselib/MultiDataset.h>
// 
#include <vislearning/features/localfeatures/GenericLocalFeatureSelection.h>
#include <vislearning/features/simplefeatures/CodebookPrototypes.h>
// 
#include <vislearning/math/cluster/ClusterAlgorithm.h>




namespace OBJREC
{

  /**
   * @class FeatureLearningPrototypes
   * @brief compute new histogram entries somehow, represent clusters only based on representatives, no additional information like dimensionwise variances...
   * @author Alexander Freytag
   * @date 17-04-2013 (dd-mm-yyyy)
  */  
  
  class FeatureLearningPrototypes : public FeatureLearningGeneric
  {

    protected:
      
      /************************
       * 
       *   protected variables
       * 
       **************************/       
           
      bool showTrainingImages;
      
      //! define the initial number of clusters our codebook shall contain
      int initialNumberOfClusters;       
      
      OBJREC::ClusterAlgorithm * clusterAlgo;      
  
      NICE::VectorDistance<double> * distFunction;

      LocalFeatureRepresentation * featureExtractor;
      
      //! The currently known "cluster" centers, which are used for BoW histogram computation 
//       NICE::VVector prototypes;     
      OBJREC::CodebookPrototypes prototypes;   
            
      int newImageCounter;
      //just needed for visualisation
      double oldMaxDist;
      
      //TODO stupid!!!
      double maxValForVisualization;
      
      //! just for temporary debugging
      int i_posXOfNewPrototype;
      int i_posYOfNewPrototype;      
            
      
      /************************
       * 
       *   protected methods
       * 
       **************************/
            
      void setClusterAlgo( const std::string & _clusterAlgoString);
      void setFeatureExtractor( const bool & _setForTraining = false);
      
      void extractFeaturesFromTrainingImages(  const OBJREC::MultiDataset *_md,  NICE::VVector & examplesTraining  ); 
      
      void train ( const OBJREC::MultiDataset *_md ); 
      
      virtual bool loadInitialCodebook ( );
      virtual bool writeInitialCodebook ( );      
      
      virtual void evaluateCurrentCodebookForGivenFeatures (  const NICE::VVector & _features,
                                                              const NICE::VVector & _positions,
                                                              NICE::FloatImage & _noveltyImageGaussFiltered,
                                                              NICE::FloatImage * _noveltyImage = NULL                                                              
                                                            );

    public:

      /** constructor
        * @param _conf needs a configfile
        * @param _md and a MultiDataset (contains images and other things)
        * @param _section section information for parsing config files
        */
      FeatureLearningPrototypes ( const NICE::Config *_conf, const OBJREC::MultiDataset *_md , const std::string & _section = "featureLearning");

      /** simple destructor */
      virtual ~FeatureLearningPrototypes();
      
      /** this function has to be overloaded by all subclasses
          @param imgWithNovelContent 
      */
      virtual void learnNewFeatures ( const std::string & _filename ) = 0 ;
      
      virtual NICE::FloatImage evaluateCurrentCodebookByDistance ( const std::string & _filename , const bool & beforeComputingNewFeatures = true );
      
      virtual NICE::ImageT<int> evaluateCurrentCodebookByAssignments ( const std::string & _filename , const bool & beforeComputingNewFeatures = true, const bool & _binaryShowLatestPrototype = false);            
      
      virtual void evaluateCurrentCodebookByConfusionMatrix( NICE::Matrix & _confusionMat ); 
      
      virtual NICE::VVector * getCurrentCodebook();
      

  };


} // namespace

#endif