/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 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.
*/

/*
  Contributed by Brandon Schaefer, <brandon.schaefer@canonical.com>
*/

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

#if SDL_VIDEO_DRIVER_MIR

#include "SDL_mirwindow.h"
#include "SDL_video.h"

#include "SDL_mirframebuffer.h"
#include "SDL_mirmouse.h"
#include "SDL_miropengl.h"
#include "SDL_mirvideo.h"

#include "SDL_mirdyn.h"

#define MIR_DRIVER_NAME "mir"

static const Uint32 mir_pixel_format_to_sdl_format[] = {
    SDL_PIXELFORMAT_UNKNOWN,  /* mir_pixel_format_invalid   */
    SDL_PIXELFORMAT_ABGR8888, /* mir_pixel_format_abgr_8888 */
    SDL_PIXELFORMAT_BGR888,   /* mir_pixel_format_xbgr_8888 */
    SDL_PIXELFORMAT_ARGB8888, /* mir_pixel_format_argb_8888 */
    SDL_PIXELFORMAT_RGB888,   /* mir_pixel_format_xrgb_8888 */
    SDL_PIXELFORMAT_BGR24,    /* mir_pixel_format_bgr_888   */
    SDL_PIXELFORMAT_RGB24,    /* mir_pixel_format_rgb_888   */
    SDL_PIXELFORMAT_RGB565,   /* mir_pixel_format_rgb_565   */
    SDL_PIXELFORMAT_RGBA5551, /* mir_pixel_format_rgba_5551 */
    SDL_PIXELFORMAT_RGBA4444  /* mir_pixel_format_rgba_4444 */
};

Uint32
MIR_GetSDLPixelFormat(MirPixelFormat format)
{
    return mir_pixel_format_to_sdl_format[format];
}

static int
MIR_VideoInit(_THIS);

static void
MIR_VideoQuit(_THIS);

static int
MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect);

static void
MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* sdl_display);

static int
MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* sdl_display, SDL_DisplayMode* mode);

static SDL_WindowShaper*
MIR_CreateShaper(SDL_Window* window)
{
    /* FIXME Im not sure if mir support this atm, will have to come back to this */
    return NULL;
}

static int
MIR_SetWindowShape(SDL_WindowShaper* shaper, SDL_Surface* shape, SDL_WindowShapeMode* shape_mode)
{
    return SDL_Unsupported();
}

static int
MIR_ResizeWindowShape(SDL_Window* window)
{
    return SDL_Unsupported();
}

static int
MIR_Available()
{
    int available = 0;

    if (SDL_MIR_LoadSymbols()) {
        /* !!! FIXME: try to make a MirConnection here. */
        available = 1;
        SDL_MIR_UnloadSymbols();
    }

    return available;
}

static void
MIR_DeleteDevice(SDL_VideoDevice* device)
{
    SDL_free(device);
    SDL_MIR_UnloadSymbols();
}

static void
MIR_PumpEvents(_THIS)
{
}

static SDL_VideoDevice*
MIR_CreateDevice(int device_index)
{
    MIR_Data* mir_data;
    SDL_VideoDevice* device = NULL;

    if (!SDL_MIR_LoadSymbols()) {
        return NULL;
    }

    device = SDL_calloc(1, sizeof(SDL_VideoDevice));
    if (!device) {
        SDL_MIR_UnloadSymbols();
        SDL_OutOfMemory();
        return NULL;
    }

    mir_data = SDL_calloc(1, sizeof(MIR_Data));
    if (!mir_data) {
        SDL_free(device);
        SDL_MIR_UnloadSymbols();
        SDL_OutOfMemory();
        return NULL;
    }

    device->driverdata = mir_data;

    /* mirvideo */
    device->VideoInit        = MIR_VideoInit;
    device->VideoQuit        = MIR_VideoQuit;
    device->GetDisplayBounds = MIR_GetDisplayBounds;
    device->GetDisplayModes  = MIR_GetDisplayModes;
    device->SetDisplayMode   = MIR_SetDisplayMode;
    device->free             = MIR_DeleteDevice;

    /* miropengles */
    device->GL_SwapWindow      = MIR_GL_SwapWindow;
    device->GL_MakeCurrent     = MIR_GL_MakeCurrent;
    device->GL_CreateContext   = MIR_GL_CreateContext;
    device->GL_DeleteContext   = MIR_GL_DeleteContext;
    device->GL_LoadLibrary     = MIR_GL_LoadLibrary;
    device->GL_UnloadLibrary   = MIR_GL_UnloadLibrary;
    device->GL_GetSwapInterval = MIR_GL_GetSwapInterval;
    device->GL_SetSwapInterval = MIR_GL_SetSwapInterval;
    device->GL_GetProcAddress  = MIR_GL_GetProcAddress;

    /* mirwindow */
    device->CreateWindow         = MIR_CreateWindow;
    device->DestroyWindow        = MIR_DestroyWindow;
    device->GetWindowWMInfo      = MIR_GetWindowWMInfo;
    device->SetWindowFullscreen  = MIR_SetWindowFullscreen;
    device->MaximizeWindow       = MIR_MaximizeWindow;
    device->MinimizeWindow       = MIR_MinimizeWindow;
    device->RestoreWindow        = MIR_RestoreWindow;
    device->ShowWindow           = MIR_RestoreWindow;
    device->HideWindow           = MIR_HideWindow;
    device->SetWindowSize        = MIR_SetWindowSize;
    device->SetWindowMinimumSize = MIR_SetWindowMinimumSize;
    device->SetWindowMaximumSize = MIR_SetWindowMaximumSize;
    device->SetWindowTitle       = MIR_SetWindowTitle;
    device->SetWindowGrab        = MIR_SetWindowGrab;

    device->CreateWindowFrom     = NULL;
    device->SetWindowIcon        = NULL;
    device->RaiseWindow          = NULL;
    device->SetWindowBordered    = NULL;
    device->SetWindowGammaRamp   = NULL;
    device->GetWindowGammaRamp   = NULL;
    device->OnWindowEnter        = NULL;
    device->SetWindowPosition    = NULL;

    /* mirframebuffer */
    device->CreateWindowFramebuffer  = MIR_CreateWindowFramebuffer;
    device->UpdateWindowFramebuffer  = MIR_UpdateWindowFramebuffer;
    device->DestroyWindowFramebuffer = MIR_DestroyWindowFramebuffer;

    device->shape_driver.CreateShaper      = MIR_CreateShaper;
    device->shape_driver.SetWindowShape    = MIR_SetWindowShape;
    device->shape_driver.ResizeWindowShape = MIR_ResizeWindowShape;

    device->PumpEvents = MIR_PumpEvents;

    device->SuspendScreenSaver = NULL;

    device->StartTextInput   = NULL;
    device->StopTextInput    = NULL;
    device->SetTextInputRect = NULL;

    device->HasScreenKeyboardSupport = NULL;
    device->ShowScreenKeyboard       = NULL;
    device->HideScreenKeyboard       = NULL;
    device->IsScreenKeyboardShown    = NULL;

    device->SetClipboardText = NULL;
    device->GetClipboardText = NULL;
    device->HasClipboardText = NULL;

    device->ShowMessageBox = NULL;

    return device;
}

VideoBootStrap MIR_bootstrap = {
    MIR_DRIVER_NAME, "SDL Mir video driver",
    MIR_Available, MIR_CreateDevice
};

static SDL_DisplayMode
MIR_ConvertModeToSDLMode(MirOutputMode const* mode, MirPixelFormat format)
{
    SDL_DisplayMode sdl_mode  = {
        .format = MIR_GetSDLPixelFormat(format),
        .w      = MIR_mir_output_mode_get_width(mode),
        .h      = MIR_mir_output_mode_get_height(mode),
        .refresh_rate = MIR_mir_output_mode_get_refresh_rate(mode),
        .driverdata   = NULL
    };

    return sdl_mode;
}

static void
MIR_AddModeToDisplay(SDL_VideoDisplay* display, MirOutputMode const* mode, MirPixelFormat format)
{
    SDL_DisplayMode sdl_mode = MIR_ConvertModeToSDLMode(mode, format);
    SDL_AddDisplayMode(display, &sdl_mode);
}

static void
MIR_InitDisplayFromOutput(_THIS, MirOutput* output)
{
    SDL_VideoDisplay display;
    int m;

    MirPixelFormat format = MIR_mir_output_get_current_pixel_format(output);
    int num_modes         = MIR_mir_output_get_num_modes(output);
    SDL_DisplayMode current_mode = MIR_ConvertModeToSDLMode(mir_output_get_current_mode(output), format);

    SDL_zero(display);

    // Unfortunate cast, but SDL_AddVideoDisplay will strdup this pointer so its read-only in this case.
    display.name = (char*)MIR_mir_output_type_name(MIR_mir_output_get_type(output));

    for (m = 0; m < num_modes; m++) {
        MirOutputMode const* mode = MIR_mir_output_get_mode(output, m);
        MIR_AddModeToDisplay(&display, mode, format);
    }

    display.desktop_mode = current_mode;
    display.current_mode = current_mode;

    display.driverdata = output;
    SDL_AddVideoDisplay(&display);
}

static void
MIR_InitDisplays(_THIS)
{
    MIR_Data* mir_data = _this->driverdata;
    int num_outputs    = MIR_mir_display_config_get_num_outputs(mir_data->display_config);
    int d;

    for (d = 0; d < num_outputs; d++) {
        MirOutput* output = MIR_mir_display_config_get_mutable_output(mir_data->display_config, d);
        SDL_bool enabled  = MIR_mir_output_is_enabled(output);
        MirOutputConnectionState state = MIR_mir_output_get_connection_state(output);

        if (enabled && state == mir_output_connection_state_connected) {
            MIR_InitDisplayFromOutput(_this, output);
        }
    }
}

static int
MIR_VideoInit(_THIS)
{
    MIR_Data* mir_data = _this->driverdata;

    mir_data->connection     = MIR_mir_connect_sync(NULL, __PRETTY_FUNCTION__);
    mir_data->current_window = NULL;
    mir_data->software       = SDL_FALSE;
    mir_data->pixel_format   = mir_pixel_format_invalid;

    if (!MIR_mir_connection_is_valid(mir_data->connection)) {
        return SDL_SetError("Failed to connect to the mir server: %s",
            MIR_mir_connection_get_error_message(mir_data->connection));
    }

    mir_data->display_config = MIR_mir_connection_create_display_configuration(mir_data->connection);

    MIR_InitDisplays(_this);
    MIR_InitMouse();

    return 0;
}

static void
MIR_CleanUpDisplayConfig(_THIS)
{
    MIR_Data* mir_data = _this->driverdata;
    int i;

    // SDL_VideoQuit frees the display driverdata, we own it not them
    for (i = 0; i < _this->num_displays; ++i) {
        _this->displays[i].driverdata = NULL;
    }

    MIR_mir_display_config_release(mir_data->display_config);
}

static void
MIR_VideoQuit(_THIS)
{
    MIR_Data* mir_data = _this->driverdata;

    MIR_CleanUpDisplayConfig(_this);

    MIR_FiniMouse();

    MIR_GL_DeleteContext(_this, NULL);
    MIR_GL_UnloadLibrary(_this);

    MIR_mir_connection_release(mir_data->connection);

    SDL_free(mir_data);
    _this->driverdata = NULL;
}

static int
MIR_GetDisplayBounds(_THIS, SDL_VideoDisplay* display, SDL_Rect* rect)
{
    MirOutput const* output = display->driverdata;

    rect->x = MIR_mir_output_get_position_x(output);
    rect->y = MIR_mir_output_get_position_y(output);
    rect->w = display->current_mode.w;
    rect->h = display->current_mode.h;

    return 0;
}

static void
MIR_GetDisplayModes(_THIS, SDL_VideoDisplay* display)
{
}

static int
MIR_SetDisplayMode(_THIS, SDL_VideoDisplay* display, SDL_DisplayMode* mode)
{
    int m;
    MirOutput* output = display->driverdata;
    int num_modes     = MIR_mir_output_get_num_modes(output);
    Uint32 sdl_format = MIR_GetSDLPixelFormat(
                            MIR_mir_output_get_current_pixel_format(output));

    for (m = 0; m < num_modes; m++) {
        MirOutputMode const* mir_mode = MIR_mir_output_get_mode(output, m);
        int width  = MIR_mir_output_mode_get_width(mir_mode);
        int height = MIR_mir_output_mode_get_height(mir_mode);
        double refresh_rate = MIR_mir_output_mode_get_refresh_rate(mir_mode);

        if (mode->format == sdl_format &&
            mode->w      == width &&
            mode->h      == height &&
            mode->refresh_rate == refresh_rate) {

            // FIXME Currently wont actually *set* anything. Need to wait for applying display changes
            MIR_mir_output_set_current_mode(output, mir_mode);
            return 0;
        }
    }

    return -1;
}

#endif /* SDL_VIDEO_DRIVER_MIR */

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

