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

#include "SDL_DirectFB_video.h"
#include "SDL_DirectFB_modes.h"
#include "SDL_DirectFB_window.h"
#include "SDL_DirectFB_shape.h"

#if SDL_DIRECTFB_OPENGL
#include "SDL_DirectFB_opengl.h"
#endif

#include "SDL_syswm.h"

#include "../SDL_pixels_c.h"

int
DirectFB_CreateWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_DISPLAYDATA(window);
    DFB_WindowData *windata = NULL;
    DFBWindowOptions wopts;
    DFBWindowDescription desc;
    int x, y;
    int bshaped = 0;

    SDL_DFB_ALLOC_CLEAR(window->driverdata, sizeof(DFB_WindowData));
    SDL_memset(&desc, 0, sizeof(DFBWindowDescription));
    windata = (DFB_WindowData *) window->driverdata;

    windata->is_managed = devdata->has_own_wm;
#if 1
    SDL_DFB_CHECKERR(devdata->dfb->SetCooperativeLevel(devdata->dfb,
                                                       DFSCL_NORMAL));
    SDL_DFB_CHECKERR(dispdata->layer->SetCooperativeLevel(dispdata->layer,
                                                          DLSCL_ADMINISTRATIVE));
#endif
    /* FIXME ... ughh, ugly */
    if (window->x == -1000 && window->y == -1000)
        bshaped = 1;

    /* Fill the window description. */
    x = window->x;
    y = window->y;

    DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);

    /* Create Window */
    desc.caps = 0;
    desc.flags =
        DWDESC_WIDTH | DWDESC_HEIGHT | DWDESC_POSX | DWDESC_POSY | DWDESC_SURFACE_CAPS;

    if (bshaped) {
        desc.flags |= DWDESC_CAPS;
        desc.caps |= DWCAPS_ALPHACHANNEL;
    }
    else
    {
        desc.flags |= DWDESC_PIXELFORMAT;
    }

    if (!(window->flags & SDL_WINDOW_BORDERLESS))
        desc.caps |= DWCAPS_NODECORATION;

    desc.posx = x;
    desc.posy = y;
    desc.width = windata->size.w;
    desc.height = windata->size.h;
    desc.pixelformat = dispdata->pixelformat;
    desc.surface_caps = DSCAPS_PREMULTIPLIED;
#if DIRECTFB_MAJOR_VERSION == 1 && DIRECTFB_MINOR_VERSION >= 6
    if (window->flags & SDL_WINDOW_OPENGL) {
        desc.surface_caps |= DSCAPS_GL;
    }
#endif

    /* Create the window. */
    SDL_DFB_CHECKERR(dispdata->layer->CreateWindow(dispdata->layer, &desc,
                                                   &windata->dfbwin));

    /* Set Options */
    SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));

    /* explicit rescaling of surface */
    wopts |= DWOP_SCALE;
    if (window->flags & SDL_WINDOW_RESIZABLE) {
        wopts &= ~DWOP_KEEP_SIZE;
    }
    else {
        wopts |= DWOP_KEEP_SIZE;
    }

    if (window->flags & SDL_WINDOW_FULLSCREEN) {
        wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_STACKING | DWOP_KEEP_SIZE;
        SDL_DFB_CHECK(windata->dfbwin->SetStackingClass(windata->dfbwin, DWSC_UPPER));
    }

    if (bshaped) {
        wopts |= DWOP_SHAPED | DWOP_ALPHACHANNEL;
        wopts &= ~DWOP_OPAQUE_REGION;
    }

    SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));

    /* See what we got */
    SDL_DFB_CHECK(DirectFB_WM_GetClientSize
                     (_this, window, &window->w, &window->h));

    /* Get the window's surface. */
    SDL_DFB_CHECKERR(windata->dfbwin->GetSurface(windata->dfbwin,
                                                 &windata->window_surface));

    /* And get a subsurface for rendering */
    SDL_DFB_CHECKERR(windata->window_surface->
                     GetSubSurface(windata->window_surface, &windata->client,
                                   &windata->surface));

    SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0xFF));

    /* Create Eventbuffer */

    SDL_DFB_CHECKERR(windata->dfbwin->CreateEventBuffer(windata->dfbwin,
                                                        &windata->
                                                        eventbuffer));
    SDL_DFB_CHECKERR(windata->dfbwin->
                     EnableEvents(windata->dfbwin, DWET_ALL));

    /* Create a font */
    /* FIXME: once during Video_Init */
    windata->font = NULL;

    /* Make it the top most window. */
    SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));

    /* remember parent */
    /* windata->sdlwin = window; */

    /* Add to list ... */

    windata->next = devdata->firstwin;
    windata->opacity = 0xFF;
    devdata->firstwin = window;

    /* Draw Frame */
    DirectFB_WM_RedrawLayout(_this, window);

    return 0;
  error:
    SDL_DFB_RELEASE(windata->surface);
    SDL_DFB_RELEASE(windata->dfbwin);
    return -1;
}

int
DirectFB_CreateWindowFrom(_THIS, SDL_Window * window, const void *data)
{
    return SDL_Unsupported();
}

void
DirectFB_SetWindowTitle(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    if (windata->is_managed) {
        windata->wm_needs_redraw = 1;
        DirectFB_WM_RedrawLayout(_this, window);
    } else {
        SDL_Unsupported();
    }
}

void
DirectFB_SetWindowIcon(_THIS, SDL_Window * window, SDL_Surface * icon)
{
    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);
    SDL_Surface *surface = NULL;

    if (icon) {
        SDL_PixelFormat format;
        DFBSurfaceDescription dsc;
        Uint32 *dest;
        Uint32 *p;
        int pitch, i;

        /* Convert the icon to ARGB for modern window managers */
        SDL_InitFormat(&format, SDL_PIXELFORMAT_ARGB8888);
        surface = SDL_ConvertSurface(icon, &format, 0);
        if (!surface) {
            return;
        }
        dsc.flags =
            DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
        dsc.caps = DSCAPS_VIDEOONLY;
        dsc.width = surface->w;
        dsc.height = surface->h;
        dsc.pixelformat = DSPF_ARGB;

        SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
                                                     &windata->icon));

        SDL_DFB_CHECKERR(windata->icon->Lock(windata->icon, DSLF_WRITE,
                                             (void *) &dest, &pitch));

        p = surface->pixels;
        for (i = 0; i < surface->h; i++)
            memcpy((char *) dest + i * pitch,
                   (char *) p + i * surface->pitch, 4 * surface->w);

        SDL_DFB_CHECK(windata->icon->Unlock(windata->icon));
        SDL_FreeSurface(surface);
    } else {
        SDL_DFB_RELEASE(windata->icon);
    }
    return;
  error:
    SDL_FreeSurface(surface);
    SDL_DFB_RELEASE(windata->icon);
    return;
}

void
DirectFB_SetWindowPosition(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);
    int x, y;

    x = window->x;
    y = window->y;

    DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
    SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, x, y));
}

void
DirectFB_SetWindowSize(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    if(SDL_IsShapedWindow(window))
        DirectFB_ResizeWindowShape(window);

    if (!(window->flags & SDL_WINDOW_FULLSCREEN)) {
        int cw;
        int ch;

        /* Make sure all events are disabled for this operation ! */
        SDL_DFB_CHECKERR(windata->dfbwin->DisableEvents(windata->dfbwin,
                                                        DWET_ALL));
        SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize(_this, window, &cw, &ch));

        if (cw != window->w || ch != window->h) {

            DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);
            SDL_DFB_CHECKERR(windata->dfbwin->Resize(windata->dfbwin,
                                                     windata->size.w,
                                                     windata->size.h));
        }

        SDL_DFB_CHECKERR(DirectFB_WM_GetClientSize
                     (_this, window, &window->w, &window->h));
        DirectFB_AdjustWindowSurface(window);

        SDL_DFB_CHECKERR(windata->dfbwin->EnableEvents(windata->dfbwin,
                                                       DWET_ALL));

    }
    return;
  error:
    SDL_DFB_CHECK(windata->dfbwin->EnableEvents(windata->dfbwin, DWET_ALL));
    return;
}

void
DirectFB_ShowWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, windata->opacity));

}

void
DirectFB_HideWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    SDL_DFB_CHECK(windata->dfbwin->GetOpacity(windata->dfbwin, &windata->opacity));
    SDL_DFB_CHECK(windata->dfbwin->SetOpacity(windata->dfbwin, 0));
}

void
DirectFB_RaiseWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);

    SDL_DFB_CHECK(windata->dfbwin->RaiseToTop(windata->dfbwin));
    SDL_DFB_CHECK(windata->dfbwin->RequestFocus(windata->dfbwin));
}

void
DirectFB_MaximizeWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    DFBWindowOptions wopts;

    SDL_DFB_CHECK(windata->dfbwin->GetPosition(windata->dfbwin,
                                 &windata->restore.x, &windata->restore.y));
    SDL_DFB_CHECK(windata->dfbwin->GetSize(windata->dfbwin, &windata->restore.w,
                             &windata->restore.h));

    DirectFB_WM_AdjustWindowLayout(window, window->flags | SDL_WINDOW_MAXIMIZED, display->current_mode.w, display->current_mode.h) ;

    SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, 0, 0));
    SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin,
                            display->current_mode.w, display->current_mode.h));

    /* Set Options */
    SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
    wopts |= DWOP_KEEP_SIZE | DWOP_KEEP_POSITION;
    SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));
}

void
DirectFB_MinimizeWindow(_THIS, SDL_Window * window)
{
    /* FIXME: Size to 32x32 ? */

    SDL_Unsupported();
}

void
DirectFB_RestoreWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);
    DFBWindowOptions wopts;

    /* Set Options */
    SDL_DFB_CHECK(windata->dfbwin->GetOptions(windata->dfbwin, &wopts));
    wopts &= ~(DWOP_KEEP_SIZE | DWOP_KEEP_POSITION);
    SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));

    /* Window layout */
    DirectFB_WM_AdjustWindowLayout(window, window->flags & ~(SDL_WINDOW_MAXIMIZED | SDL_WINDOW_MINIMIZED),
        windata->restore.w, windata->restore.h);
    SDL_DFB_CHECK(windata->dfbwin->Resize(windata->dfbwin, windata->restore.w,
                            windata->restore.h));
    SDL_DFB_CHECK(windata->dfbwin->MoveTo(windata->dfbwin, windata->restore.x,
                            windata->restore.y));

    if (!(window->flags & SDL_WINDOW_RESIZABLE))
        wopts |= DWOP_KEEP_SIZE;

    if (window->flags & SDL_WINDOW_FULLSCREEN)
        wopts |= DWOP_KEEP_POSITION | DWOP_KEEP_SIZE;
    SDL_DFB_CHECK(windata->dfbwin->SetOptions(windata->dfbwin, wopts));


}

void
DirectFB_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
{
    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);
    DFB_WindowData *gwindata = ((devdata->grabbed_window) ? (DFB_WindowData *) ((devdata->grabbed_window)->driverdata) : NULL);

    if ((window->flags & SDL_WINDOW_INPUT_GRABBED)) {
        if (gwindata != NULL)
        {
            SDL_DFB_CHECK(gwindata->dfbwin->UngrabPointer(gwindata->dfbwin));
            SDL_DFB_CHECK(gwindata->dfbwin->UngrabKeyboard(gwindata->dfbwin));
        }
        SDL_DFB_CHECK(windata->dfbwin->GrabPointer(windata->dfbwin));
        SDL_DFB_CHECK(windata->dfbwin->GrabKeyboard(windata->dfbwin));
        devdata->grabbed_window = window;
    } else {
        SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
        SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));
        devdata->grabbed_window = NULL;
    }
}

void
DirectFB_DestroyWindow(_THIS, SDL_Window * window)
{
    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);
    DFB_WindowData *p;

    /* Some cleanups */
    SDL_DFB_CHECK(windata->dfbwin->UngrabPointer(windata->dfbwin));
    SDL_DFB_CHECK(windata->dfbwin->UngrabKeyboard(windata->dfbwin));

#if SDL_DIRECTFB_OPENGL
    DirectFB_GL_DestroyWindowContexts(_this, window);
#endif

    if (window->shaper)
    {
        SDL_ShapeData *data = window->shaper->driverdata;
        SDL_DFB_CHECK(data->surface->ReleaseSource(data->surface));
        SDL_DFB_RELEASE(data->surface);
        SDL_DFB_FREE(data);
        SDL_DFB_FREE(window->shaper);
    }

    SDL_DFB_CHECK(windata->window_surface->SetFont(windata->window_surface, NULL));
    SDL_DFB_CHECK(windata->surface->ReleaseSource(windata->surface));
    SDL_DFB_CHECK(windata->window_surface->ReleaseSource(windata->window_surface));
    SDL_DFB_RELEASE(windata->icon);
    SDL_DFB_RELEASE(windata->font);
    SDL_DFB_RELEASE(windata->eventbuffer);
    SDL_DFB_RELEASE(windata->surface);
    SDL_DFB_RELEASE(windata->window_surface);

    SDL_DFB_RELEASE(windata->dfbwin);

    /* Remove from list ... */

    p = devdata->firstwin->driverdata;

    while (p && p->next != window)
        p = (p->next ? p->next->driverdata : NULL);
    if (p)
        p->next = windata->next;
    else
        devdata->firstwin = windata->next;
    SDL_free(windata);
    return;
}

SDL_bool
DirectFB_GetWindowWMInfo(_THIS, SDL_Window * window,
                         struct SDL_SysWMinfo * info)
{
    const Uint32 version = ((((Uint32) info->version.major) * 1000000) +
                            (((Uint32) info->version.minor) * 10000) +
                            (((Uint32) info->version.patch)));

    SDL_DFB_DEVICEDATA(_this);
    SDL_DFB_WINDOWDATA(window);

    /* Before 2.0.6, it was possible to build an SDL with DirectFB support
       (SDL_SysWMinfo will be large enough to hold DirectFB info), but build
       your app against SDL headers that didn't have DirectFB support
       (SDL_SysWMinfo could be smaller than DirectFB needs. This would lead
       to an app properly using SDL_GetWindowWMInfo() but we'd accidentally
       overflow memory on the stack or heap. To protect against this, we've
       padded out the struct unconditionally in the headers and DirectFB will
       just return an error for older apps using this function. Those apps
       will need to be recompiled against newer headers or not use DirectFB,
       maybe by forcing SDL_VIDEODRIVER=x11. */
    if (version < 2000006) {
        info->subsystem = SDL_SYSWM_UNKNOWN;
        SDL_SetError("Version must be 2.0.6 or newer");
        return SDL_FALSE;
    }

    if (info->version.major == SDL_MAJOR_VERSION &&
        info->version.minor == SDL_MINOR_VERSION) {
        info->subsystem = SDL_SYSWM_DIRECTFB;
        info->info.dfb.dfb = devdata->dfb;
        info->info.dfb.window = windata->dfbwin;
        info->info.dfb.surface = windata->surface;
        return SDL_TRUE;
    } else {
        SDL_SetError("Application not compiled with SDL %d.%d",
                     SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
        return SDL_FALSE;
    }
}

void
DirectFB_AdjustWindowSurface(SDL_Window * window)
{
    SDL_DFB_WINDOWDATA(window);
    int adjust = windata->wm_needs_redraw;
    int cw, ch;

    DirectFB_WM_AdjustWindowLayout(window, window->flags, window->w, window->h);

    SDL_DFB_CHECKERR(windata->
                     window_surface->GetSize(windata->window_surface, &cw,
                                             &ch));
    if (cw != windata->size.w || ch != windata->size.h) {
        adjust = 1;
    }

    if (adjust) {
#if SDL_DIRECTFB_OPENGL
        DirectFB_GL_FreeWindowContexts(SDL_GetVideoDevice(), window);
#endif

#if (DFB_VERSION_ATLEAST(1,2,1))
        SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
                                                        windata->size.w,
                                                        windata->size.h));
        SDL_DFB_CHECKERR(windata->surface->MakeSubSurface(windata->surface,
                                                          windata->
                                                          window_surface,
                                                          &windata->client));
#else
        DFBWindowOptions opts;

        SDL_DFB_CHECKERR(windata->dfbwin->GetOptions(windata->dfbwin, &opts));
        /* recreate subsurface */
        SDL_DFB_RELEASE(windata->surface);

        if (opts & DWOP_SCALE)
            SDL_DFB_CHECKERR(windata->dfbwin->ResizeSurface(windata->dfbwin,
                                                            windata->size.w,
                                                            windata->size.h));
        SDL_DFB_CHECKERR(windata->window_surface->
                         GetSubSurface(windata->window_surface,
                                       &windata->client, &windata->surface));
#endif
        DirectFB_WM_RedrawLayout(SDL_GetVideoDevice(), window);

#if SDL_DIRECTFB_OPENGL
        DirectFB_GL_ReAllocWindowContexts(SDL_GetVideoDevice(), window);
#endif
   }
  error:
    return;
}

int
DirectFB_SetWindowOpacity(_THIS, SDL_Window * window, float opacity)
{
    const Uint8 alpha = (Uint8) ((unsigned int) (opacity * 255.0f));
    SDL_DFB_WINDOWDATA(window);
    SDL_DFB_CHECKERR(windata->dfbwin->SetOpacity(windata->dfbwin, alpha));
    windata->opacity = alpha;
    return 0;

error:
    return -1;
}

#endif /* SDL_VIDEO_DRIVER_DIRECTFB */
