#include "XcbGlInterface.h"

#include "FileLogger.h"
#include <iostream>

#include <GL/gl.h>

XcbGlInterface::XcbGlInterface(Display* display, int default_screen)
    : mDisplay(display),
      mContext(),
      mConfig()
{
    MLOG_INFO("Creating XcbGlInterface");
    setupContext(default_screen);
}

XcbGlInterface::~XcbGlInterface()
{
    MLOG_INFO("Destroying XcbGlInterface");
    destroyContext();
}

static int visual_attribs[] =
{
    GLX_X_RENDERABLE, True,
    GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
    GLX_RENDER_TYPE, GLX_RGBA_BIT,
    GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
    GLX_RED_SIZE, 8,
    GLX_GREEN_SIZE, 8,
    GLX_BLUE_SIZE, 8,
    GLX_ALPHA_SIZE, 8,
    GLX_DEPTH_SIZE, 24,
    GLX_STENCIL_SIZE, 8,
    GLX_DOUBLEBUFFER, True,
    //GLX_SAMPLE_BUFFERS  , 1,
    //GLX_SAMPLES         , 4,
    None
};

std::unique_ptr<XcbGlInterface> XcbGlInterface::Create(Display* display, int default_screen)
{
    return std::make_unique<XcbGlInterface>(display, default_screen);
}

void XcbGlInterface::setupContext(int default_screen)
{
    /* Query framebuffer configurations that match visual_attribs */
    int num_fb_configs = 0;
    GLXFBConfig* fb_configs = glXChooseFBConfig(mDisplay, default_screen, visual_attribs, &num_fb_configs);
    if (!fb_configs || num_fb_configs == 0)
    {
        MLOG_ERROR("glXGetFBConfigs failed");
        return;
    }

    /* Select first framebuffer config and query visualID */
    int visualID = 0;
    mConfig = fb_configs[0];
    glXGetFBConfigAttrib(mDisplay, mConfig, GLX_VISUAL_ID, &visualID);

    /* Create OpenGL context */
    mContext = glXCreateNewContext(mDisplay, mConfig, GLX_RGBA_TYPE, 0, True);
    if (!mContext)
    {
        MLOG_ERROR("glXCreateNewContext failed");
        return;
    }
}

void XcbGlInterface::destroyContext()
{
    glXDestroyContext(mDisplay, mContext);
}
