/*
  Simple DirectMedia Layer
  Copyright (C) 2017 BlackBerry Limited

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/

#include "../../SDL_internal.h"
#include "sdl_qnx.h"

static EGLDisplay   egl_disp;

/**
 * Detertmines the pixel format to use based on the current display and EGL
 * configuration.
 * @param   egl_conf    EGL configuration to use
 * @return  A SCREEN_FORMAT* constant for the pixel format to use
 */
static int
chooseFormat(EGLConfig egl_conf)
{
    EGLint buffer_bit_depth;
    EGLint alpha_bit_depth;

    eglGetConfigAttrib(egl_disp, egl_conf, EGL_BUFFER_SIZE, &buffer_bit_depth);
    eglGetConfigAttrib(egl_disp, egl_conf, EGL_ALPHA_SIZE, &alpha_bit_depth);

    switch (buffer_bit_depth) {
        case 32:
            return SCREEN_FORMAT_RGBX8888;
        case 24:
            return SCREEN_FORMAT_RGB888;
        case 16:
            switch (alpha_bit_depth) {
                case 4:
                    return SCREEN_FORMAT_RGBX4444;
                case 1:
                    return SCREEN_FORMAT_RGBA5551;
                default:
                    return SCREEN_FORMAT_RGB565;
            }
        default:
            return 0;
    }
}

/**
 * Enumerates the supported EGL configurations and chooses a suitable one.
 * @param[out]  pconf   The chosen configuration
 * @param[out]  pformat The chosen pixel format
 * @return 0 if successful, -1 on error
 */
int
glGetConfig(EGLConfig *pconf, int *pformat)
{
    EGLConfig egl_conf = (EGLConfig)0;
    EGLConfig *egl_configs;
    EGLint egl_num_configs;
    EGLint val;
    EGLBoolean rc;
    EGLint i;

    // Determine the numbfer of configurations.
    rc = eglGetConfigs(egl_disp, NULL, 0, &egl_num_configs);
    if (rc != EGL_TRUE) {
        return -1;
    }

    if (egl_num_configs == 0) {
        return -1;
    }

    // Allocate enough memory for all configurations.
    egl_configs = malloc(egl_num_configs * sizeof(*egl_configs));
    if (egl_configs == NULL) {
        return -1;
    }

    // Get the list of configurations.
    rc = eglGetConfigs(egl_disp, egl_configs, egl_num_configs,
                       &egl_num_configs);
    if (rc != EGL_TRUE) {
        free(egl_configs);
        return -1;
    }

    // Find a good configuration.
    for (i = 0; i < egl_num_configs; i++) {
        eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_SURFACE_TYPE, &val);
        if (!(val & EGL_WINDOW_BIT)) {
            continue;
        }

        eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RENDERABLE_TYPE, &val);
        if (!(val & EGL_OPENGL_ES2_BIT)) {
            continue;
        }

        eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_DEPTH_SIZE, &val);
        if (val == 0) {
            continue;
        }

        egl_conf = egl_configs[i];
        break;
    }

    free(egl_configs);
    *pconf = egl_conf;
    *pformat = chooseFormat(egl_conf);

    return 0;
}

/**
 * Initializes the EGL library.
 * @param   _THIS
 * @param   name    unused
 * @return  0 if successful, -1 on error
 */
int
glLoadLibrary(_THIS, const char *name)
{
    EGLNativeDisplayType    disp_id = EGL_DEFAULT_DISPLAY;

    egl_disp = eglGetDisplay(disp_id);
    if (egl_disp == EGL_NO_DISPLAY) {
        return -1;
    }

    if (eglInitialize(egl_disp, NULL, NULL) == EGL_FALSE) {
        return -1;
    }

    return 0;
}

/**
 * Finds the address of an EGL extension function.
 * @param   proc    Function name
 * @return  Function address
 */
void *
glGetProcAddress(_THIS, const char *proc)
{
    return eglGetProcAddress(proc);
}

/**
 * Associates the given window with the necessary EGL structures for drawing and
 * displaying content.
 * @param   _THIS
 * @param   window  The SDL window to create the context for
 * @return  A pointer to the created context, if successful, NULL on error
 */
SDL_GLContext
glCreateContext(_THIS, SDL_Window *window)
{
    window_impl_t   *impl = (window_impl_t *)window->driverdata;
    EGLContext      context;
    EGLSurface      surface;

    struct {
        EGLint client_version[2];
        EGLint none;
    } egl_ctx_attr = {
        .client_version = { EGL_CONTEXT_CLIENT_VERSION, 2 },
        .none = EGL_NONE
    };

    struct {
        EGLint render_buffer[2];
        EGLint none;
    } egl_surf_attr = {
        .render_buffer = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER },
        .none = EGL_NONE
    };

    context = eglCreateContext(egl_disp, impl->conf, EGL_NO_CONTEXT,
                               (EGLint *)&egl_ctx_attr);
    if (context == EGL_NO_CONTEXT) {
        return NULL;
    }

    surface = eglCreateWindowSurface(egl_disp, impl->conf, impl->window,
                                     (EGLint *)&egl_surf_attr);
    if (surface == EGL_NO_SURFACE) {
        return NULL;
    }

    eglMakeCurrent(egl_disp, surface, surface, context);

    impl->surface = surface;
    return context;
}

/**
 * Sets a new value for the number of frames to display before swapping buffers.
 * @param   _THIS
 * @param   interval    New interval value
 * @return  0 if successful, -1 on error
 */
int
glSetSwapInterval(_THIS, int interval)
{
    if (eglSwapInterval(egl_disp, interval) != EGL_TRUE) {
        return -1;
    }

    return 0;
}

/**
 * Swaps the EGL buffers associated with the given window
 * @param   _THIS
 * @param   window  Window to swap buffers for
 * @return  0 if successful, -1 on error
 */
int
glSwapWindow(_THIS, SDL_Window *window)
{
    /* !!! FIXME: should we migrate this all over to use SDL_egl.c? */
    window_impl_t   *impl = (window_impl_t *)window->driverdata;
    return eglSwapBuffers(egl_disp, impl->surface) == EGL_TRUE ? 0 : -1;
}

/**
 * Makes the given context the current one for drawing operations.
 * @param   _THIS
 * @param   window  SDL window associated with the context (maybe NULL)
 * @param   context The context to activate
 * @return  0 if successful, -1 on error
 */
int
glMakeCurrent(_THIS, SDL_Window *window, SDL_GLContext context)
{
    window_impl_t   *impl;
    EGLSurface      surface = NULL;

    if (window) {
        impl = (window_impl_t *)window->driverdata;
        surface = impl->surface;
    }

    if (eglMakeCurrent(egl_disp, surface, surface, context) != EGL_TRUE) {
        return -1;
    }

    return 0;
}

/**
 * Destroys a context.
 * @param   _THIS
 * @param   context The context to destroy
 */
void
glDeleteContext(_THIS, SDL_GLContext context)
{
    eglDestroyContext(egl_disp, context);
}

/**
 * Terminates access to the EGL library.
 * @param   _THIS
 */
void
glUnloadLibrary(_THIS)
{
    eglTerminate(egl_disp);
}
