/*
    This file is part of the Boson game
    Copyright (C) 2005 Rivo Laks <rivolaks@hot.ee>

    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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef BOGL_H
#define BOGL_H

class QString;
class QStringList;

// macro that is used for versions returned by bogl (such as OpenGL version)
#define MAKE_VERSION_BOGL(a,b,c) ( ((a) << 16) | ((b) << 8) | (c) )

// Defines
#define GL_GLEXT_LEGACY

#define QT_CLEAN_NAMESPACE

#ifdef __gl_h_
#error You should include "bogl.h" before <GL/gl.h>
#endif

// Some gl headers define GLsizeiptrARB type while others do not and there
//  doesn't seem to be any good way to find out if it's defined. So we replace
//  OpenGL type's name
#define GLsizeiptrARB GLsizeiptrARB_ORIGINAL

// Include OpenGL headers
#include <GL/gl.h>
#include <GL/glu.h>

// AB: the Qt includes are required to avoid conflicts with GLX
//#include <qnamespace.h>
//#include <qglobal.h>
//#include <qevent.h>
//#include <GL/glx.h>


#include <bogl_decl_p.h>

#undef GLsizeiptrARB


// bogl variables
extern bool bogl_inited;

// bogl functions
void boglInit();
bool boglResolveGLSymbols();
unsigned int boglGetOpenGLVersion();
QString boglGetOpenGLVersionString();
QString boglGetOpenGLVendorString();
QString boglGetOpenGLRendererString();
QStringList boglGetOpenGLExtensions();
QString boglGetGLUVersionString();
QStringList boglGetGLUExtensions();



// Typedefs
// This type was added for vbo extension.
// TODO: why do we use "ARB" here?
typedef int GLsizeiptrARB;
#ifndef GL_ARB_shader_objects
/* GL types for handling shader object handles and characters */
typedef char GLcharARB;		/* native character */
#endif

// Function prototypes
typedef void (*_boglBlendColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
typedef void (*_boglDeleteBuffers)(GLsizei, const GLuint*);
typedef void (*_boglGenBuffers)(GLsizei, GLuint*);
typedef void (*_boglBindBuffer)(GLenum, GLuint);
typedef void (*_boglBufferData)(GLenum, GLsizeiptrARB, const GLvoid*, GLenum);
typedef GLvoid* (* _boglMapBuffer) (GLenum target, GLenum access);
typedef GLboolean (* _boglUnmapBuffer) (GLenum target);
typedef void (*_boglActiveTexture)(GLenum);

typedef void (*_boglAttachShader) (GLuint, GLuint);
typedef void (*_boglCompileShader) (GLuint);
typedef GLuint (*_boglCreateProgram) (void);
typedef GLuint (*_boglCreateShader) (GLenum);
typedef void (*_boglDeleteProgram) (GLuint);
typedef void (*_boglDeleteShader) (GLuint);
typedef void (*_boglGetProgramInfoLog) (GLuint, GLsizei, GLsizei *, GLcharARB *);
typedef void (*_boglGetProgramiv) (GLuint, GLenum, GLint *);
typedef void (*_boglGetShaderInfoLog) (GLuint, GLsizei, GLsizei *, GLcharARB *);
typedef void (*_boglGetShaderiv) (GLuint, GLenum, GLint *);
typedef GLint (*_boglGetUniformLocation) (GLuint, const GLcharARB *);
typedef void (*_boglLinkProgram) (GLuint);
typedef void (*_boglShaderSource) (GLuint, GLsizei, const GLcharARB* *, const GLint *);
typedef void (*_boglUniform1f) (GLint, GLfloat);
typedef void (*_boglUniform1i) (GLint, GLint);
typedef void (*_boglUniform2fv) (GLint, GLsizei, const GLfloat *);
typedef void (*_boglUniform3fv) (GLint, GLsizei, const GLfloat *);
typedef void (*_boglUniform4fv) (GLint, GLsizei, const GLfloat *);
typedef void (*_boglUseProgram) (GLuint);


// Function pointers for extensions
// Blendcolor
extern _boglBlendColor boglBlendColor;
// VBO
extern _boglDeleteBuffers boglDeleteBuffers;
extern _boglGenBuffers boglGenBuffers;
extern _boglBindBuffer boglBindBuffer;
extern _boglBufferData boglBufferData;
extern _boglMapBuffer boglMapBuffer;
extern _boglUnmapBuffer boglUnmapBuffer;
// Textures
extern _boglActiveTexture boglActiveTexture;
// Shaders
extern _boglAttachShader boglAttachShader;
extern _boglCompileShader boglCompileShader;
extern _boglCreateProgram boglCreateProgram;
extern _boglCreateShader boglCreateShader;
extern _boglDeleteProgram boglDeleteProgram;
extern _boglDeleteShader boglDeleteShader;
extern _boglGetProgramInfoLog boglGetProgramInfoLog;
extern _boglGetProgramiv boglGetProgramiv;
extern _boglGetShaderInfoLog boglGetShaderInfoLog;
extern _boglGetShaderiv boglGetShaderiv;
extern _boglGetUniformLocation boglGetUniformLocation;
extern _boglLinkProgram boglLinkProgram;
extern _boglShaderSource boglShaderSource;
extern _boglUniform1f boglUniform1f;
extern _boglUniform1i boglUniform1i;
extern _boglUniform2fv boglUniform2fv;
extern _boglUniform3fv boglUniform3fv;
extern _boglUniform4fv boglUniform4fv;
extern _boglUseProgram boglUseProgram;



// Defines
#ifndef GL_ARB_imaging
#define GL_CONSTANT_COLOR                 0x8001
#define GL_ONE_MINUS_CONSTANT_COLOR       0x8002
#define GL_CONSTANT_ALPHA                 0x8003
#define GL_ONE_MINUS_CONSTANT_ALPHA       0x8004
#define GL_BLEND_COLOR                    0x8005
#define GL_FUNC_ADD                       0x8006
#define GL_MIN                            0x8007
#define GL_MAX                            0x8008
#define GL_BLEND_EQUATION                 0x8009
#define GL_FUNC_SUBTRACT                  0x800A
#define GL_FUNC_REVERSE_SUBTRACT          0x800B
#define GL_CONVOLUTION_1D                 0x8010
#define GL_CONVOLUTION_2D                 0x8011
#define GL_SEPARABLE_2D                   0x8012
#define GL_CONVOLUTION_BORDER_MODE        0x8013
#define GL_CONVOLUTION_FILTER_SCALE       0x8014
#define GL_CONVOLUTION_FILTER_BIAS        0x8015
#define GL_REDUCE                         0x8016
#define GL_CONVOLUTION_FORMAT             0x8017
#define GL_CONVOLUTION_WIDTH              0x8018
#define GL_CONVOLUTION_HEIGHT             0x8019
#define GL_MAX_CONVOLUTION_WIDTH          0x801A
#define GL_MAX_CONVOLUTION_HEIGHT         0x801B
#define GL_POST_CONVOLUTION_RED_SCALE     0x801C
#define GL_POST_CONVOLUTION_GREEN_SCALE   0x801D
#define GL_POST_CONVOLUTION_BLUE_SCALE    0x801E
#define GL_POST_CONVOLUTION_ALPHA_SCALE   0x801F
#define GL_POST_CONVOLUTION_RED_BIAS      0x8020
#define GL_POST_CONVOLUTION_GREEN_BIAS    0x8021
#define GL_POST_CONVOLUTION_BLUE_BIAS     0x8022
#define GL_POST_CONVOLUTION_ALPHA_BIAS    0x8023
#define GL_HISTOGRAM                      0x8024
#define GL_PROXY_HISTOGRAM                0x8025
#define GL_HISTOGRAM_WIDTH                0x8026
#define GL_HISTOGRAM_FORMAT               0x8027
#define GL_HISTOGRAM_RED_SIZE             0x8028
#define GL_HISTOGRAM_GREEN_SIZE           0x8029
#define GL_HISTOGRAM_BLUE_SIZE            0x802A
#define GL_HISTOGRAM_ALPHA_SIZE           0x802B
#define GL_HISTOGRAM_LUMINANCE_SIZE       0x802C
#define GL_HISTOGRAM_SINK                 0x802D
#define GL_MINMAX                         0x802E
#define GL_MINMAX_FORMAT                  0x802F
#define GL_MINMAX_SINK                    0x8030
#define GL_TABLE_TOO_LARGE                0x8031
#define GL_COLOR_MATRIX                   0x80B1
#define GL_COLOR_MATRIX_STACK_DEPTH       0x80B2
#define GL_MAX_COLOR_MATRIX_STACK_DEPTH   0x80B3
#define GL_POST_COLOR_MATRIX_RED_SCALE    0x80B4
#define GL_POST_COLOR_MATRIX_GREEN_SCALE  0x80B5
#define GL_POST_COLOR_MATRIX_BLUE_SCALE   0x80B6
#define GL_POST_COLOR_MATRIX_ALPHA_SCALE  0x80B7
#define GL_POST_COLOR_MATRIX_RED_BIAS     0x80B8
#define GL_POST_COLOR_MATRIX_GREEN_BIAS   0x80B9
#define GL_POST_COLOR_MATRIX_BLUE_BIAS    0x80BA
#define GL_POST_COLOR_MATRIX_ALPHA_BIAS   0x80BB
#define GL_COLOR_TABLE                    0x80D0
#define GL_POST_CONVOLUTION_COLOR_TABLE   0x80D1
#define GL_POST_COLOR_MATRIX_COLOR_TABLE  0x80D2
#define GL_PROXY_COLOR_TABLE              0x80D3
#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
#define GL_COLOR_TABLE_SCALE              0x80D6
#define GL_COLOR_TABLE_BIAS               0x80D7
#define GL_COLOR_TABLE_FORMAT             0x80D8
#define GL_COLOR_TABLE_WIDTH              0x80D9
#define GL_COLOR_TABLE_RED_SIZE           0x80DA
#define GL_COLOR_TABLE_GREEN_SIZE         0x80DB
#define GL_COLOR_TABLE_BLUE_SIZE          0x80DC
#define GL_COLOR_TABLE_ALPHA_SIZE         0x80DD
#define GL_COLOR_TABLE_LUMINANCE_SIZE     0x80DE
#define GL_COLOR_TABLE_INTENSITY_SIZE     0x80DF
#define GL_CONSTANT_BORDER                0x8151
#define GL_REPLICATE_BORDER               0x8153
#define GL_CONVOLUTION_BORDER_COLOR       0x8154
#endif

#define GL_ARRAY_BUFFER                   0x8892
#define GL_ELEMENT_ARRAY_BUFFER           0x8893
#define GL_WRITE_ONLY                     0x88B9
#define GL_STATIC_DRAW                    0x88E4
#define GL_DYNAMIC_DRAW                   0x88E8

#define GL_TEXTURE0                       0x84C0
#define GL_TEXTURE1                       0x84C1
#define GL_TEXTURE2                       0x84C2
#define GL_TEXTURE3                       0x84C3
#define GL_ACTIVE_TEXTURE                 0x84E0
#define GL_CLIENT_ACTIVE_TEXTURE          0x84E1
#define GL_MAX_TEXTURE_UNITS              0x84E2

#define GL_REFLECTION_MAP                 0x8512
#define GL_TEXTURE_CUBE_MAP               0x8513
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X    0x8515
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE      0x851C

#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT   0x83F0
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT  0x83F3

#define GL_GENERATE_MIPMAP                0x8191

#ifndef GL_EXT_texture_filter_anisotropic
#define GL_TEXTURE_MAX_ANISOTROPY_EXT     0x84FE
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
#endif

#ifndef GL_EXT_texture_lod_bias
#define GL_MAX_TEXTURE_LOD_BIAS_EXT       0x84FD
#define GL_TEXTURE_FILTER_CONTROL_EXT     0x8500
#define GL_TEXTURE_LOD_BIAS_EXT           0x8501
#endif

#define GL_COMBINE                        0x8570
#define GL_COMBINE_RGB                    0x8571
#define GL_COMBINE_ALPHA                  0x8572
#define GL_SOURCE0_RGB                    0x8580
#define GL_SOURCE1_RGB                    0x8581
#define GL_SOURCE2_RGB                    0x8582
#define GL_SOURCE0_ALPHA                  0x8588
#define GL_SOURCE1_ALPHA                  0x8589
#define GL_SOURCE2_ALPHA                  0x858A
#define GL_OPERAND0_RGB                   0x8590
#define GL_OPERAND1_RGB                   0x8591
#define GL_OPERAND2_RGB                   0x8592
#define GL_OPERAND0_ALPHA                 0x8598
#define GL_OPERAND1_ALPHA                 0x8599
#define GL_OPERAND2_ALPHA                 0x859A
#define GL_RGB_SCALE                      0x8573
#define GL_ADD_SIGNED                     0x8574
#define GL_INTERPOLATE                    0x8575
#define GL_SUBTRACT                       0x84E7
#define GL_CONSTANT                       0x8576
#define GL_PRIMARY_COLOR                  0x8577
#define GL_PREVIOUS                       0x8578
#define GL_DOT3_RGB                       0x86AE
#define GL_DOT3_RGBA                      0x86AF

#define GL_PROGRAM_OBJECT                 0x8B40
#define GL_SHADER_OBJECT                  0x8B48
#define GL_COMPILE_STATUS                 0x8B81
#define GL_LINK_STATUS                    0x8B82
#define GL_VERTEX_SHADER                  0x8B31
#define GL_FRAGMENT_SHADER                0x8B30


// AB: defines for extensions:
//     (note: the above defines are partially for extensions too, one day we
//      should sort this properly)
// GL_ARB_multitexture (part of OpenGL 1.2.1)
#define GL_MAX_TEXTURE_UNITS_ARB          0x84E2



/**
 * This header includes more or less complete support for following extensions:
 * @li GL_multitexture_ARB (GL 1.3) - first 4 texture units
 * @li GL_blend_color_EXT / GL_ARB_imaging() - full support
 * @li GL_texture_env_combine_ARB (GL 1.3) - full support
 * @li GL_texture_env_dot3_ARB (GL 1.3) - full support
 * @li GL_vertex_buffer_object_ARB (GL 1.5) - necessary VBO functionality
 * @li GL_shader_object_ARB and other shader extensions (GL 2.0) - necessary stuff
 * ...
 **/

#endif
