/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial Usage
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtGui/QImage>
#include "glwidget.h"

#include <math.h>

#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE  0x809D
#endif

GLWidget::GLWidget(QWidget *parent)
    : QGLWidget(QGLFormat(QGL::SampleBuffers|QGL::AlphaChannel), parent)
{
    setWindowTitle(tr("OpenGL framebuffer objects"));
    makeCurrent();
    fbo = new QGLFramebufferObject(256, 256);

    tile_list = glGenLists(1);
    glNewList(tile_list, GL_COMPILE);
    glBegin(GL_QUADS);
    {
        glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
    }
    glEnd();
    glEndList();
}

GLWidget::~GLWidget()
{
    glDeleteLists(tile_list, 1);
    delete fbo;
}

void GLWidget::paintEvent(QPaintEvent *)
{
    draw();
}

void GLWidget::draw()
{
    QPainter p(this); // used for text overlay

    // save the GL state set for QPainter
    saveGLState();

    QPainter fbo_painter(fbo);
    fbo_painter.setBackgroundMode(Qt::TransparentMode);
    fbo_painter.setBackground(Qt::NoBrush);
    //fbo_painter.setPen(QPen(QColor(0, 0, 255, 160)));
    fbo_painter.setPen(QPen(Qt::red));
    fbo_painter.drawText(10, fbo->height() / 2, "red on transparent");

    // second line
    fbo_painter.setBackgroundMode(Qt::OpaqueMode);
    fbo_painter.setBackground(QBrush(Qt::green));
    fbo_painter.setPen(QPen(Qt::blue));
    fbo_painter.drawText(10, (fbo->height() / 2) + 20, "blue on green");

    fbo_painter.end();

    // draw into the GL widget
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1, 1, -1, 1, 10, 100);
    glTranslatef(0.0f, 0.0f, -15.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glViewport(0, 0, width(), height());
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glBindTexture(GL_TEXTURE_2D, fbo->texture());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glEnable(GL_TEXTURE_2D);
    //glEnable(GL_MULTISAMPLE);
    glEnable(GL_CULL_FACE);

    // draw background
    glPushMatrix();
//    glScalef(1.7f, 1.7f, 1.7f);
//    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    glCallList(tile_list);
    glPopMatrix();

//    glRotatef(rot_x, 1.0f, 0.0f, 0.0f);
    //glRotatef(rot_y, 0.0f, 1.0f, 0.0f);
    //glRotatef(rot_z, 0.0f, 0.0f, 1.0f);
//    glScalef(scale/w, scale/w, scale/w);

    //glDepthFunc(GL_LESS);
    //glEnable(GL_DEPTH_TEST);
    //// draw the Qt icon
    ////glTranslatef(-w+1, -h+1, 0.0f);
    ////for (int y=h-1; y>=0; --y) {
    //    //uint *p = (uint*) logo.scanLine(y);
    //    //uint *end = p + w;
    //    //int  x = 0;
    //    //while (p < end) {
    //        //glColor4ub(qRed(*p), qGreen(*p), qBlue(*p), uchar(qAlpha(*p)*.9));
    //        //glTranslatef(0.0f, 0.0f, wave[y*w+x]);
    //        //if (qAlpha(*p) > 128)
    //            glCallList(tile_list);
    //        //glTranslatef(0.0f, 0.0f, -wave[y*w+x]);
    //        //glTranslatef(2.0f, 0.0f, 0.0f);
    //        //++x;
    //        //++p;
    //    //}
    //    //glTranslatef(-w*2.0f, 2.0f, 0.0f);
    ////}

    // restore the GL state that QPainter expects
    restoreGLState();

    // draw the overlayed text using QPainter
    p.setPen(QColor(197, 197, 197, 157));
    p.setBrush(QColor(197, 197, 197, 127));
    p.drawRect(QRect(0, 0, width(), 50));
    p.setPen(Qt::black);
    p.setBrush(Qt::NoBrush);
    //const QString str1(tr("A simple OpenGL framebuffer object example."));
    //const QString str2(tr("Use the mouse wheel to zoom, press buttons and move mouse to rotate, double-click to flip."));
    //QFontMetrics fm(p.font());
    //p.drawText(width()/2 - fm.width(str1)/2, 20, str1);
    //p.drawText(width()/2 - fm.width(str2)/2, 20 + fm.lineSpacing(), str2);
}

void GLWidget::saveGLState()
{
    glPushAttrib(GL_ALL_ATTRIB_BITS);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
}

void GLWidget::restoreGLState()
{
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    glPopAttrib();
}
