/**
* @file LFonHSG.h
* @brief This class can be used to calculate the positions of keyfeatures in a Honeyrate Structure Grid (HSG). Also the class call the normal getDescriptors methode from a given type of LocalFeature.
* @author Eric Bach, Alexander Freytag
* @date 26-10-2011 (dd-mm-yyyy)
*/

#ifndef LFonHSGINCLUDE
#define LFonHSGINCLUDE

/** standard includes **/
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

/** NICE includes **/
#include <core/basics/Config.h>
// 
#include <core/image/Convert.h>
#include <core/image/ImageT.h>
// 
#include <core/vector/VectorT.h>
#include <core/vector/MatrixT.h>
#include <core/vector/VVector.h>

/** LocalFeature*-header includes **/
#include "LocalFeatureRepresentation.h"
#include "GenericLocalFeatureSelection.h"

/** STRINGTOOLS **/
/** 1) boost **/
#ifdef NICE_USELIB_BOOST
#include <boost/tokenizer.hpp>
/** 2) NICE (standard) **/
#else
#include <core/basics/StringTools.h>
#endif

namespace OBJREC
{
class LFonHSG : public LocalFeatureRepresentation
{
    /* private member */
  private:
    
    //! if true, print some log-output
    bool debug;
    
    /* parameter for the grid */
    //! stepwidhts of the grid
    int sampleScaling;
    //! which scales should be used
    std::string scales;
    //! vector which save the different scales
    std::vector <float> scalesV;

    //! the descriptor instance
    OBJREC::LocalFeature* lf;    
    
    /** Calculate the keypoint-positions by given imagesize, sample-spacing and scales.
        @brief The methode returns the calculated positions on a honeyrate-grid. This
        positions starts with (0;0).
        @param[in] unsigned int imageWidth  - width (x) of the given image
        @param[in] unsigned int imageHeight - heigth (y) of the given image
        @param[in,out] NICE::VVector positions    - destination for the calculated positions
    **/
    void getPositionsOnHSG ( const unsigned int imageWidth,
                             const unsigned int imageHeight,
                             NICE::VVector& positions ) const;
    
    protected:
    void convertScalesStringToScaleList ( );


    /* public member */
  public:
    
    ///////////////////// ///////////////////// /////////////////////
    //                   CONSTRUCTORS / DESTRUCTORS
    ///////////////////// ///////////////////// /////////////////////    
    
    /** 
     * @brief default constructor
     * @date 10-02-2014 (dd-mm-yyyy )
     * @author Alexander Freytag
     */
    LFonHSG ( );     
    
    //! simple contructor
    LFonHSG ( const NICE::Config * _conf, const std::string _confSection = "LFonHSG" /*NOTE previous default: "HSG"*/);
    
    //! simple desctructor
    virtual ~LFonHSG();
    
    /** 
     * @brief Jobs previously performed in the config-version of the constructor, read settings etc.
     * @author Alexander Freytag
     * @date 10-02-2014 ( dd-mm-yyyy )
     */    
    void initFromConfig ( const NICE::Config * _conf, const std::string & _confSection = "LFonHSG");     

    ///////////////////// ///////////////////// /////////////////////
    //                      FEATURE STUFF
    ///////////////////// ///////////////////// //////////////////           
    
    //! Returns the descriptorsize
    int getDescSize() const;

    //! Extract the descriptor-Values from a given grayscale-Image.
    int extractFeatures ( const NICE::Image & img, NICE::VVector & features, NICE::VVector & positions ) const;

    //! Extract the descriptor-Values from a given color-Image.
    int extractFeatures ( const NICE::ColorImage & cimg, NICE::VVector & features, NICE::VVector & positions ) const;

    //! Visualisierung
    void visualizeFeatures ( NICE::Image & mark, const NICE::VVector & positions, size_t color ) const;
    
    ///////////////////// INTERFACE PERSISTENT /////////////////////
    // interface specific methods for store and restore
    ///////////////////// INTERFACE PERSISTENT /////////////////////   
    
    /** 
     * @brief Load object from external file (stream)
     * @author Alexander Freytag
     * @date 10-02-2014 ( dd-mmyyyy)
     */     
    virtual void restore ( std::istream & is, int format = 0 );
    
    /** 
     * @brief Save object to external file (stream)
     * @author Alexander Freytag
     * @date 10-02-2014 ( dd-mmyyyy)
     */       
    virtual void store( std::ostream & os, int format = 0 ) const;
    
    /** 
     * @brief Clear  object
     * @author Alexander Freytag
     * @date 10-02-2014 ( dd-mmyyyy)
     */    
    virtual void clear ();     
};
}
#endif
