/** 
* @file FCCodebookHistBin.h
* @brief create features with a predefined codebook
* @author Erik Rodner
* @date 02/05/2008

*/
#ifndef FCCODEBOOKHISTBININCLUDE
#define FCCODEBOOKHISTBININCLUDE

#include "core/vector/VectorT.h"
#include "core/vector/MatrixT.h"

#include "core/basics/Config.h"
#include "vislearning/features/fbase/FeatureFactory.h"
#include "vislearning/features/localfeatures/LocalFeatureRepresentation.h"

#include "Codebook.h"


namespace OBJREC {

/** create features with codebook */
class FCCodebookHistBin : public FeatureFactory
{

  protected:
    //! normalization method used (enum type)
    int n_method;

    //! local feature method
  	const LocalFeatureRepresentation *lfrep;

    //! pointer to our codebook
	  const Codebook *codebook;

    void calcHistogram ( const NICE::VVector & features,
             NICE::Vector & histogram );

    void calcHistogram ( const NICE::VVector & features,
             NICE::Vector & histogram,
             NICE::Matrix & assignments);

  	void normalizeHistogram ( NICE::Vector & histogram );

  public:
    //! enum type used for normalization method
  	enum {
	    NORMALIZE_RAW = 0,
	    NORMALIZE_BINZERO,
	    NORMALIZE_SUM,
	    NORMALIZE_THRESH
	  };


    /**
    * @brief standard constructor 
    *
    * @param conf pointer to a Config object with some parameter settings (currently not used)
    * @param lfrep local feature extraction method (keep the pointer!)
    * @param normalizationMethod name of the normalization method (sum, binzero, raw, thresh)
    * @param codebook pointer to the codebook (keep the pointer!)
    */
    FCCodebookHistBin( const NICE::Config *conf,
        const LocalFeatureRepresentation *lfrep,
        const std::string & normalizationMethod,
        const Codebook *codebook );
        
    /** simple destructor */
    virtual ~FCCodebookHistBin();
    
    /**
    * @brief calculate a BoV histogram vector (no local information, only global)
    *
    * @param img input image
    * @param vec resulting feature vector
    *
    * @return -1 if something fails (no local features found for example) and zero if everything was okay 
    */
    int convert ( const NICE::Image & img, NICE::Vector & vec );
    
    /**
    * @brief calculate a BoV histogram vector and also store the assignments of each local feature to a BoV cluster (codebook element)
    *
    * @param features input local features (size is N)
    * @param vec resulting BoV feature vector
    * @param assignments assignments of local features to BoV clusters given as a 3xN matrix, with assignments(0,*) representing the distance
    * of a local feature to the nearest BoV cluster, assignments(1,*) storing the BoV cluster index, and assignments(2,*) being the index of the local feature
    *
    * @return 
    */
    int calcAssignments ( const NICE::VVector & features, NICE::Vector & vec, NICE::Matrix & assignments );

    /**
    * @brief set the type of the normalization method (see the enum of the class)
    *
    * @param normalizationMethod see enum type
    */
    void setNormalizationMethod ( int normalizationMethod );

    /**
    * @brief get the currently used normalization method
    *
    * @return see enum type
    */
    int getNormalizationMethod () const;
     
};


} // namespace

#endif
