/** 
* @file LocalizationResult.h
* @brief classification result, what else?
* @author Erik Rodner
* @date 02/13/2008

*/
#ifndef LocalizationResultINCLUDE
#define LocalizationResultINCLUDE

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

#include <string>
#include <vector>
#include <assert.h>
 
#include "ClassificationResult.h"
#include "ClassNames.h"

#include "core/basics/Persistent.h"

#include <core/image/Region.h>
#include <core/image/RectT.h>


namespace OBJREC {

class ImageInfo;

class SingleLocalizationResult 
{
    private:

	/** used for depth ordering */
	int controlPoints; 
	int xi, yi, xa, ya;
	
	bool hasRegionInformation_bool;
	NICE::Region reg;
    
    
    public:
    
	ClassificationResult *r;

    /** Unique object identifier.
     * (set when loading bounding box information from a ImageInfo file.
     * @see ImageInfo::loadImageInfo()
     */
    int objectid;


	SingleLocalizationResult ( ClassificationResult *r, const NICE::Region & reg, int controlPoints = 0 );

    /**
     * @brief constructor
     * @param xi (left)
     * @param yi (top)
     * @param xa (width)
     * @param ya (height)
     */
    SingleLocalizationResult ( ClassificationResult *r, int xi, int yi, int xa, int ya );
	~SingleLocalizationResult ();

    /**
     * @brief get the bounding box
     * @param xi (left)
     * @param yi (top)
     * @param xa (width)
     * @param ya (height)
     */
	void getBoundingBox ( int & xi, int & yi, int & xa, int & ya ) const;
	void getBoundingBox ( NICE::RectT<int> & rectangle ) const;

	void getCentroid ( double & x, double & y ) const;
	bool hasRegionInformation () const { return hasRegionInformation_bool; };
	int getControlPoints () const { return controlPoints; };

	const NICE::Region & getRegion () const { assert (hasRegionInformation_bool); return reg; };

	void addPoint ( int x, int y ) { assert(hasRegionInformation_bool); reg.add(x,y); };

	double getBBOverlapMeasure ( const SingleLocalizationResult & slr ) const;
	double getBBOverlapMeasureMin ( const SingleLocalizationResult & slr ) const;
};


class LocalizationResult : public std::vector<SingleLocalizationResult *>, public NICE::Persistent
{
    private:
	const ClassNames *cn;
	NICE::Image *labeledImage;
	
    public:

  typedef std::vector<SingleLocalizationResult *>::iterator iterator;
  typedef std::vector<SingleLocalizationResult *>::const_iterator const_iterator;

	bool hasLabeledImage;
	int xsize;
	int ysize;

    
    enum {
		FILEFORMAT_PASCAL2006_RESULT = 0,
		FILEFORMAT_PASCAL2006_GROUNDTRUTH,
        FILEFORMAT_POLYGON
    };

    LocalizationResult ( int xsize = -1, int ysize = -1 );
    LocalizationResult ( const ClassNames *cn, int xsize = -1, int ysize = -1);
    LocalizationResult ( const ClassNames *cn, const NICE::Image & img, int classno );
    LocalizationResult ( const ClassNames *cn, const NICE::ColorImage & img );

    ~LocalizationResult ();

    void sortEmpricalDepth();
    void sortDescendingConfidence();
    void getLabeledImageCache ( NICE::Image & mark ) const;
    void calcLabeledImage ( NICE::Image & mark, int backgroundClassNo ) const;
    void setMap ( const NICE::Image & labeledImage );

    void displayBoxes ( NICE::ColorImage & img, 
			const ClassNames *cn = NULL,
			bool display_confidence = true,
			bool invert = false,
			int width = 1) const;

    /**
     * @brief Loads image label information from the file format supported by the ImageLabeler tool.
     *
     * This function ignores the label description (xml section < legend > ) and assumes, that the label names were loaded in advance
     * and are present in the ClassNames reference member variable LocalizationResult::cn.
     *
     * Note: Uses class ImageInfo for loading the xml information and inserts them into this LocalizationResult class.
     * A future TODO would be to directly include the ImageInfo loading code here (or as part of LocalizationResult) to substitute redundancy
     * between the classes ImageInfo and LocalizationResult (meaning both use BoundingBoxes etc).
     *
     * Currently only rectangular bounding box information are transferred from the loaded ImageInfo instance to this class.
     * So, trying to use for instance Polygon data created with the ImageLabeler will fail (empty LocalizationResult).
     *
     * @param sFilename file name of the image label file (usually *.dat, xml formatted)
     * @param selectObjectWithUniqueId unique object id for specifying a bounding box that is to be extracted from the label file(default -1, deactivated)
     * @see OBJREC::ImageInfo
     * @author Johannes Rühle
     * @date 2012-05-11
     */
    void loadImageInfo(std::string sFilename, int selectObjectWithUniqueId = -1);
    void loadImageInfo(ImageInfo &p_ImageInfo, int selectObjectWithUniqueId = -1);

    void restore (std::istream & is, int format = 0);
    void store (std::ostream & os, int format = 0) const;
    void clear ();
    int getMaxClassno () { assert(cn != NULL); return cn->getMaxClassno(); };

};


} // namespace

#endif
