/*@@@**************************************************************************
 * \file  ellipseList.cpp
 * \author Hernan Badino
 * \date  Thu Feb 26 16:14:22 Local time zone must be set--see zic manual page 2009
 * \notes 
 *******************************************************************************
 ******************************************************************************/

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

#include "glheader.h"
#include <math.h>


using namespace VIC;


CEllipseList::CEllipseList( int /* f_bufferSize_i */ )
{}

/// Destructor.
CEllipseList::~CEllipseList()
{}

// Add ellipses from other list.
bool 
CEllipseList::add (  const CEllipseList & f_otherList )
{    
    m_ellipse_v.insert( m_ellipse_v.begin(), 
                        f_otherList.m_ellipse_v.begin(),
                        f_otherList.m_ellipse_v.end() );
    return true;
}

// Add empty ellipses.
bool
CEllipseList::add ( float   f_u_f, 
                    float   f_v_f,
                    float   f_radiusU_f,
                    float   f_radiusV_f,
                    float   f_rotAngle_f,
                    SRgba   f_color,
                    float   f_lineWidth_i )
{
    SEllipse newEllipse;

    newEllipse.outlineColor = f_color;

    /// Make transparent filling.
    newEllipse.fillColor.a  = 0;

    newEllipse.u_f         = f_u_f;
    newEllipse.v_f         = f_v_f;
    newEllipse.radiusU_f   = f_radiusU_f;
    newEllipse.radiusV_f   = f_radiusV_f;
    newEllipse.rotation_f  = f_rotAngle_f*180.f/M_PI;
    newEllipse.lineWidth_f = f_lineWidth_i;

    m_ellipse_v.push_back(newEllipse);

    return true;
}

// Add a filled ellipse.
bool
CEllipseList::add (  float   f_u_f, 
                     float   f_v_f,
                     float   f_radiusU_f,
                     float   f_radiusV_f,
                     float   f_rotAngle_f,
                     SRgba   f_color,
                     SRgba   f_fillColor,
                     float   f_lineWidth_i )
{
    SEllipse newEllipse;

    newEllipse.outlineColor = f_color;

    /// Make transparent filling.
    newEllipse.fillColor   = f_fillColor;

    newEllipse.u_f         = f_u_f;
    newEllipse.v_f         = f_v_f;
    newEllipse.radiusU_f   = f_radiusU_f;
    newEllipse.radiusV_f   = f_radiusV_f;
    newEllipse.rotation_f  = f_rotAngle_f*180.f/M_PI;
    newEllipse.lineWidth_f = f_lineWidth_i;

    m_ellipse_v.push_back(newEllipse);

    return true;
}

// Clear ellipse list.
bool CEllipseList::clear ()
{
    m_ellipse_v.clear();
    return m_ellipse_v.size() == 0;
}

// Draw all ellipses.
bool CEllipseList::show () const
{
    std::vector< SEllipse >::const_iterator last = m_ellipse_v.end();

    for (std::vector< SEllipse >::const_iterator i = m_ellipse_v.begin(); 
         i != last; ++i )
    {
        const int   segments_i  = 36;
        const float increment_f = M_PI * 2. / segments_i;

        float u_p[segments_i];
        float v_p[segments_i];

        float t = 0;

        for( int s = 0; s < segments_i; ++s )
        {
            u_p[s] = i->radiusU_f * cos(t);
            v_p[s] = i->radiusV_f * sin(t);
            t += increment_f;
        }

        glPushMatrix();
        glTranslatef ( i->u_f, i->v_f, 0.f );
        glRotatef    ( i->rotation_f, 0.f, 0.f, 1.f );
        //glTranslatef ( -i->u_f, -i->v_f, 0.f );

        glLineWidth( i->lineWidth_f );

        /// If not complete transparent.
        if ( i->fillColor.a != 0 )
        {
            glColor4ub( i->fillColor.r, 
                        i->fillColor.g, 
                        i->fillColor.b, 
                        i->fillColor.a );
            
            glBegin(GL_POLYGON);

            for( int s = 0; s < segments_i; ++s )
            {
                glVertex2f( u_p[s], v_p[s] );
            }

            glEnd();
        }       

        glColor4ub( i->outlineColor.r, 
                    i->outlineColor.g, 
                    i->outlineColor.b, 
                    i->outlineColor.a );
        
        glBegin ( GL_LINE_LOOP ) ;

        for( int s = 0; s < segments_i; ++s )
        {
            glVertex2f( u_p[s], v_p[s] );
        }
        
        glEnd();

        glPopMatrix();
    }

    /// Todo: Check GL status and return value.
    return true;
}

bool CEllipseList::write ( FILE*                f_file_p,
                           const float          f_offsetU_f /* = 0.0 */,
                           const float          f_offsetV_f /* = 0.0 */,
                           const std::string    f_parameters_str /* = "" */) const
{
    return CDrawingElementList::write( f_file_p, 
                                       f_offsetU_f, 
                                       f_offsetV_f, 
                                       f_parameters_str );
}

/// Return number of elements.
int
CEllipseList::getSize () const
{
    return m_ellipse_v.size();    
}


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