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

/* General touch handling code for SDL */

#include "SDL_assert.h"
#include "SDL_events.h"
#include "SDL_events_c.h"
#include "../video/SDL_sysvideo.h"


static int SDL_num_touch = 0;
static SDL_Touch **SDL_touchDevices = NULL;

/* for mapping touch events to mice */
static SDL_bool finger_touching = SDL_FALSE;
static SDL_FingerID track_fingerid;
static SDL_TouchID  track_touchid;

/* Public functions */
int
SDL_TouchInit(void)
{
    return (0);
}

int
SDL_GetNumTouchDevices(void)
{
    return SDL_num_touch;
}

SDL_TouchID
SDL_GetTouchDevice(int index)
{
    if (index < 0 || index >= SDL_num_touch) {
        SDL_SetError("Unknown touch device index %d", index);
        return 0;
    }
    return SDL_touchDevices[index]->id;
}

static int
SDL_GetTouchIndex(SDL_TouchID id)
{
    int index;
    SDL_Touch *touch;

    for (index = 0; index < SDL_num_touch; ++index) {
        touch = SDL_touchDevices[index];
        if (touch->id == id) {
            return index;
        }
    }
    return -1;
}

SDL_Touch *
SDL_GetTouch(SDL_TouchID id)
{
    int index = SDL_GetTouchIndex(id);
    if (index < 0 || index >= SDL_num_touch) {
        if (SDL_GetVideoDevice()->ResetTouch != NULL) {
            SDL_SetError("Unknown touch id %d, resetting", (int) id);
            (SDL_GetVideoDevice()->ResetTouch)(SDL_GetVideoDevice());
        } else {
            SDL_SetError("Unknown touch device id %d, cannot reset", (int) id);
        }
        return NULL;
    }
    return SDL_touchDevices[index];
}

SDL_TouchDeviceType
SDL_GetTouchDeviceType(SDL_TouchID id)
{
    SDL_Touch *touch = SDL_GetTouch(id);
    if (touch) {
        return touch->type;
    }
    return SDL_TOUCH_DEVICE_INVALID;
}

static int
SDL_GetFingerIndex(const SDL_Touch * touch, SDL_FingerID fingerid)
{
    int index;
    for (index = 0; index < touch->num_fingers; ++index) {
        if (touch->fingers[index]->id == fingerid) {
            return index;
        }
    }
    return -1;
}

static SDL_Finger *
SDL_GetFinger(const SDL_Touch * touch, SDL_FingerID id)
{
    int index = SDL_GetFingerIndex(touch, id);
    if (index < 0 || index >= touch->num_fingers) {
        return NULL;
    }
    return touch->fingers[index];
}

int
SDL_GetNumTouchFingers(SDL_TouchID touchID)
{
    SDL_Touch *touch = SDL_GetTouch(touchID);
    if (touch) {
        return touch->num_fingers;
    }
    return 0;
}

SDL_Finger *
SDL_GetTouchFinger(SDL_TouchID touchID, int index)
{
    SDL_Touch *touch = SDL_GetTouch(touchID);
    if (!touch) {
        return NULL;
    }
    if (index < 0 || index >= touch->num_fingers) {
        SDL_SetError("Unknown touch finger");
        return NULL;
    }
    return touch->fingers[index];
}

int
SDL_AddTouch(SDL_TouchID touchID, SDL_TouchDeviceType type, const char *name)
{
    SDL_Touch **touchDevices;
    int index;

    index = SDL_GetTouchIndex(touchID);
    if (index >= 0) {
        return index;
    }

    /* Add the touch to the list of touch */
    touchDevices = (SDL_Touch **) SDL_realloc(SDL_touchDevices,
                                      (SDL_num_touch + 1) * sizeof(*touchDevices));
    if (!touchDevices) {
        return SDL_OutOfMemory();
    }

    SDL_touchDevices = touchDevices;
    index = SDL_num_touch;

    SDL_touchDevices[index] = (SDL_Touch *) SDL_malloc(sizeof(*SDL_touchDevices[index]));
    if (!SDL_touchDevices[index]) {
        return SDL_OutOfMemory();
    }

    /* Added touch to list */
    ++SDL_num_touch;

    /* we're setting the touch properties */
    SDL_touchDevices[index]->id = touchID;
    SDL_touchDevices[index]->type = type;
    SDL_touchDevices[index]->num_fingers = 0;
    SDL_touchDevices[index]->max_fingers = 0;
    SDL_touchDevices[index]->fingers = NULL;

    /* Record this touch device for gestures */
    /* We could do this on the fly in the gesture code if we wanted */
    SDL_GestureAddTouch(touchID);

    return index;
}

static int
SDL_AddFinger(SDL_Touch *touch, SDL_FingerID fingerid, float x, float y, float pressure)
{
    SDL_Finger *finger;

    if (touch->num_fingers == touch->max_fingers) {
        SDL_Finger **new_fingers;
        new_fingers = (SDL_Finger **)SDL_realloc(touch->fingers, (touch->max_fingers+1)*sizeof(*touch->fingers));
        if (!new_fingers) {
            return SDL_OutOfMemory();
        }
        touch->fingers = new_fingers;
        touch->fingers[touch->max_fingers] = (SDL_Finger *)SDL_malloc(sizeof(*finger));
        if (!touch->fingers[touch->max_fingers]) {
            return SDL_OutOfMemory();
        }
        touch->max_fingers++;
    }

    finger = touch->fingers[touch->num_fingers++];
    finger->id = fingerid;
    finger->x = x;
    finger->y = y;
    finger->pressure = pressure;
    return 0;
}

static int
SDL_DelFinger(SDL_Touch* touch, SDL_FingerID fingerid)
{
    SDL_Finger *temp;

    int index = SDL_GetFingerIndex(touch, fingerid);
    if (index < 0) {
        return -1;
    }

    touch->num_fingers--;
    temp = touch->fingers[index];
    touch->fingers[index] = touch->fingers[touch->num_fingers];
    touch->fingers[touch->num_fingers] = temp;
    return 0;
}

int
SDL_SendTouch(SDL_TouchID id, SDL_FingerID fingerid,
              SDL_bool down, float x, float y, float pressure)
{
    int posted;
    SDL_Finger *finger;

    SDL_Touch* touch = SDL_GetTouch(id);
    if (!touch) {
        return -1;
    }

    /* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */
    {
        SDL_Mouse *mouse = SDL_GetMouse();
        if (mouse->touch_mouse_events) {
            /* FIXME: maybe we should only restrict to a few SDL_TouchDeviceType */
            if (id != SDL_MOUSE_TOUCHID) {
                SDL_Window *window = SDL_GetMouseFocus();
                if (window) {
                    if (down) {
                        if (finger_touching == SDL_FALSE) {
                            int pos_x = (int)(x * (float)window->w);
                            int pos_y = (int)(y * (float)window->h);
                            if (pos_x < 0) pos_x = 0;
                            if (pos_x > window->w - 1) pos_x = window->w - 1;
                            if (pos_y < 0) pos_y = 0;
                            if (pos_y > window->h - 1) pos_y = window->h - 1;
                            SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
                            SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, SDL_BUTTON_LEFT);
                        }
                    } else {
                        if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
                            SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, SDL_BUTTON_LEFT);
                        }
                    }
                }
                if (down) {
                    if (finger_touching == SDL_FALSE) {
                        finger_touching = SDL_TRUE;
                        track_touchid = id;
                        track_fingerid = fingerid;
                    }
                } else {
                    if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
                        finger_touching = SDL_FALSE;
                    }
                }
            }
        }
    }

    finger = SDL_GetFinger(touch, fingerid);
    if (down) {
        if (finger) {
            /* This finger is already down */
            return 0;
        }

        if (SDL_AddFinger(touch, fingerid, x, y, pressure) < 0) {
            return 0;
        }

        posted = 0;
        if (SDL_GetEventState(SDL_FINGERDOWN) == SDL_ENABLE) {
            SDL_Event event;
            event.tfinger.type = SDL_FINGERDOWN;
            event.tfinger.touchId = id;
            event.tfinger.fingerId = fingerid;
            event.tfinger.x = x;
            event.tfinger.y = y;
            event.tfinger.dx = 0;
            event.tfinger.dy = 0;
            event.tfinger.pressure = pressure;
            posted = (SDL_PushEvent(&event) > 0);
        }
    } else {
        if (!finger) {
            /* This finger is already up */
            return 0;
        }

        posted = 0;
        if (SDL_GetEventState(SDL_FINGERUP) == SDL_ENABLE) {
            SDL_Event event;
            event.tfinger.type = SDL_FINGERUP;
            event.tfinger.touchId =  id;
            event.tfinger.fingerId = fingerid;
            /* I don't trust the coordinates passed on fingerUp */
            event.tfinger.x = finger->x;
            event.tfinger.y = finger->y;
            event.tfinger.dx = 0;
            event.tfinger.dy = 0;
            event.tfinger.pressure = pressure;
            posted = (SDL_PushEvent(&event) > 0);
        }

        SDL_DelFinger(touch, fingerid);
    }
    return posted;
}

int
SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid,
                    float x, float y, float pressure)
{
    SDL_Touch *touch;
    SDL_Finger *finger;
    int posted;
    float xrel, yrel, prel;

    touch = SDL_GetTouch(id);
    if (!touch) {
        return -1;
    }

    /* SDL_HINT_TOUCH_MOUSE_EVENTS: controlling whether touch events should generate synthetic mouse events */
    {
        SDL_Mouse *mouse = SDL_GetMouse();
        if (mouse->touch_mouse_events) {
            if (id != SDL_MOUSE_TOUCHID) {
                SDL_Window *window = SDL_GetMouseFocus();
                if (window) {
                    if (finger_touching == SDL_TRUE && track_touchid == id && track_fingerid == fingerid) {
                        int pos_x = (int)(x * (float)window->w);
                        int pos_y = (int)(y * (float)window->h);
                        if (pos_x < 0) pos_x = 0;
                        if (pos_x > window->w - 1) pos_x = window->w - 1;
                        if (pos_y < 0) pos_y = 0;
                        if (pos_y > window->h - 1) pos_y = window->h - 1;
                        SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, pos_x, pos_y);
                    }
                }
            }
        }
    }

    finger = SDL_GetFinger(touch,fingerid);
    if (!finger) {
        return SDL_SendTouch(id, fingerid, SDL_TRUE, x, y, pressure);
    }

    xrel = x - finger->x;
    yrel = y - finger->y;
    prel = pressure - finger->pressure;

    /* Drop events that don't change state */
    if (xrel == 0.0f && yrel == 0.0f && prel == 0.0f) {
#if 0
        printf("Touch event didn't change state - dropped!\n");
#endif
        return 0;
    }

    /* Update internal touch coordinates */
    finger->x = x;
    finger->y = y;
    finger->pressure = pressure;

    /* Post the event, if desired */
    posted = 0;
    if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
        SDL_Event event;
        event.tfinger.type = SDL_FINGERMOTION;
        event.tfinger.touchId = id;
        event.tfinger.fingerId = fingerid;
        event.tfinger.x = x;
        event.tfinger.y = y;
        event.tfinger.dx = xrel;
        event.tfinger.dy = yrel;
        event.tfinger.pressure = pressure;
        posted = (SDL_PushEvent(&event) > 0);
    }
    return posted;
}

void
SDL_DelTouch(SDL_TouchID id)
{
    int i;
    int index = SDL_GetTouchIndex(id);
    SDL_Touch *touch = SDL_GetTouch(id);

    if (!touch) {
        return;
    }

    for (i = 0; i < touch->max_fingers; ++i) {
        SDL_free(touch->fingers[i]);
    }
    SDL_free(touch->fingers);
    SDL_free(touch);

    SDL_num_touch--;
    SDL_touchDevices[index] = SDL_touchDevices[SDL_num_touch];

    /* Delete this touch device for gestures */
    SDL_GestureDelTouch(id);
}

void
SDL_TouchQuit(void)
{
    int i;

    for (i = SDL_num_touch; i--; ) {
        SDL_DelTouch(SDL_touchDevices[i]->id);
    }
    SDL_assert(SDL_num_touch == 0);

    SDL_free(SDL_touchDevices);
    SDL_touchDevices = NULL;
    SDL_GestureQuit();
}

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