/**
* @file ImageInfo.h
* @brief localization info + image filename + ?
* @author Erik Rodner
* @date 04/16/2008
*/
#ifndef IMAGEINFOINCLUDE
#define IMAGEINFOINCLUDE

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

#include "vislearning/cbaselib/Polygon.h"
#include "vislearning/cbaselib/BoundingBox.h"
#include "vislearning/cbaselib/CategoryInfo.h"

#include "LocalizationResult.h"
#include <assert.h>

#ifdef NICE_USELIB_QT4_XML

class QString;
class QDomElement;

#endif //NICE_USELIB_QT4_XML

namespace OBJREC
{

/**
 * @brief Class for loading label information created by the ImageLabeler tool.
 *
 * The label file format is xml consisting of several sections about the label desription,
 * occuring objects (such as bounding boxes and polygons) and their label ids, and reference to the
 * original image file.
 *
 * Note: Be aware of the code redundancy of the xml loading presented here and the separate code in the ImageLabeler tool.
 * Both try to interprete/load the label xml but with different code, so changes at one code place do not affect the other one.
 *
 * Second note/todo: in future this class should complete be integrated into LocalizationResult, which also includes bounding box label info
 * and is more integrated into NICE feature extraction and classification mechanism.
 * Currently, to convert a loaded label file into a LocalizationResult, use function LocalizationResult::loadImageInfo() (currently only bounding box information).
 *
 * localization info + image filename + ?
 */
class ImageInfo
{

  protected:
    std::string imagefn;
    LocalizationResult *lr;
    bool localization_info;

#ifdef NICE_USELIB_QT4_XML

    virtual bool polyFromData( QString *aPolyData, Polygon &p_Poly);
    virtual bool BBoxFromData(QString *aBBoxData, int &id , BoundingBox &p_bbox);

    virtual void extractSectionLegend ( QDomElement *anElement );
    virtual bool extractSectionImage(QDomElement *element, const std::string &p_sImageInfoFilename );
    virtual bool extractSectionSegmented(QDomElement *element );
    virtual bool extractSectionDescription(QDomElement *element );
    virtual bool extractSectionTags(QDomElement *element );
    virtual bool extractSectionObjects(QDomElement *element );
    virtual bool extractObjectPolygon(QDomElement *element );
    virtual bool extractObjectRectangle(QDomElement *element );
    virtual bool extractImageSize(QDomElement *element );
    virtual bool extractSectionPureData(QDomElement *element );
    virtual bool loadCategoryInfo ( QDomElement *anElement );


    NICE::ImageT< unsigned int > imageTFromData (
      const int &aWidth,
      const int &aHeight,
      QString *aPureData
    );



#endif //NICE_USELIB_QT4_XML

  public:

    /**
     * @brief simple constructor
     * @param _imagefn image file name
     * @param _lr Localization result containing label information
     */
    ImageInfo ( const std::string & _imagefn, LocalizationResult *_lr ) :
        imagefn ( _imagefn ), lr ( _lr ), localization_info ( true ) {};

    ImageInfo() {};

    ImageInfo ( const std::string & _imagefn ) :
        imagefn ( _imagefn ), lr ( NULL ), localization_info ( false ) {};

    /** simple destructor */
    virtual ~ImageInfo();

    const std::string & img () const
    {
      return imagefn;
    };

    /**
    * @brief Returns available localization information.
    *
    * Note: This class doesn't create a new LocalizationResult instance - it only returns the reference to a previously assigned instance (see constructor).
    * To convert a loaded label file into a LocalizationResult, use function LocalizationResult::loadImageInfo() (currently only bounding box information).
    * @see LocalizationResult::loadImageInfo()
    */
    const LocalizationResult *localization () const
    {
      assert ( localization_info );
      return lr;
    };
    bool hasLocalizationInfo () const
    {
      return localization_info;
    };

    virtual bool loadImageInfo ( const std::string &aFilename );

    const std::list< CategoryInfo > * labels() const;
    const std::list< BoundingBox > * bboxes() const;
    const std::list< Polygon > * polys() const;
    NICE::ImageT< unsigned int > labeledImage() const;
    std::string tags() const;
    std::string imagePath() const;
    std::string imageDescription() const;
    std::string segmentedImagePath() const;

    void setListOfPolygons( std::list< Polygon > &p_polys )
    {
        polys_ = p_polys;
    }
  protected:
    std::list< CategoryInfo > labels_;
    std::list< BoundingBox > bboxes_;
    std::list< Polygon > polys_;
    NICE::ImageT< unsigned int > labeled_image_;
    //std::list< std::string > tags_;
    std::string tags_;
    std::string image_path_;
    std::string image_description_;
    std::string segmented_image_path_;
    int m_iImageWidth;
    int m_iImageHeight;

};


} // namespace

#endif
