#ifndef __DRAWINGLIST_H
#define __DRAWINGLIST_H

/**
 *******************************************************************************
 *
 * @file drawingList.h
 *
 * \class CDrawingList
 * \date  Tue Oct 13, 2009
 * \author Hernan Badino (hernan.badino@gmail.com)
 *
 * \brief This class maintains a list of primitives drawings and draw them on
 * a the current opengl context.
 *
 * The drawing list class provides a drawing tool for displaying or storing
 * drawings. Drawing primitives are rectangles, ellipses, lines, images, etc.
 *
 *******************************************************************************/

/* INCLUDES */
#include "colors.h"
#include "lineList.h"
#include "rectList.h"
#include "ellipseList.h"
#include "triangleList.h"
#include "displayImageList.h"
#include "displayCEImageList.h"

#include "colorEncoding.h"

#include "standardTypes.h"

#include <string>

/* CONSTANTS */


/* DATA TYPES */


/* PROTOTYPES */


namespace VIC
{
    class CDrawingList
    {
    public:
    /// Construction, Destruction
    public:
        CDrawingList( std::string f_name_str = "Unnamed Drawing List" );
        virtual ~CDrawingList();
    
        /// Get the name of the drawing list.
        virtual std::string getName ( ) const { return m_name_str; }

        /// Add line.
        virtual bool        addDrawingList ( const CDrawingList &f_other );

        ////// Add primitive drawings.
        /// Add image.
        virtual bool        addImage ( const CImageBase & f_img,
                                       const float        f_u_f,
                                       const float        f_v_f,
                                       const float        f_width_f,
                                       const float        f_height_f,
                                       const float        f_scale_f  = 1.f,
                                       const float        f_offset_f = 0.f,
                                       const float        f_alpha_f  = 1.f,
                                       const bool         f_makeCopy_b = false);
        
        /// Add image.
        virtual bool        addColorEncImage ( const CImageBase *   f_img_p,
                                               const float          f_u_f,
                                               const float          f_v_f,
                                               const float          f_width_f,
                                               const float          f_height_f,
                                               const CColorEncoding f_encoder,
                                               const float          f_alpha_f = 1.f,
                                               const bool           f_makeCopy_b = false);
        
        /// Add line.
        virtual bool        addLine ( const float f_u1_f, const float f_v1_f,
                                      const float f_u2_f, const float f_v2_f );
 
        /// Add line.
        virtual bool        addLine ( const S2D<float> &f_point1, 
                                      const S2D<float> &f_point2 );

        /// Add rectangle.
        virtual bool        addRectangle ( const float f_u1_f, const float f_v1_f,
                                           const float f_u2_f, const float f_v2_f );

        /// Add rectangle.
        virtual bool        addRectangle ( const S2D<float> &f_tl, 
                                           const S2D<float> &f_br );

        /// Add filled rectangle.
        virtual bool        addFilledRectangle ( const float f_u1_f, const float f_v1_f,
                                                 const float f_u2_f, const float f_v2_f );
        
        /// Add filled rectangle.
        virtual bool        addFilledRectangle ( const S2D<float> &f_tl, 
                                                 const S2D<float> &f_bt );

        /// Add line.
        virtual bool        addTriangle ( const float f_u1_f, const float f_v1_f,
                                          const float f_u2_f, const float f_v2_f,
                                          const float f_u3_f, const float f_v3_f );

        /// Add triangle.
        virtual bool        addTriangle ( const S2D<float> &f_vertex1, 
                                          const S2D<float> &f_vertex2, 
                                          const S2D<float> &f_vertex3 );

        /// Add filled triangle.
        virtual bool        addFilledTriangle ( const float f_u1_f, const float f_v1_f,
                                                const float f_u2_f, const float f_v2_f,
                                                const float f_u3_f, const float f_v3_f );

        /// Add filled triangle.
        virtual bool        addFilledTriangle ( const S2D<float> &f_vertex1, 
                                                const S2D<float> &f_vertex2, 
                                                const S2D<float> &f_vertex3 );

        /// Add circle.
        virtual bool        addCircle ( const float f_u_f, const float f_v_f,
                                        const float f_radius_f );

        /// Add circle.
        virtual bool        addCircle ( const S2D<float> &f_center,
                                        const float f_radius_f );
        
        /// Add filled circle.
        virtual bool        addFilledCircle ( const float f_u_f, const float f_v_f,
                                              const float f_radius_f );

        /// Add circle.
        virtual bool        addFilledCircle ( const S2D<float> &f_center,
                                              const float f_radius_f );

        /// Add ellipse.
        virtual bool        addEllipse ( const float f_u_f,    const float f_v_f,
                                         const float f_radU_f, const float f_radV_f,
                                         const float f_rotation_f = 0.f );

        /// Add ellipse.
        virtual bool        addEllipse ( const S2D<float> &f_center,
                                         const S2D<float> &f_radius,
                                         const float f_rotation_f = 0.f );

        /// Add filled ellipse.
        virtual bool        addFilledEllipse ( const float f_u_f,    const float f_v_f,
                                               const float f_radU_f, const float f_radV_f,
                                               const float f_rotation_f = 0.f );

        /// Add ellipse.
        virtual bool        addFilledEllipse ( const S2D<float> &f_center,
                                               const S2D<float> &f_radius,
                                               const float f_rotation_f = 0.f );

    ////// Set/Get drawing state.
    public:
        
        /// Set/Get line color.
        virtual bool          setLineColor ( SRgb  f_color );
        
        /// Set/Get line color with opacity.
        virtual bool          setLineColor ( SRgba f_color );
        virtual SRgba         getLineColor ( ) const { return m_lineColor; }        

        /// Set/Get fill color.
        virtual bool          setFillColor ( SRgb  f_color );

        /// Set/Get fill color with opacity.
        virtual bool          setFillColor ( SRgba f_color );
        virtual SRgba         getFillColor ( ) const { return m_fillColor; }

        /// Set/Get line width.
        virtual bool          setLineWidth ( float f_width_f );
        virtual float         getLineWidth ( ) const { return m_lineWidth_f; }
        
        /// Set/Get display state.
        virtual bool          setDisplayState ( SDisplayState f_dState );
        virtual SDisplayState getDisplayState ( ) const;

        /// Set/Get position.
        virtual bool          setPosition ( S2D<int> f_newPos );
        virtual S2D<int>      getPosition ( ) const { return m_position; }

        /// Set/Get visibility.
        virtual void          setVisibility ( bool f_state_b ){ m_visible_b = f_state_b; }
        virtual bool          isVisible ( ) const { return m_visible_b; }

        /// Get the number of elements in the drawing list.
        virtual int           getElementsCount() const;

    //// Actions
    public:
        /// Show all.
        virtual bool          show ();        
        
        /// Show all.
        virtual bool          clear ();

    protected:

        /// Write in file.
        virtual bool          write ( FILE*                f_file_p,
                                      const float          f_offsetX_f = 0.0,
                                      const float          f_offsetY_f = 0.0,
                                      const std::string    f_parameters_str = "");
    private:

        /// Name of this list.
        std::string                m_name_str;
        
        /// Line width.
        S2D<int>                   m_position;

        /// Line width.
        bool                       m_visible_b;

        /// Current line color.
        SRgba                      m_lineColor;

        /// Current fill color.
        SRgba                      m_fillColor;

        /// Line width.
        float                      m_lineWidth_f;

    /// Drawing elements
    private:

        /// List of lines.
        std::vector<CDrawingElementList *>  m_drawElems_v;

        /// List of lines.
        CLineList                           m_lines;

        /// List of rectangles.
        CRectangleList                      m_rectangles;

        /// List of rectangles.
        CEllipseList                        m_ellipses;

        /// List of triangles.
        CTriangleList                       m_triangles;

        /// List of images.
        CDisplayImageList                   m_images;

        /// List of color encoded images.
        CDisplayColorEncImageList           m_colorEncImages;
    };

    inline bool 
    CDrawingList::setLineColor ( SRgb  f_color ) 
    { 
        m_lineColor = f_color; 
        return true; 
    }
    
    /// Set line color with opacity.
    inline bool 
    CDrawingList::setLineColor ( SRgba f_color )
    { 
        m_lineColor = f_color;
        return true;
    }
    
    /// Set fill color.
    inline bool 
    CDrawingList::setFillColor ( SRgb  f_color )
    { 
        m_fillColor = f_color; 
        return true; 
    }
    
    /// Set fill color with opacity.
    inline bool 
    CDrawingList::setFillColor ( SRgba f_color ) 
    { 
        m_fillColor = f_color;
        return true;
    }

    /// Set line width.
    inline bool 
    CDrawingList::setLineWidth ( float f_width_f )  
    { 
        m_lineWidth_f = f_width_f;
        return true;
    }

    /// Set new position.
    inline bool 
    CDrawingList::setPosition ( S2D<int> f_newPos )
    {
        m_position = f_newPos;
        return true;
    }
    
    /// Set new display state.
    inline bool 
    CDrawingList::setDisplayState ( SDisplayState f_dState )
    {
        m_position  = f_dState.position;
        m_visible_b = f_dState.visible_b;
        return true;
    }

    /// Get new display state.
    inline SDisplayState 
    CDrawingList::getDisplayState ( ) const
    {
        return SDisplayState (m_position, m_visible_b);
    }


} // Namespace VIC

#endif // __DRAWINGLIST_H

/* ////////////  Version History ///////////////
 *  $Log: drawingList.h,v $
 *  Revision 1.2  2009/11/18 15:51:01  badino
 *  badino: documentation added. Some other global changes.
 *
 *//////////////////////////////////////////////
