/*
  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 Thomas Perl <thomas.perl@jollamobile.com> */

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

#ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH

#include "SDL_log.h"
#include "SDL_waylandtouch.h"
#include "../../events/SDL_touch_c.h"

struct SDL_WaylandTouch {
    struct qt_touch_extension *touch_extension;
};


/**
 * Qt TouchPointState
 * adapted from qtbase/src/corelib/global/qnamespace.h
 **/
enum QtWaylandTouchPointState {
    QtWaylandTouchPointPressed    = 0x01,
    QtWaylandTouchPointMoved      = 0x02,
    /*
    Never sent by the server:
    QtWaylandTouchPointStationary = 0x04,
    */
    QtWaylandTouchPointReleased   = 0x08,
};

static void
touch_handle_touch(void *data,
        struct qt_touch_extension *qt_touch_extension,
        uint32_t time,
        uint32_t id,
        uint32_t state,
        int32_t x,
        int32_t y,
        int32_t normalized_x,
        int32_t normalized_y,
        int32_t width,
        int32_t height,
        uint32_t pressure,
        int32_t velocity_x,
        int32_t velocity_y,
        uint32_t flags,
        struct wl_array *rawdata)
{
    /**
     * Event is assembled in QtWayland in TouchExtensionGlobal::postTouchEvent
     * (src/compositor/wayland_wrapper/qwltouch.cpp)
     **/

    float FIXED_TO_FLOAT = 1. / 10000.;
    float xf = FIXED_TO_FLOAT * x;
    float yf = FIXED_TO_FLOAT * y;

    float PRESSURE_TO_FLOAT = 1. / 255.;
    float pressuref = PRESSURE_TO_FLOAT * pressure;

    uint32_t touchState = state & 0xFFFF;
    /*
    Other fields that are sent by the server (qwltouch.cpp),
    but not used at the moment can be decoded in this way:

    uint32_t sentPointCount = state >> 16;
    uint32_t touchFlags = flags & 0xFFFF;
    uint32_t capabilities = flags >> 16;
    */

    SDL_TouchID deviceId = 1;
	if (SDL_AddTouch(deviceId, "qt_touch_extension") < 0) {
		 SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
	}

    switch (touchState) {
        case QtWaylandTouchPointPressed:
        case QtWaylandTouchPointReleased:
            SDL_SendTouch(deviceId, (SDL_FingerID)id,
                    (touchState == QtWaylandTouchPointPressed) ? SDL_TRUE : SDL_FALSE,
                    xf, yf, pressuref);
            break;
        case QtWaylandTouchPointMoved:
            SDL_SendTouchMotion(deviceId, (SDL_FingerID)id, xf, yf, pressuref);
            break;
        default:
            /* Should not happen */
            break;
    }
}

static void
touch_handle_configure(void *data,
        struct qt_touch_extension *qt_touch_extension,
        uint32_t flags)
{
}


/* wayland-qt-touch-extension.c BEGINS */

static const struct qt_touch_extension_listener touch_listener = {
    touch_handle_touch,
    touch_handle_configure,
};

static const struct wl_interface *qt_touch_extension_types[] = {
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

static const struct wl_message qt_touch_extension_requests[] = {
    { "dummy", "", qt_touch_extension_types + 0 },
};

static const struct wl_message qt_touch_extension_events[] = {
    { "touch", "uuuiiiiiiuiiua", qt_touch_extension_types + 0 },
    { "configure", "u", qt_touch_extension_types + 0 },
};

WL_EXPORT const struct wl_interface qt_touch_extension_interface = {
    "qt_touch_extension", 1,
    1, qt_touch_extension_requests,
    2, qt_touch_extension_events,
};

/* wayland-qt-touch-extension.c ENDS */

/* wayland-qt-windowmanager.c BEGINS */
static const struct wl_interface *qt_windowmanager_types[] = {
    NULL,
    NULL,
};

static const struct wl_message qt_windowmanager_requests[] = {
    { "open_url", "us", qt_windowmanager_types + 0 },
};

static const struct wl_message qt_windowmanager_events[] = {
    { "hints", "i", qt_windowmanager_types + 0 },
    { "quit", "", qt_windowmanager_types + 0 },
};

WL_EXPORT const struct wl_interface qt_windowmanager_interface = {
    "qt_windowmanager", 1,
    1, qt_windowmanager_requests,
    2, qt_windowmanager_events,
};
/* wayland-qt-windowmanager.c ENDS */

/* wayland-qt-surface-extension.c BEGINS */
extern const struct wl_interface qt_extended_surface_interface;
#ifndef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
extern const struct wl_interface wl_surface_interface;
#endif

static const struct wl_interface *qt_surface_extension_types[] = {
    NULL,
    NULL,
    &qt_extended_surface_interface,
#ifdef SDL_VIDEO_DRIVER_WAYLAND_DYNAMIC
    /* FIXME: Set this dynamically to (*WAYLAND_wl_surface_interface) ? 
     * The value comes from auto generated code and does 
     * not appear to actually be used anywhere
     */
    NULL, 
#else
    &wl_surface_interface,
#endif    
};

static const struct wl_message qt_surface_extension_requests[] = {
    { "get_extended_surface", "no", qt_surface_extension_types + 2 },
};

WL_EXPORT const struct wl_interface qt_surface_extension_interface = {
    "qt_surface_extension", 1,
    1, qt_surface_extension_requests,
    0, NULL,
};

static const struct wl_message qt_extended_surface_requests[] = {
    { "update_generic_property", "sa", qt_surface_extension_types + 0 },
    { "set_content_orientation", "i", qt_surface_extension_types + 0 },
    { "set_window_flags", "i", qt_surface_extension_types + 0 },
};

static const struct wl_message qt_extended_surface_events[] = {
    { "onscreen_visibility", "i", qt_surface_extension_types + 0 },
    { "set_generic_property", "sa", qt_surface_extension_types + 0 },
    { "close", "", qt_surface_extension_types + 0 },
};

WL_EXPORT const struct wl_interface qt_extended_surface_interface = {
    "qt_extended_surface", 1,
    3, qt_extended_surface_requests,
    3, qt_extended_surface_events,
};

/* wayland-qt-surface-extension.c ENDS */

void
Wayland_touch_create(SDL_VideoData *data, uint32_t id)
{
    struct SDL_WaylandTouch *touch;

    if (data->touch) {
        Wayland_touch_destroy(data);
    }

    /* !!! FIXME: check for failure, call SDL_OutOfMemory() */
    data->touch = SDL_malloc(sizeof(struct SDL_WaylandTouch));

    touch = data->touch;
    touch->touch_extension = wl_registry_bind(data->registry, id, &qt_touch_extension_interface, 1);
    qt_touch_extension_add_listener(touch->touch_extension, &touch_listener, data);
}

void
Wayland_touch_destroy(SDL_VideoData *data)
{
    if (data->touch) {
        struct SDL_WaylandTouch *touch = data->touch;
        if (touch->touch_extension) {
            qt_touch_extension_destroy(touch->touch_extension);
        }

        SDL_free(data->touch);
        data->touch = NULL;
    }
}

#endif /* SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH */
