/*
  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_DIRECTFB

#include "SDL_assert.h"

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

#include "../SDL_sysvideo.h"
#include "../../events/SDL_mouse_c.h"

static SDL_Cursor *DirectFB_CreateDefaultCursor(void);
static SDL_Cursor *DirectFB_CreateCursor(SDL_Surface * surface,
                                         int hot_x, int hot_y);
static int DirectFB_ShowCursor(SDL_Cursor * cursor);
static void DirectFB_MoveCursor(SDL_Cursor * cursor);
static void DirectFB_FreeCursor(SDL_Cursor * cursor);
static void DirectFB_WarpMouse(SDL_Window * window, int x, int y);
static void DirectFB_FreeMouse(SDL_Mouse * mouse);

static const char *arrow[] = {
    /* pixels */
    "X                               ",
    "XX                              ",
    "X.X                             ",
    "X..X                            ",
    "X...X                           ",
    "X....X                          ",
    "X.....X                         ",
    "X......X                        ",
    "X.......X                       ",
    "X........X                      ",
    "X.....XXXXX                     ",
    "X..X..X                         ",
    "X.X X..X                        ",
    "XX  X..X                        ",
    "X    X..X                       ",
    "     X..X                       ",
    "      X..X                      ",
    "      X..X                      ",
    "       XX                       ",
    "                                ",
    "                                ",
    "                                ",
    "                                ",
    "                                ",
    "                                ",
    "                                ",
    "                                ",
    "                                ",
    "                                ",
    "                                ",
    "                                ",
    "                                ",
};

static SDL_Cursor *
DirectFB_CreateDefaultCursor(void)
{
    SDL_VideoDevice *dev = SDL_GetVideoDevice();

    SDL_DFB_DEVICEDATA(dev);
    DFB_CursorData *curdata;
    DFBResult ret;
    DFBSurfaceDescription dsc;
    SDL_Cursor *cursor;
    Uint32 *dest;
    Uint32 *p;
    int pitch, i, j;

    SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
    SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));

    dsc.flags =
        DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
    dsc.caps = DSCAPS_VIDEOONLY;
    dsc.width = 32;
    dsc.height = 32;
    dsc.pixelformat = DSPF_ARGB;

    SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
                                                 &curdata->surf));
    curdata->hotx = 0;
    curdata->hoty = 0;
    cursor->driverdata = curdata;

    SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, DSLF_WRITE,
                                         (void *) &dest, &pitch));

    /* Relies on the fact that this is only called with ARGB surface. */
    for (i = 0; i < 32; i++)
    {
        for (j = 0; j < 32; j++)
        {
            switch (arrow[i][j])
            {
            case ' ': dest[j] = 0x00000000; break;
            case '.': dest[j] = 0xffffffff; break;
            case 'X': dest[j] = 0xff000000; break;
            }
        }
        dest += (pitch >> 2);
    }

    curdata->surf->Unlock(curdata->surf);
    return cursor;
  error:
    return NULL;
}

/* Create a cursor from a surface */
static SDL_Cursor *
DirectFB_CreateCursor(SDL_Surface * surface, int hot_x, int hot_y)
{
    SDL_VideoDevice *dev = SDL_GetVideoDevice();

    SDL_DFB_DEVICEDATA(dev);
    DFB_CursorData *curdata;
    DFBResult ret;
    DFBSurfaceDescription dsc;
    SDL_Cursor *cursor;
    Uint32 *dest;
    Uint32 *p;
    int pitch, i;

    SDL_assert(surface->format->format == SDL_PIXELFORMAT_ARGB8888);
    SDL_assert(surface->pitch == surface->w * 4);

    SDL_DFB_ALLOC_CLEAR( cursor, sizeof(*cursor));
    SDL_DFB_ALLOC_CLEAR(curdata, sizeof(*curdata));

    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,
                                                 &curdata->surf));
    curdata->hotx = hot_x;
    curdata->hoty = hot_y;
    cursor->driverdata = curdata;

    SDL_DFB_CHECKERR(curdata->surf->Lock(curdata->surf, 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);

    curdata->surf->Unlock(curdata->surf);
    return cursor;
  error:
    return NULL;
}

/* Show the specified cursor, or hide if cursor is NULL */
static int
DirectFB_ShowCursor(SDL_Cursor * cursor)
{
    SDL_DFB_CURSORDATA(cursor);
    DFBResult ret;
    SDL_Window *window;

    window = SDL_GetFocusWindow();
    if (!window)
        return -1;
    else {
        SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);

        if (display) {
            DFB_DisplayData *dispdata =
                (DFB_DisplayData *) display->driverdata;
            DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;

            if (cursor)
                SDL_DFB_CHECKERR(windata->dfbwin->
                                 SetCursorShape(windata->dfbwin,
                                                curdata->surf, curdata->hotx,
                                                curdata->hoty));

            SDL_DFB_CHECKERR(dispdata->layer->
                             SetCooperativeLevel(dispdata->layer,
                                                 DLSCL_ADMINISTRATIVE));
            SDL_DFB_CHECKERR(dispdata->layer->
                             SetCursorOpacity(dispdata->layer,
                                              cursor ? 0xC0 : 0x00));
            SDL_DFB_CHECKERR(dispdata->layer->
                             SetCooperativeLevel(dispdata->layer,
                                                 DLSCL_SHARED));
        }
    }

    return 0;
  error:
    return -1;
}

/* Free a window manager cursor */
static void
DirectFB_FreeCursor(SDL_Cursor * cursor)
{
    SDL_DFB_CURSORDATA(cursor);

    SDL_DFB_RELEASE(curdata->surf);
    SDL_DFB_FREE(cursor->driverdata);
    SDL_DFB_FREE(cursor);
}

/* Warp the mouse to (x,y) */
static void
DirectFB_WarpMouse(SDL_Window * window, int x, int y)
{
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
    DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
    DFBResult ret;
    int cx, cy;

    SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
    SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
                                                 cx + x + windata->client.x,
                                                 cy + y + windata->client.y));

  error:
    return;
}

#if USE_MULTI_API

static void DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window,
                               int x, int y);

static int id_mask;

static DFBEnumerationResult
EnumMice(DFBInputDeviceID device_id, DFBInputDeviceDescription desc,
         void *callbackdata)
{
    DFB_DeviceData *devdata = callbackdata;

    if ((desc.type & DIDTF_MOUSE) && (device_id & id_mask)) {
        SDL_Mouse mouse;

        SDL_zero(mouse);
        mouse.id = device_id;
        mouse.CreateCursor = DirectFB_CreateCursor;
        mouse.ShowCursor = DirectFB_ShowCursor;
        mouse.MoveCursor = DirectFB_MoveCursor;
        mouse.FreeCursor = DirectFB_FreeCursor;
        mouse.WarpMouse = DirectFB_WarpMouse;
        mouse.FreeMouse = DirectFB_FreeMouse;
        mouse.cursor_shown = 1;

        SDL_AddMouse(&mouse, desc.name, 0, 0, 1);
        devdata->mouse_id[devdata->num_mice++] = device_id;
    }
    return DFENUM_OK;
}

void
DirectFB_InitMouse(_THIS)
{
    SDL_DFB_DEVICEDATA(_this);

    devdata->num_mice = 0;
    if (devdata->use_linux_input) {
        /* try non-core devices first */
        id_mask = 0xF0;
        devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
        if (devdata->num_mice == 0) {
            /* try core devices */
            id_mask = 0x0F;
            devdata->dfb->EnumInputDevices(devdata->dfb, EnumMice, devdata);
        }
    }
    if (devdata->num_mice == 0) {
        SDL_Mouse mouse;

        SDL_zero(mouse);
        mouse.CreateCursor = DirectFB_CreateCursor;
        mouse.ShowCursor = DirectFB_ShowCursor;
        mouse.MoveCursor = DirectFB_MoveCursor;
        mouse.FreeCursor = DirectFB_FreeCursor;
        mouse.WarpMouse = DirectFB_WarpMouse;
        mouse.FreeMouse = DirectFB_FreeMouse;
        mouse.cursor_shown = 1;

        SDL_AddMouse(&mouse, "Mouse", 0, 0, 1);
        devdata->num_mice = 1;
    }
}

void
DirectFB_QuitMouse(_THIS)
{
    SDL_DFB_DEVICEDATA(_this);

    if (devdata->use_linux_input) {
        SDL_MouseQuit();
    } else {
        SDL_DelMouse(0);
    }
}


/* This is called when a mouse motion event occurs */
static void
DirectFB_MoveCursor(SDL_Cursor * cursor)
{

}

/* Warp the mouse to (x,y) */
static void
DirectFB_WarpMouse(SDL_Mouse * mouse, SDL_Window * window, int x, int y)
{
    SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
    DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
    DFB_WindowData *windata = (DFB_WindowData *) window->driverdata;
    DFBResult ret;
    int cx, cy;

    SDL_DFB_CHECKERR(windata->dfbwin->GetPosition(windata->dfbwin, &cx, &cy));
    SDL_DFB_CHECKERR(dispdata->layer->WarpCursor(dispdata->layer,
                                                 cx + x + windata->client.x,
                                                 cy + y + windata->client.y));

  error:
    return;
}

/* Free the mouse when it's time */
static void
DirectFB_FreeMouse(SDL_Mouse * mouse)
{
    /* nothing yet */
}

#else /* USE_MULTI_API */

void
DirectFB_InitMouse(_THIS)
{
    SDL_DFB_DEVICEDATA(_this);

    SDL_Mouse *mouse = SDL_GetMouse();

    mouse->CreateCursor = DirectFB_CreateCursor;
    mouse->ShowCursor = DirectFB_ShowCursor;
    mouse->WarpMouse = DirectFB_WarpMouse;
    mouse->FreeCursor = DirectFB_FreeCursor;

    SDL_SetDefaultCursor(DirectFB_CreateDefaultCursor());

    devdata->num_mice = 1;
}

void
DirectFB_QuitMouse(_THIS)
{
}


#endif

#endif /* SDL_VIDEO_DRIVER_DIRECTFB */

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