/**
 * @version $Id: JsonObjectsTracker.h 23039 2011-07-04 07:47:47Z nkrachkovsky $
 * ------------------------------------------------------------------------------
 * This class represents JsonObjectsTracker class for rendering analytics and
 * metadata from Json representation
 * ------------------------------------------------------------------------------
 * @author Nickolay Krachkovsky
 * @QA
 * @copyright videoNEXT Network Solutions LLC 2010
 * ------------------------------------------------------------------------------
 */

#ifndef JSONOBJECTSTRACKER_H
#define JSONOBJECTSTRACKER_H

#include <stdio.h>
#include <map>
#include <set>
#include <vector>
#include <list>
#include <string>
#include <boost/shared_ptr.hpp>

#if defined( WIN32 ) && defined( _MSC_VER )
#include <WinSock2.h>
#endif

#include "AbstractObjectsTracker.h"

#define OBJEVT_COUNT 2
#define MLPG_COUNT 3
#define MILLION 1000000

namespace Json { class Value; }

class JsonObjectsTracker : public AbstractObjectsTracker
{
public:
    JsonObjectsTracker();
    virtual ~JsonObjectsTracker();

    virtual void setObjectsData(const std::string& Bitstream);

    virtual void setMetadataInfo(const std::map< std::string, std::vector< std::string > >& VisibleMetadata);

    /**
     * Draw analytics objects over some part of zoomed im image at any place of the destination screenRect
     */
    virtual void parseAndDraw(Graphics* g2, const Rectangle2& dstRect, const Rectangle2& srcRect, float zoomFactor);

    virtual std::list<LinkEntry> linksList();

    void clearObjects();
    
    void log_debug( const std::string& msg ) { fprintf(stderr, "%s\n", msg.c_str()); }
protected:
    class RenderObject
    {
    public:
        virtual ~RenderObject();
        void setObj( long long now, double Lifetime, int LineWidth, Color ObjectColor );
        void setObj( const RenderObject& ro );
        virtual void draw( JsonObjectsTracker* jsot );
        bool isAlive( long long now ) const;
    public:
        long long start;
        long long finish;
        int lineWidth;
        Color color;
    };
    typedef boost::shared_ptr< RenderObject > RenderObjectPtr;

    class BBObject : public RenderObject
    {
    public:
        virtual void draw( JsonObjectsTracker* jsot );
    public:
        int x, y;
        int w, h;
    };
    typedef boost::shared_ptr< BBObject > BBObjectPtr;

    class MLine : public RenderObject
    {
    public:
        virtual void draw( JsonObjectsTracker* jsot );
        void preparePointData( JsonObjectsTracker* jsot );
        bool isNativeDraw();
    public:
        std::vector< Point2 > points;
        bool is_native_draw;
    };
    typedef boost::shared_ptr< MLine > MLinePtr;

    class Polygon : public MLine
    {
    public:
        virtual void draw( JsonObjectsTracker* jsot );
    };
    typedef boost::shared_ptr< Polygon > PolygonPtr;

    class Text : public RenderObject
    {
    public:
        Text() : x(0), y(0), h(12), style(Graphics::Regular), horz_align(Graphics::Left), vert_align(Graphics::Top)
        { }
        virtual void draw( JsonObjectsTracker* jsot );
    public:
        int x, y;
        float h;
        std::string msg;
        //std::string style;
        Graphics::FONT_STYLE style;
        std::string font;
        Graphics::HORZ_ALIGN horz_align;
        Graphics::VERT_ALIGN vert_align;
    };
    typedef boost::shared_ptr< Text > TextPtr;

    class Metadata : public Text
    {
    public:
        virtual void draw( JsonObjectsTracker* jsot );
    public:
        std::string meta_id;
    };
    typedef boost::shared_ptr< Metadata > MetadataPtr;

    typedef std::map< std::string, BBObjectPtr > bboxes_map_t;
    typedef std::map< std::string, RenderObjectPtr > object2_map_t;
    typedef std::map< std::string, object2_map_t > object_map_t;
    typedef std::list< RenderObjectPtr > objects_list_t;

private:
    bool parseMLPVertecies( MLinePtr ml, const Json::Value& jsPoints );
    std::list< RenderObjectPtr > parseMLinePolygon( int mp, const Json::Value& js, const Json::Value& parent, const std::string& extraInfo = std::string() );
    TextPtr parseTextMetadata( int tm, const Json::Value& js, const Json::Value& parent, const std::string& extraInfo = std::string() );
    void parseRootObject( const Json::Value& js );

    void updateTrails();

    void drawTextLinks();

protected:
    static const char* objs_evts[OBJEVT_COUNT];
    static const char* ml_pg[MLPG_COUNT];
    static std::set< std::string > notObjIds;

    static std::set< std::string > genNotObjsIds();
    static const Json::Value getProp( const char* prop, const Json::Value& js, const Json::Value& parent );

protected:
    bboxes_map_t bboxes[OBJEVT_COUNT];
    object_map_t objmap;
    objects_list_t objects;

    bool calc_trail;

private: // temporal objects
    Graphics* graph;
    //int im_height;
    //Rectangle2 screenRect;

    Rectangle2 dstRect;
    Rectangle2 srcRect;
    float zoomFactor;
    float kW;
    float kH;
    float metaY[9];

    std::vector<int> xPoints;
    std::vector<int> yPoints;
    std::map< std::string, std::vector< std::string > > visibleMetadata;

    std::list<LinkEntry> lprOutNumbers;
};

#endif // JSONOBJECTSTRACKER_H
