/*
  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.
*/
#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_NACL

#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi_simple/ps.h"
#include "ppapi_simple/ps_interface.h"
#include "ppapi_simple/ps_event.h"
#include "nacl_io/nacl_io.h"

#include "SDL_naclvideo.h"
#include "SDL_naclwindow.h"
#include "SDL_naclevents_c.h"
#include "SDL_naclopengles.h"   
#include "SDL_video.h"
#include "../SDL_sysvideo.h"
#include "../../events/SDL_events_c.h"

#define NACLVID_DRIVER_NAME "nacl"

/* Static init required because NACL_SetScreenResolution 
 * may appear even before SDL starts and we want to remember
 * the window width and height
 */
static SDL_VideoData nacl = {0};

void
NACL_SetScreenResolution(int width, int height, Uint32 format)
{
    PP_Resource context;
    
    nacl.w = width;
    nacl.h = height;   
    nacl.format = format;
    
    if (nacl.window) {
        nacl.window->w = width;
        nacl.window->h = height;
        SDL_SendWindowEvent(nacl.window, SDL_WINDOWEVENT_RESIZED, width, height);
    }
    
    /* FIXME: Check threading issues...otherwise use a hardcoded _this->context across all threads */
    context = (PP_Resource) SDL_GL_GetCurrentContext();
    if (context) {
        PSInterfaceGraphics3D()->ResizeBuffers(context, width, height);
    }

}



/* Initialization/Query functions */
static int NACL_VideoInit(_THIS);
static void NACL_VideoQuit(_THIS);

static int NACL_Available(void) {
    return PSGetInstanceId() != 0;
}

static void NACL_DeleteDevice(SDL_VideoDevice *device) {
    SDL_VideoData *driverdata = (SDL_VideoData*) device->driverdata;
    driverdata->ppb_core->ReleaseResource((PP_Resource) driverdata->ppb_message_loop);
    SDL_free(device->driverdata);
    SDL_free(device);
}

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

static SDL_VideoDevice *NACL_CreateDevice(int devindex) {
    SDL_VideoDevice *device;
    
    /* Initialize all variables that we clean on shutdown */
    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
    if (!device) {
        SDL_OutOfMemory();
        return NULL;
    }
    device->driverdata = &nacl;
  
    /* Set the function pointers */
    device->VideoInit = NACL_VideoInit;
    device->VideoQuit = NACL_VideoQuit;
    device->PumpEvents = NACL_PumpEvents;
    
    device->CreateWindow = NACL_CreateWindow;
    device->SetWindowTitle = NACL_SetWindowTitle;
    device->DestroyWindow = NACL_DestroyWindow;
    
    device->SetDisplayMode = NACL_SetDisplayMode;
    
    device->free = NACL_DeleteDevice;
    
    /* GL pointers */
    device->GL_LoadLibrary = NACL_GLES_LoadLibrary;
    device->GL_GetProcAddress = NACL_GLES_GetProcAddress;
    device->GL_UnloadLibrary = NACL_GLES_UnloadLibrary;
    device->GL_CreateContext = NACL_GLES_CreateContext;
    device->GL_MakeCurrent = NACL_GLES_MakeCurrent;
    device->GL_SetSwapInterval = NACL_GLES_SetSwapInterval;
    device->GL_GetSwapInterval = NACL_GLES_GetSwapInterval;
    device->GL_SwapWindow = NACL_GLES_SwapWindow;
    device->GL_DeleteContext = NACL_GLES_DeleteContext;
    
    
    return device;
}

VideoBootStrap NACL_bootstrap = {
    NACLVID_DRIVER_NAME, "SDL Native Client Video Driver",
    NACL_Available, NACL_CreateDevice
};

int NACL_VideoInit(_THIS) {
    SDL_VideoData *driverdata = (SDL_VideoData *) _this->driverdata;
    SDL_DisplayMode mode;

    SDL_zero(mode);
    mode.format = driverdata->format;
    mode.w = driverdata->w;
    mode.h = driverdata->h;
    mode.refresh_rate = 0;
    mode.driverdata = NULL;
    if (SDL_AddBasicVideoDisplay(&mode) < 0) {
        return -1;
    }

    SDL_AddDisplayMode(&_this->displays[0], &mode);
    
    PSInterfaceInit();
    driverdata->instance = PSGetInstanceId();
    driverdata->ppb_graphics = PSInterfaceGraphics3D();
    driverdata->ppb_message_loop = PSInterfaceMessageLoop();
    driverdata->ppb_core = PSInterfaceCore();
    driverdata->ppb_fullscreen = PSInterfaceFullscreen();
    driverdata->ppb_instance = PSInterfaceInstance();
    driverdata->ppb_image_data = PSInterfaceImageData();
    driverdata->ppb_view = PSInterfaceView();
    driverdata->ppb_var = PSInterfaceVar();
    driverdata->ppb_input_event = (PPB_InputEvent*) PSGetInterface(PPB_INPUT_EVENT_INTERFACE);
    driverdata->ppb_keyboard_input_event = (PPB_KeyboardInputEvent*) PSGetInterface(PPB_KEYBOARD_INPUT_EVENT_INTERFACE);
    driverdata->ppb_mouse_input_event = (PPB_MouseInputEvent*) PSGetInterface(PPB_MOUSE_INPUT_EVENT_INTERFACE);
    driverdata->ppb_wheel_input_event = (PPB_WheelInputEvent*) PSGetInterface(PPB_WHEEL_INPUT_EVENT_INTERFACE);
    driverdata->ppb_touch_input_event = (PPB_TouchInputEvent*) PSGetInterface(PPB_TOUCH_INPUT_EVENT_INTERFACE);
    
    
    driverdata->message_loop = driverdata->ppb_message_loop->Create(driverdata->instance);
    
    PSEventSetFilter(PSE_ALL);
    
    /* We're done! */
    return 0;
}

void NACL_VideoQuit(_THIS) {
}

#endif /* SDL_VIDEO_DRIVER_NACL */
/* vi: set ts=4 sw=4 expandtab: */
