#ifndef VIDEOOUT_OPENGL_H_
#define VIDEOOUT_OPENGL_H_

#include <DisplayRes.h>
#include "videooutbase.h"
#include "NuppelVideoPlayer.h"

#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>

#define XMD_H 1
#include <X11/extensions/xf86vmode.h>

extern "C" {
#include <X11/extensions/Xinerama.h>
}

const int kMinOpenglTexSize = 64;
const int kNumberBuffers    = 2;

typedef struct GLframe
{
    uint   vid_width;
    uint   vid_height;
    GLint  tex_width;
    GLint  tex_height;
    QRect  position;
    long long uOffset;
    long long vOffset;
    GLuint tex;
};

class VideoOutputOpengl : public VideoOutput
{
  public:
    VideoOutputOpengl();
   ~VideoOutputOpengl();
    bool Init(int width, int height, float aspect, WId winid,
              int winx, int winy, int winw, int winh, WId embedid = 0);
    void PrepareFrame(VideoFrame *buffer, FrameScanType);
    void ShowPip(VideoFrame *frame, NuppelVideoPlayer *pipplayer);
    void Show(FrameScanType );
    void MoveResize();
    void InputChanged(int width, int height, float aspect, MythCodecID codec_id);
    void Zoom(int direction);
    void AspectChanged(float aspect);
    void EmbedInWidget(WId wid, int x, int y, int w, int h);
    void StopEmbedding(void);
    void ResizeForGui(void);
    void ResizeForVideo(uint width, uint height);
    void ResizeForVideo(void);
    int  GetRefreshRate(void);
    void DrawUnusedRects(bool sync = true);
    float GetDisplayAspect(void);
    void UpdatePauseFrame(void);
    void ProcessFrame(VideoFrame *frame, OSD *osd,
                      FilterChain *filterList,
                      NuppelVideoPlayer *pipPlayer);
    int SetPictureAttribute(int attributeType, int newValue);

  private:
    void SetViewPort();
    void InitOpenGL();
    void InitDisplayMeasurements(uint width, uint height);
    bool InitSetupBuffers(void);
    void CreateBuffers(void);
    void CreatePauseFrame(void);
    void DeleteBuffers(bool delete_pause_frame);
    bool CheckExtensions(void);
    bool LoadFragmentProgram(void);
    bool CreateVideoTexture(GLframe *frame, QSize size, QRect pos);
    bool CreateTexture(GLint width, GLint height, GLuint *tex, unsigned char *data);
    bool InitGlxContext(WId winid, int width, int height);
    void UpdateVideoTexture(GLframe vid, VideoFrame *buffer);

    // Misc.
    DisplayRes          *display_res;
    QMutex               global_lock;

    // Basic X11 info
    Window               XJ_win;
    Window               XJ_curwin;
    Display             *XJ_disp;
    int                  XJ_screen_num;
    bool                 XJ_started;

    // opengl 
    GLXContext           my_context;
    GLint                max_texture_size;
    GLuint               frag_prog;
    GLframe              glVideo;
    GLframe              glPip;
    bool                 texture_rects;
    int                  my_gl_texture;

    // General
    bool                 use_colourcontrols;
    VideoFrame           av_pause_frame;
    unsigned char       *scratchspace;
    bool                 actually_draw_pip;
};

#endif
