/***************************************************************************
 *
 * Project:  OpenCPN
 * Purpose:  texture OpenGL text rendering built from wxFont
 * Author:   Sean D'Epagnier
 *
 ***************************************************************************
 *   Copyright (C) 2014 Sean D'Epagnier                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA.         *
 **************************************************************************/

#include <wx/wx.h>

#include "pi_DepthFont.h"

#ifdef USE_ANDROID_GLES2
#include <gl2.h>
#include "linmath.h"
#include "shaders.h"
#else
 #include <GL/gl.h>
 #include <GL/glu.h>
#endif

DepthFont::DepthFont( )
{
    texobj = 0;
    m_built = false;
    m_scaleFactor = 0;
}

DepthFont::~DepthFont( )
{
    Delete( );
}

void DepthFont::Delete( )
{
    if (texobj) {
        glDeleteTextures(1, &texobj);
        texobj = 0;
    }
    m_built = false;
    m_scaleFactor = 0;
}

void DepthFont::Build( wxFont *font, double scale )
{
    /* avoid rebuilding if the parameters are the same */
    if(m_built && (*font == m_font) )
        return;
    
    m_font = *font;
    m_scaleFactor = scale;

    m_maxglyphw = 0;
    m_maxglyphh = 0;
    
    wxScreenDC sdc;

    sdc.SetFont( *font );

    for( int i=0 ; i < 10 ; i++){
        wxCoord gw, gh;
        wxString text;
        text = wxString::Format(_T("%d"), i);
        wxCoord descent, exlead;
        sdc.GetTextExtent( text, &gw, &gh, &descent, &exlead, font ); // measure the text

        tgi[i].width = gw;
        tgi[i].height = gh - descent;

        tgi[i].advance = gw;
        
        
        m_maxglyphw = wxMax(tgi[i].width,  m_maxglyphw);
        m_maxglyphh = wxMax(tgi[i].height, m_maxglyphh);
    }

    int w = 10 * m_maxglyphw;
    int h = m_maxglyphh;

    /* make power of 2 */
    
    for(tex_w = 1; tex_w < w; tex_w *= 2);
    for(tex_h = 1; tex_h < h; tex_h *= 2);

    wxBitmap tbmp(tex_w, tex_h);
    wxMemoryDC dc;
    dc.SelectObject(tbmp);
    dc.SetFont( *font );
    
    /* fill bitmap with black */
    dc.SetBackground( wxBrush( wxColour( 0, 0, 0 ) ) );
    dc.Clear();
        
    /* draw the text white */
    dc.SetTextForeground( wxColour( 255, 255, 255 ) );

 /*    wxPen pen(wxColour( 255, 255, 255 ));
     wxBrush brush(wxColour( 255, 255, 255 ), wxTRANSPARENT);
     dc.SetPen(pen);
     dc.SetBrush(brush);
  */  
    int row = 0, col = 0;
    for( int i = 0; i < 10; i++ ) {

        tgi[i].x = col * m_maxglyphw;
        tgi[i].y = row * m_maxglyphh;

        wxString text;
        text = wxString::Format(_T("%d"), i);

        dc.DrawText(text, tgi[i].x, tgi[i].y );
        
        col++;
    }

    dc.SelectObject(wxNullBitmap);
    
    wxImage image = tbmp.ConvertToImage();

    GLuint format, internalformat;
    int stride;

    format = GL_ALPHA;
    internalformat = format;
    stride = 1;

    unsigned char *imgdata = image.GetData();
    
    if(imgdata){
        unsigned char *teximage = (unsigned char *) malloc( stride * tex_w * tex_h );

        for( int j = 0; j < tex_w*tex_h; j++ )
            for( int k = 0; k < stride; k++ )
                teximage[j * stride + k] = imgdata[3*j];

        glGenTextures( 1, &texobj );
        glBindTexture( GL_TEXTURE_2D, texobj );

        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST/*GL_LINEAR*/ );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

        glTexImage2D( GL_TEXTURE_2D, 0, internalformat, tex_w, tex_h, 0,
                    format, GL_UNSIGNED_BYTE, teximage );

        free(teximage);
    }
    
    m_built = true;
}


bool DepthFont::GetGLTextureRect(wxRect &texrect, int symIndex)
{
    if(symIndex < 10){
        texrect.x = tgi[symIndex].x;
        texrect.y = tgi[symIndex].y;
        texrect.width = tgi[symIndex].width;
        texrect.height = tgi[symIndex].height;
        return true;
    }
    else{
        texrect.x = tgi[0].x;
        texrect.y = tgi[0].y;
        texrect.width = tgi[0].width;
        texrect.height = tgi[0].height;
        return false;
    }        
}

