/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>

  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"

#if SDL_VIDEO_DRIVER_RPI

/* References
 * http://elinux.org/RPi_VideoCore_APIs
 * https://github.com/raspberrypi/firmware/blob/master/opt/vc/src/hello_pi/hello_triangle/triangle.c
 * http://cgit.freedesktop.org/wayland/weston/tree/src/rpi-renderer.c
 * http://cgit.freedesktop.org/wayland/weston/tree/src/compositor-rpi.c
 */

/* SDL internals */
#include "../SDL_sysvideo.h"
#include "SDL_version.h"
#include "SDL_syswm.h"
#include "SDL_loadso.h"
#include "SDL_events.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "SDL_hints.h"

#ifdef SDL_INPUT_LINUXEV
#include "../../core/linux/SDL_evdev.h"
#endif

/* RPI declarations */
#include "SDL_rpivideo.h"
#include "SDL_rpievents_c.h"
#include "SDL_rpiopengles.h"
#include "SDL_rpimouse.h"

static void
RPI_Destroy(SDL_VideoDevice * device)
{
    SDL_free(device->driverdata);
    SDL_free(device);
}

static int 
RPI_GetRefreshRate()
{
    TV_DISPLAY_STATE_T tvstate;
    if (vc_tv_get_display_state( &tvstate ) == 0) {
        //The width/height parameters are in the same position in the union
        //for HDMI and SDTV
        HDMI_PROPERTY_PARAM_T property;
        property.property = HDMI_PROPERTY_PIXEL_CLOCK_TYPE;
        vc_tv_hdmi_get_property(&property);
        return property.param1 == HDMI_PIXEL_CLOCK_TYPE_NTSC ? 
            tvstate.display.hdmi.frame_rate * (1000.0f/1001.0f) : 
            tvstate.display.hdmi.frame_rate;
    } 
    return 60;  /* Failed to get display state, default to 60 */
}

static SDL_VideoDevice *
RPI_Create()
{
    SDL_VideoDevice *device;
    SDL_VideoData *phdata;

    /* Initialize SDL_VideoDevice structure */
    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
    if (device == NULL) {
        SDL_OutOfMemory();
        return NULL;
    }

    /* Initialize internal data */
    phdata = (SDL_VideoData *) SDL_calloc(1, sizeof(SDL_VideoData));
    if (phdata == NULL) {
        SDL_OutOfMemory();
        SDL_free(device);
        return NULL;
    }

    device->driverdata = phdata;

    /* Setup amount of available displays */
    device->num_displays = 0;

    /* Set device free function */
    device->free = RPI_Destroy;

    /* Setup all functions which we can handle */
    device->VideoInit = RPI_VideoInit;
    device->VideoQuit = RPI_VideoQuit;
    device->GetDisplayModes = RPI_GetDisplayModes;
    device->SetDisplayMode = RPI_SetDisplayMode;
    device->CreateSDLWindow = RPI_CreateWindow;
    device->CreateSDLWindowFrom = RPI_CreateWindowFrom;
    device->SetWindowTitle = RPI_SetWindowTitle;
    device->SetWindowIcon = RPI_SetWindowIcon;
    device->SetWindowPosition = RPI_SetWindowPosition;
    device->SetWindowSize = RPI_SetWindowSize;
    device->ShowWindow = RPI_ShowWindow;
    device->HideWindow = RPI_HideWindow;
    device->RaiseWindow = RPI_RaiseWindow;
    device->MaximizeWindow = RPI_MaximizeWindow;
    device->MinimizeWindow = RPI_MinimizeWindow;
    device->RestoreWindow = RPI_RestoreWindow;
    device->SetWindowMouseGrab = RPI_SetWindowMouseGrab;
    device->DestroyWindow = RPI_DestroyWindow;
#if 0
    device->GetWindowWMInfo = RPI_GetWindowWMInfo;
#endif
    device->GL_LoadLibrary = RPI_GLES_LoadLibrary;
    device->GL_GetProcAddress = RPI_GLES_GetProcAddress;
    device->GL_UnloadLibrary = RPI_GLES_UnloadLibrary;
    device->GL_CreateContext = RPI_GLES_CreateContext;
    device->GL_MakeCurrent = RPI_GLES_MakeCurrent;
    device->GL_SetSwapInterval = RPI_GLES_SetSwapInterval;
    device->GL_GetSwapInterval = RPI_GLES_GetSwapInterval;
    device->GL_SwapWindow = RPI_GLES_SwapWindow;
    device->GL_DeleteContext = RPI_GLES_DeleteContext;
    device->GL_DefaultProfileConfig = RPI_GLES_DefaultProfileConfig;

    device->PumpEvents = RPI_PumpEvents;

    return device;
}

VideoBootStrap RPI_bootstrap = {
    "RPI",
    "RPI Video Driver",
    RPI_Create
};


/*****************************************************************************/
/* SDL Video and Display initialization/handling functions                   */
/*****************************************************************************/

static void
AddDispManXDisplay(const int display_id)
{
    DISPMANX_MODEINFO_T modeinfo;
    DISPMANX_DISPLAY_HANDLE_T handle;
    SDL_VideoDisplay display;
    SDL_DisplayMode current_mode;
    SDL_DisplayData *data;

    handle = vc_dispmanx_display_open(display_id);
    if (!handle) {
        return;  /* this display isn't available */
    }

    if (vc_dispmanx_display_get_info(handle, &modeinfo) < 0) {
        vc_dispmanx_display_close(handle);
        return;
    }

    /* RPI_GetRefreshRate() doesn't distinguish between displays. I'm not sure the hardware distinguishes either */
    SDL_zero(current_mode);
    current_mode.w = modeinfo.width;
    current_mode.h = modeinfo.height;
    current_mode.refresh_rate = RPI_GetRefreshRate();
    /* 32 bpp for default */
    current_mode.format = SDL_PIXELFORMAT_ABGR8888;

    current_mode.driverdata = NULL;

    SDL_zero(display);
    display.desktop_mode = current_mode;
    display.current_mode = current_mode;

    /* Allocate display internal data */
    data = (SDL_DisplayData *) SDL_calloc(1, sizeof(SDL_DisplayData));
    if (data == NULL) {
        vc_dispmanx_display_close(handle);
        return;  /* oh well */
    }

    data->dispman_display = handle;

    display.driverdata = data;

    SDL_AddVideoDisplay(&display, SDL_FALSE);
}

int
RPI_VideoInit(_THIS)
{
    /* Initialize BCM Host */
    bcm_host_init();

    AddDispManXDisplay(DISPMANX_ID_MAIN_LCD);  /* your default display */
    AddDispManXDisplay(DISPMANX_ID_FORCE_OTHER);  /* an "other" display...maybe DSI-connected screen while HDMI is your main */

#ifdef SDL_INPUT_LINUXEV    
    if (SDL_EVDEV_Init() < 0) {
        return -1;
    }
#endif    
    
    RPI_InitMouse(_this);

    return 1;
}

void
RPI_VideoQuit(_THIS)
{
#ifdef SDL_INPUT_LINUXEV    
    SDL_EVDEV_Quit();
#endif    
}

void
RPI_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
{
    /* Only one display mode available, the current one */
    SDL_AddDisplayMode(display, &display->current_mode);
}

int
RPI_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
{
    return 0;
}

static void
RPI_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data)
{
   SDL_WindowData *wdata = ((SDL_WindowData *) data);

   SDL_LockMutex(wdata->vsync_cond_mutex);
   SDL_CondSignal(wdata->vsync_cond);
   SDL_UnlockMutex(wdata->vsync_cond_mutex);
}

int
RPI_CreateWindow(_THIS, SDL_Window * window)
{
    SDL_WindowData *wdata;
    SDL_VideoDisplay *display;
    SDL_DisplayData *displaydata;
    VC_RECT_T dst_rect;
    VC_RECT_T src_rect;
    VC_DISPMANX_ALPHA_T         dispman_alpha;
    DISPMANX_UPDATE_HANDLE_T dispman_update;
    uint32_t layer = SDL_RPI_VIDEOLAYER;
    const char *env;

    /* Disable alpha, otherwise the app looks composed with whatever dispman is showing (X11, console,etc) */
    dispman_alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS; 
    dispman_alpha.opacity = 0xFF; 
    dispman_alpha.mask = 0;

    /* Allocate window internal data */
    wdata = (SDL_WindowData *) SDL_calloc(1, sizeof(SDL_WindowData));
    if (wdata == NULL) {
        return SDL_OutOfMemory();
    }
    display = SDL_GetDisplayForWindow(window);
    displaydata = (SDL_DisplayData *) display->driverdata;

    /* Windows have one size for now */
    window->w = display->desktop_mode.w;
    window->h = display->desktop_mode.h;

    /* OpenGL ES is the law here, buddy */
    window->flags |= SDL_WINDOW_OPENGL;

    /* Create a dispman element and associate a window to it */
    dst_rect.x = 0;
    dst_rect.y = 0;
    dst_rect.width = window->w;
    dst_rect.height = window->h;

    src_rect.x = 0;
    src_rect.y = 0;
    src_rect.width = window->w << 16;
    src_rect.height = window->h << 16;

    env = SDL_GetHint(SDL_HINT_RPI_VIDEO_LAYER);
    if (env) {
        layer = SDL_atoi(env);
    }

    dispman_update = vc_dispmanx_update_start( 0 );
    wdata->dispman_window.element = vc_dispmanx_element_add (dispman_update,
                                                             displaydata->dispman_display,
                                                             layer /* layer */,
                                                             &dst_rect,
                                                             0 /*src*/,
                                                             &src_rect,
                                                             DISPMANX_PROTECTION_NONE,
                                                             &dispman_alpha /*alpha*/,
                                                             0 /*clamp*/,
                                                             0 /*transform*/);
    wdata->dispman_window.width = window->w;
    wdata->dispman_window.height = window->h;
    vc_dispmanx_update_submit_sync(dispman_update);
    
    if (!_this->egl_data) {
        if (SDL_GL_LoadLibrary(NULL) < 0) {
            return -1;
        }
    }
    wdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) &wdata->dispman_window);

    if (wdata->egl_surface == EGL_NO_SURFACE) {
        return SDL_SetError("Could not create GLES window surface");
    }

    /* Start generating vsync callbacks if necesary */
    wdata->double_buffer = SDL_FALSE;
    if (SDL_GetHintBoolean(SDL_HINT_VIDEO_DOUBLE_BUFFER, SDL_FALSE)) {
        wdata->vsync_cond = SDL_CreateCond();
        wdata->vsync_cond_mutex = SDL_CreateMutex();
        wdata->double_buffer = SDL_TRUE;
        vc_dispmanx_vsync_callback(displaydata->dispman_display, RPI_vsync_callback, (void*)wdata);
    }

    /* Setup driver data for this window */
    window->driverdata = wdata;

    /* One window, it always has focus */
    SDL_SetMouseFocus(window);
    SDL_SetKeyboardFocus(window);

    /* Window has been successfully created */
    return 0;
}

void
RPI_DestroyWindow(_THIS, SDL_Window * window)
{
    SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata;

    if(data) {
        if (data->double_buffer) {
            /* Wait for vsync, and then stop vsync callbacks and destroy related stuff, if needed */
            SDL_LockMutex(data->vsync_cond_mutex);
            SDL_CondWait(data->vsync_cond, data->vsync_cond_mutex);
            SDL_UnlockMutex(data->vsync_cond_mutex);

            vc_dispmanx_vsync_callback(displaydata->dispman_display, NULL, NULL);

            SDL_DestroyCond(data->vsync_cond);
            SDL_DestroyMutex(data->vsync_cond_mutex);
        }

#if SDL_VIDEO_OPENGL_EGL
        if (data->egl_surface != EGL_NO_SURFACE) {
            SDL_EGL_DestroySurface(_this, data->egl_surface);
        }
#endif
        SDL_free(data);
        window->driverdata = NULL;
    }
}

int
RPI_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
    return -1;
}

void
RPI_SetWindowTitle(_THIS, SDL_Window * window)
{
}
void
RPI_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
}
void
RPI_SetWindowPosition(_THIS, SDL_Window * window)
{
}
void
RPI_SetWindowSize(_THIS, SDL_Window * window)
{
}
void
RPI_ShowWindow(_THIS, SDL_Window * window)
{
}
void
RPI_HideWindow(_THIS, SDL_Window * window)
{
}
void
RPI_RaiseWindow(_THIS, SDL_Window * window)
{
}
void
RPI_MaximizeWindow(_THIS, SDL_Window * window)
{
}
void
RPI_MinimizeWindow(_THIS, SDL_Window * window)
{
}
void
RPI_RestoreWindow(_THIS, SDL_Window * window)
{
}
void
RPI_SetWindowMouseGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{

}

/*****************************************************************************/
/* SDL Window Manager function                                               */
/*****************************************************************************/
#if 0
SDL_bool
RPI_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info)
{
    if (info->version.major <= SDL_MAJOR_VERSION) {
        return SDL_TRUE;
    } else {
        SDL_SetError("application not compiled with SDL %d.%d",
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
        return SDL_FALSE;
    }

    /* Failed to get window manager information */
    return SDL_FALSE;
}
#endif

#endif /* SDL_VIDEO_DRIVER_RPI */

/* vi: set ts=4 sw=4 expandtab: */
