#ifndef UTIL_OPENGL_H_
#define UTIL_OPENGL_H_

#include <qstring.h>
#include <qrect.h>
#include <vector>

#define GL_GLEXT_PROTOTYPES
#define GLX_GLXEXT_PROTOTYPES
#define XMD_H 1
#include <GL/glx.h>
#include <GL/gl.h>
#undef GLX_ARB_get_proc_address
#include <GL/glxext.h>
#include <GL/glext.h>

typedef enum GLEXTS
{
    SUPP_NONE = 0x00,
    SUPP_RECT = 0x01,
    SUPP_PROG = 0x02,
    SUPP_FBUF = 0x04
};

class OpenglVideo;

class OpenglContext
{ 
  public:

    friend class OpenglVideo;

    OpenglContext();
   ~OpenglContext();
    bool Create(Window window, int width, int height, bool visible);
    void Init(void);
    void MakeCurrent(bool current);
    void SwapBuffers(void);
    bool TextureSupport(void)  { return m_supported & SUPP_RECT; };
    bool FragProgSupport(void) { return m_supported & SUPP_PROG; };
    bool FrameBufSupport(void) { return m_supported & SUPP_FBUF; };
    GLint GetMaxTexSize(void)  { return m_max_tex_size; };
    Display* GetDisplay(void)  { return m_display; };
    int  GetScreenNum(void)    { return m_screen_num; };
    Window GetWindow(void)     { return m_window; };
    void CreateTexture(GLuint *tex);
    bool SetupTexture(QSize size, GLuint *tex, int filt);
    void SetupTextureFilters(GLuint *tex, int filt);
    void DeleteTexture(GLuint *tex);
    bool CreateProgram(QString *program, GLuint *prog);
    void DeleteProgram(GLuint *prog);
    bool CreateFrameBuffer(GLuint *buf, GLuint *tex, int width, int height);
    void DeleteFrameBuffer(GLuint *buf);
    void EnableTextures(void);

  private:
    int  EnableTextureRects(void);
    int  EnableFragProgs(void);
    int  EnableFrameBufs(void);
    void DeleteTextures(void);
    void DeletePrograms(void);
    void DeleteFrameBuffers(void);
    bool CheckGlx(void);
    bool GetVisual(void);
    bool CreateWindow(Window winid, int width, int height);
    bool CreateContext(void);
    __GLXextFuncPtr glXGetProcAddress(const char * const procName);

    int          m_texture;
    Display     *m_display;
    int          m_screen_num;
    Window       m_window;
    XVisualInfo* m_visual;
    GLXContext   m_context;
    bool         m_visible;
    QString      m_extensions;
    int          m_supported;
    GLint        m_max_tex_size; 
    bool         m_textures_enabled;

    vector<GLuint> textures;
    vector<GLuint> programs;
    vector<GLuint> framebuffers;

    unsigned char   *scratchspace;

    PFNGLGENPROGRAMSARBPROC             m_glGenProgramsARB;
    PFNGLBINDPROGRAMARBPROC             m_glBindProgramARB;
    PFNGLPROGRAMSTRINGARBPROC           m_glProgramStringARB;
    PFNGLPROGRAMENVPARAMETER4FARBPROC   m_glProgramEnvParameter4fARB;
    PFNGLDELETEPROGRAMSARBPROC          m_glDeleteProgramsARB;
    PFNGLGETPROGRAMIVARBPROC            m_glGetProgramivARB;

    PFNGLGENFRAMEBUFFERSEXTPROC         m_glGenFramebuffersEXT;
    PFNGLBINDFRAMEBUFFEREXTPROC         m_glBindFramebufferEXT;
    PFNGLFRAMEBUFFERTEXTURE2DEXTPROC    m_glFramebufferTexture2DEXT;
    PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC  m_glCheckFramebufferStatusEXT;
    PFNGLDELETEFRAMEBUFFERSEXTPROC      m_glDeleteFramebuffersEXT;
};

#endif
