/*@@@**************************************************************************
 * \file  drawingList
 * \author Hernan Badino
 * \date  Thu Feb 26 10:45:48 Local time zone must be set--see zic manual page 2009
 * \notes 
 *******************************************************************************
 ******************************************************************************/

/* INCLUDES */
#include "drawingList.h"

using namespace VIC;

CDrawingList::CDrawingList( std::string f_name_str )
        : m_name_str (               f_name_str ),
          m_position (                     0, 0 ),
          m_visible_b (                   false ),
          m_lineColor (              0, 0, 0, 0 ),
          m_fillColor (        255, 255, 255, 0 ),
          m_lineWidth_f (                     1 )
{
    m_drawElems_v.push_back( &m_images );
    m_drawElems_v.push_back( &m_colorEncImages );
    m_drawElems_v.push_back( &m_lines );
    m_drawElems_v.push_back( &m_rectangles );
    m_drawElems_v.push_back( &m_triangles );
    m_drawElems_v.push_back( &m_ellipses );
}

CDrawingList::~CDrawingList()
{
}

/// Add image.
bool
CDrawingList::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,
                         const float        f_offset_f,
                         const float        f_alpha_f,
                         const bool         f_makeCopy_b )
{
    return m_images.add ( f_img,
                          f_u_f,
                          f_v_f,
                          f_width_f,
                          f_height_f,
                          f_scale_f,
                          f_offset_f,
                          f_alpha_f,
                          f_makeCopy_b );
}

/// Add image.
bool 
CDrawingList::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,
                                 const bool           f_makeCopy_b )
{
    return m_colorEncImages.add (  f_img_p,
                                   f_u_f,
                                   f_v_f,
                                   f_width_f,
                                   f_height_f,
                                   f_encoder,
                                   f_alpha_f,
                                   f_makeCopy_b );
}


/// Add line.
bool
CDrawingList::addLine ( const float f_u1_f, const float f_v1_f,
                        const float f_u2_f, const float f_v2_f )
{
    return m_lines.add ( f_u1_f, f_v1_f, f_u2_f, f_v2_f,
                         m_lineColor,
                         m_lineWidth_f );
}

/// Add line.
bool
CDrawingList::addLine ( const S2D<float> &f_point1, 
                        const S2D<float> &f_point2 )
{
    return m_lines.add ( f_point1.x, f_point1.y, 
                         f_point2.x, f_point2.y, 
                         m_lineColor,
                         m_lineWidth_f );
}

/// Add rectangle.
bool
CDrawingList::addRectangle ( const float f_u1_f, const float f_v1_f,
                             const float f_u2_f, const float f_v2_f )
{

    return m_rectangles.add ( f_u1_f, f_v1_f, f_u2_f, f_v2_f,
                              m_lineColor,
                              m_lineWidth_f );
}

/// Add rectangle.
bool
CDrawingList::addRectangle ( const S2D<float> &f_tl, 
                             const S2D<float> &f_br )
{
    return m_rectangles.add ( f_tl.x, f_tl.y, 
                              f_br.x, f_br.y, 
                              m_lineColor,
                              m_lineWidth_f );
}

bool
CDrawingList::addFilledRectangle ( const float f_u1_f, const float f_v1_f,
                                   const float f_u2_f, const float f_v2_f )
{

    return m_rectangles.add ( f_u1_f, f_v1_f, f_u2_f, f_v2_f,
                              m_lineColor,
                              m_fillColor,
                              m_lineWidth_f );
}

/// Add filled rectangle.
bool
CDrawingList::addFilledRectangle ( const S2D<float> &f_tl, 
                                   const S2D<float> &f_br )
{
    return m_rectangles.add ( f_tl.x, f_tl.y, 
                              f_br.x, f_br.y, 
                              m_lineColor,
                              m_fillColor,
                              m_lineWidth_f );
}

/// Add circle.
bool
CDrawingList::addCircle ( const float f_u_f, const float f_v_f,
                          const float f_radius_f )
{
    return m_ellipses.add ( f_u_f, f_v_f, 
                            f_radius_f, f_radius_f,
                            0.f, // rotation.
                            m_lineColor,
                            m_lineWidth_f );
}

/// Add circle.
bool
CDrawingList::addCircle ( const S2D<float> &f_center,
                          const float f_radius_f )
{
    return m_ellipses.add ( f_center.x, f_center.y,
                            f_radius_f, f_radius_f,
                            0.f, // rotation.
                            m_lineColor,
                            m_lineWidth_f );
}


/// Add filled circle.
bool 
CDrawingList::addFilledCircle ( const float f_u_f, const float f_v_f,
                                const float f_radius_f )
{
    return m_ellipses.add ( f_u_f, f_v_f, 
                            f_radius_f, f_radius_f,
                            0.f, // rotation.
                            m_lineColor,
                            m_fillColor,
                            m_lineWidth_f );
}

/// Add circle.
bool
CDrawingList::addFilledCircle ( const S2D<float> &f_center,
                                const float f_radius_f )
{
    return m_ellipses.add ( f_center.x, f_center.y,
                            f_radius_f, f_radius_f,
                            0.f, // rotation.
                            m_lineColor,
                            m_fillColor,
                            m_lineWidth_f );
}

/// Add ellipse.
bool 
CDrawingList::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 )
{
    return m_ellipses.add ( f_u_f, f_v_f, 
                            f_radU_f, f_radV_f,
                            f_rotation_f,
                            m_lineColor,
                            m_lineWidth_f );
}

/// Add filled ellipse.
bool 
CDrawingList::addEllipse (  const S2D<float> &f_center,
                            const S2D<float> &f_radius,
                            const float f_rotation_f )
{
    return m_ellipses.add ( f_center.x, f_center.y,
                            f_radius.x, f_radius.y,
                            f_rotation_f,
                            m_lineColor,
                            m_lineWidth_f );
}

/// Add filled ellipse.
bool 
CDrawingList::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 )
{
    return m_ellipses.add ( f_u_f, f_v_f, 
                            f_radU_f, f_radV_f,
                            f_rotation_f,
                            m_lineColor,
                            m_fillColor,
                            m_lineWidth_f );
}

/// Add filled ellipse.
bool 
CDrawingList::addFilledEllipse (  const S2D<float> &f_center,
                                  const S2D<float> &f_radius,
                                  const float f_rotation_f )
{
    return m_ellipses.add ( f_center.x, f_center.y,
                            f_radius.x, f_radius.y,
                            f_rotation_f,
                            m_lineColor,
                            m_fillColor,
                            m_lineWidth_f );
}

/// Add triangle.
bool
CDrawingList::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 )
{
    return m_triangles.add ( f_u1_f, f_v1_f, 
                             f_u2_f, f_v2_f, 
                             f_u3_f, f_v3_f,
                             m_lineColor,
                             m_lineWidth_f );
}

/// Add triangle.
bool 
CDrawingList::addTriangle ( const S2D<float> &f_vertex1, 
                            const S2D<float> &f_vertex2, 
                            const S2D<float> &f_vertex3 )
{
    return m_triangles.add ( f_vertex1, 
                             f_vertex2,
                             f_vertex3,
                             m_lineColor,
                             m_lineWidth_f );
}

/// Add filled triangle.
bool
CDrawingList::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 )
{
    return m_triangles.add ( f_u1_f, f_v1_f, 
                             f_u2_f, f_v2_f, 
                             f_u3_f, f_v3_f,
                             m_lineColor,
                             m_fillColor,
                             m_lineWidth_f );
}

/// Add filled triangle.
bool
CDrawingList::addFilledTriangle ( const S2D<float> &f_vertex1, 
                                  const S2D<float> &f_vertex2, 
                                  const S2D<float> &f_vertex3 )
{
    return m_triangles.add ( f_vertex1, 
                             f_vertex2,
                             f_vertex3,
                             m_lineColor,
                             m_fillColor,
                             m_lineWidth_f );
}

/// Show all.        
bool
CDrawingList::show ()
{
    bool resShow_b;
    bool success_b = true;
    
    std::vector< CDrawingElementList * >::const_iterator 
        last = m_drawElems_v.end();

    for (std::vector< CDrawingElementList * >::const_iterator 
             i = m_drawElems_v.begin(); 
         i != last; ++i )
    {
        if ((*i)->isBlendable())
        {
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        }
        else
        {
            glDisable(GL_BLEND);
        }

        resShow_b = (*i)->show();
        success_b &= resShow_b;
    }

    glDisable(GL_BLEND);

    return success_b;
}

/// Clear all.        
bool
CDrawingList::clear ()
{
    bool resClear_b;
    bool success_b = true;
    
    std::vector< CDrawingElementList * >::const_iterator 
        last = m_drawElems_v.end();

    for (std::vector< CDrawingElementList * >::const_iterator 
             i = m_drawElems_v.begin(); 
         i != last; ++i )
    {
        resClear_b = (*i)->clear();
        success_b &= resClear_b;
    }

    return success_b;
}

/// Write in file.
bool
CDrawingList::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 /* = "" */ )
{
    bool resWrite_b;
    bool success_b = true;
    
    std::vector< CDrawingElementList * >::const_iterator 
        last = m_drawElems_v.end();

    for (std::vector< CDrawingElementList * >::const_iterator 
             i = m_drawElems_v.begin(); 
         i != last; ++i )
    {

        resWrite_b = (*i)->write( f_file_p,
                                  f_offsetX_f,
                                  f_offsetY_f,
                                  f_parameters_str );

        success_b &= resWrite_b;
    }
    
    return success_b;
}

bool
CDrawingList::addDrawingList ( const CDrawingList &f_other )
{
    m_images.add          ( f_other.m_images );
    m_colorEncImages.add  ( f_other.m_colorEncImages );
    m_lines.add           ( f_other.m_lines );
    m_rectangles.add      ( f_other.m_rectangles );
    m_triangles.add       ( f_other.m_triangles );
    m_ellipses.add        ( f_other.m_ellipses );

    return true;    
}

int
CDrawingList::getElementsCount() const
{
    return ( m_images.getSize () + 
             m_colorEncImages.getSize () + 
             m_lines.getSize () + 
             m_rectangles.getSize () + 
             m_triangles.getSize () + 
             m_ellipses.getSize () );
}


/* ////////////  Version History ///////////////
 *  $Log: drawingList.cpp,v $
 *  Revision 1.2  2009/11/18 15:50:15  badino
 *  badino: global changes.
 *
 *//////////////////////////////////////////////
