#ifndef EXAMPLEINCLUDE
#define EXAMPLEINCLUDE

/**
* @file Example.h
* @brief data caching of several feature images and many more
* @author Erik Rodner
* @date 04/21/2008
*/

#include "CachedExample.h"

namespace OBJREC {

/** Cached example with window information */
class Example
{
  public:
    /** weight of example */
    double weight;

    /** complete image example */
    CachedExample *ce;

    /** x position of window */
    long long int x;
    /** y position of window */
    long long int y;

    /** width of window */
    int width;
    /** height of window */
    int height;

    //! if some examples are related, they have the same position
    int position;

    //! scale of the feature
    double scale;

    /** evil workaround: store simple vector example */
    NICE::Vector *vec;

    /** evil workaround: store sparse vector example */
    NICE::SparseVector *svec;

    /** simple constructor, initialize everything with 0
     */
    Example();

    /** constructor using a window covering the whole image
        @param ce associated image data
    */
    Example ( CachedExample *_ce );

    /** constructor
        @param ce associated image data
        @param x x position of window
        @param y y position of window
        @param weight weight of example
    */
    Example ( CachedExample *ce, int x, int y, double weight = 1.0 );

    /** constructor
        @param ce associated image data
        @param x x position of window
        @param y y position of window
        @param weight weight of example
    */
    Example ( CachedExample *ce, int x, int y, int width, int height, double weight = 1.0 );

    /** evil workaround: simple constructors for std::vector examples
        @param vec simple feature vector
        @param weight optional weight
    */
    Example ( NICE::Vector *vec, double weight = 1.0 );

    /**
     * copy constructor
     * @param ex input Example
     */
    Example ( const Example &ex );

    /**
     * copies the values of ex in this example
     * @param ex input Example
     */
    void copy ( const Example &ex );

    /** destructor */
    ~Example ();

    /** delete all data associated with this example
        (sparse vector, vector, cached example, etc.) */
    void clean ();

    /**
     * load from file (warning: no cachedexamples supported yet
     * @param is file
     * @param format
     */
    void restore ( std::istream & is, int format = 0 );


    /**
     * write to file (warning: no cachedexamples supported yet
     * @param is file
     * @param format
     */
    void store ( std::ostream & os, int format = 0 ) const;
};

/** labeled pair of Example
    @see Example */
class Examples : public std::vector< std::pair<int, Example> >
{
  public:
    std::string filename;

    inline int getMaxClassNo () const
    {
      int maxClassno = -1;
      for ( const_iterator i = begin(); i != end(); i++ )
        if ( i->first > maxClassno )
          maxClassno = i->first;

      return maxClassno;
    }

    /** delete all data associated with all examples
        (sparse vector, vector, cached example, etc.) */
    void clean ();

    /**
     * @brief Create an Examples object from a given full matrix of features and a vector of sample labels.
     *
     * The Examples object consists of individual Example objects containing the label and a pointer to the provided raw feature data (stored in variable Example::vec).
     * Note: No feature data is copied - an Example only contains a pointer to the raw double data.
     * An NICE::Vector is created as an wrapper around this raw double pointer using it, but not copying it.
     * You need to take care to delete these wrapper vectors once you're finished working with the Examples object, otherwise you generate a memory leak.
     * Calling Examples::clean() handles this.
     *
     * Note: memory layout needs to be transposed into rows x column: features x samples
     * features must lay next to each other in memory, so that each feature vector can
     * be adressed by a starting pointer and the number of feature dimensions to come.
     *
     * @param p_MatFeaturesColumWiseSamples matrix containing the features (dimension M) of N samples ( M x N matrix )
     * @param p_VecLabels matrix containing the labels for N samples (1xN)
     * @param p_Examples created Examples object (vector of N Example object with each Example containing a valid vec-ptr to the feature data [uncopied] )
     * @return true for successful Examples creation
     * @author Johannes Ruehle
     */
    static bool wrapExamplesAroundFeatureMatrix(const NICE::Matrix &p_MatFeaturesColumWiseSamples, const NICE::Vector &p_VecLabels, Examples &p_Examples);
    static bool wrapExamplesAroundFeatureMatrix(const NICE::Matrix &p_MatFeaturesColumWiseSamples, const NICE::VectorT<int> &p_VecLabels, Examples &p_Examples);
};


} // namespace

#endif
