/*@@@**************************************************************************
* \file  displayImageList
* \author Hernan Badino
* \date  Wed May  6 15:49:54 EDT 2009
* \notes 
*******************************************************************************
******************************************************************************/

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


//#include "glheader.h"


using namespace VIC;


CDisplayImageList::CDisplayImageList() 
{
}

/// Destructor.
CDisplayImageList::~CDisplayImageList()
{
    clear();
}

// Add images from other list.
bool 
CDisplayImageList::add ( const CDisplayImageList & f_otherList )
{
    m_image_v.insert( m_image_v.begin(), 
                      f_otherList.m_image_v.begin(),
                      f_otherList.m_image_v.end() );
    return true;
    
}

// Draw all lines.
bool CDisplayImageList::add ( const CImageBase &  f_image,
                              const float         f_u_f, 
                              const float         f_v_f,
                              const float         f_dispWidth_f,
                              const float         f_dispHeight_f,
                              const float         f_scale_f,
                              const float         f_bias_f,
                              const float         f_alpha_f,
                              const bool          f_makeCopy_b )
{
    bool res_b;
    SDisplayImage * newImage_p = new SDisplayImage;

    res_b = newImage_p->image.copyFrom ( f_image, f_makeCopy_b );

    if (res_b)
    {
        newImage_p->u_f         = f_u_f;
        newImage_p->v_f         = f_v_f;
        newImage_p->width_f     = f_dispWidth_f;
        newImage_p->height_f    = f_dispHeight_f;
        newImage_p->alpha_f     = f_alpha_f;
        newImage_p->scale_f     = f_scale_f;
        newImage_p->bias_f      = f_bias_f;

        m_image_v.push_back(newImage_p);
        
        // Generate texture.
        glGenTextures(1, &newImage_p->textureId_ui);
        
        //first call transferes the texture to hw
        glBindTexture( GL_TEXTURE_RECTANGLE_NV, newImage_p->textureId_ui );
        
        glPixelStorei( GL_UNPACK_ALIGNMENT, 1);    

        // Interpolation settings ().
        glTexParameteri( GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri( GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP);
        
        // Interpolation settings (make as parameter).
        glTexParameteri( GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //GL_LINEAR
        glTexParameteri( GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

        glPixelTransferf ( GL_RED_SCALE,   newImage_p->scale_f );
        glPixelTransferf ( GL_RED_BIAS,    newImage_p->bias_f  );        
        glPixelTransferf ( GL_GREEN_SCALE, newImage_p->scale_f );
        glPixelTransferf ( GL_GREEN_BIAS,  newImage_p->bias_f  );        
        glPixelTransferf ( GL_BLUE_SCALE,  newImage_p->scale_f );
        glPixelTransferf ( GL_BLUE_BIAS,   newImage_p->bias_f  );        

        glTexImage2D( GL_TEXTURE_RECTANGLE_NV,
                      0,                                  // base level (only 0 allowed for GL_TEXTURE_RECTANGLE_NV).
                      newImage_p->image.getImageFormat(), // internal format.
                      newImage_p->image.getWidth(),
                      newImage_p->image.getHeight(),
                      0,                                    // border.
                      newImage_p->image.getImageFormat(),   // format of pixel data array.
                      newImage_p->image.getDataType(),      // data type of pixel data array.
                      newImage_p->image.getDataPointer());  // data.
    }

    return res_b;
}

// Clear all lines.
bool CDisplayImageList::clear ()
{
    for (unsigned int i = 0; i < m_image_v.size(); ++i)
    {
        glDeleteTextures( 1, &m_image_v[i]->textureId_ui );
        delete m_image_v[i];
    }
    
    m_image_v.clear();
    return m_image_v.size() == 0;
}

// Draw all lines.
bool CDisplayImageList::show () const
{
    DisplayImageList_t::const_iterator last = m_image_v.end();
    
    glEnable( GL_TEXTURE_RECTANGLE_NV);
        
    for (DisplayImageList_t::const_iterator i = m_image_v.begin(); 
         i != last; ++i )
    {
        glBindTexture( GL_TEXTURE_RECTANGLE_NV,
                       (*i)->textureId_ui );
        
        float endX_f = (*i)->u_f + (*i)->width_f;
        float endY_f = (*i)->v_f + (*i)->height_f;
        
        glBegin(GL_QUADS);
        
        glTexCoord2f(0, 0);
        glVertex2f((*i)->u_f, (*i)->v_f);
        
        glTexCoord2f((*i)->image.getWidth(), 0);
        glVertex2f(endX_f, (*i)->v_f);

        glTexCoord2f((*i)->image.getWidth(), (*i)->image.getHeight());
        glVertex2f(endX_f, endY_f);

        glTexCoord2f(0, (*i)->image.getHeight());
        glVertex2f((*i)->u_f, endY_f);

        glEnd();        
    }

    glDisable(GL_TEXTURE_RECTANGLE_NV);

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

bool CDisplayImageList::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
CDisplayImageList::getSize () const
{
    return m_image_v.size();    
}

/*

  Possible parameters: interpolation type, show scroll bars, maintain aspect ratio

  Functionality: full screen (all and individual) with zoom posibility.
 */

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