/*
 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gesture.h"

#include <time.h>

#include <gestures/gestures.h>
#include <xorg/xf86_OSproc.h>

#include "cmt.h"
#include "properties.h"

/*
 * Gestures timer functions
 */
static GesturesTimer* Gesture_TimerCreate(void*);
static void Gesture_TimerSet(void*,
                             GesturesTimer*,
                             stime_t,
                             GesturesTimerCallback,
                             void*);
static void Gesture_TimerCancel(void*, GesturesTimer*);
static void Gesture_TimerFree(void*, GesturesTimer*);

static CARD32 Gesture_TimerCallback(OsTimerPtr, CARD32, pointer);

struct GesturesTimer {
    OsTimerPtr timer;
    GesturesTimerCallback callback;
    void* callback_data;
    int is_monotonic:1;
};

static GesturesTimerProvider Gesture_GesturesTimerProvider = {
    .create_fn = Gesture_TimerCreate,
    .set_fn = Gesture_TimerSet,
    .cancel_fn = Gesture_TimerCancel,
    .free_fn = Gesture_TimerFree
};

/*
 * Callback for Gestures library.
 */
static void Gesture_Gesture_Ready(void* client_data,
                                  const struct Gesture* gesture);

static enum GestureInterpreterDeviceClass Gesture_Device_Class(EvdevClass cls);

int
Gesture_Init(GesturePtr rec, size_t max_fingers)
{
    rec->interpreter = NewGestureInterpreter();
    rec->slot_states = NULL;

    if (!rec->interpreter)
        return !Success;
    rec->fingers = malloc(max_fingers * sizeof(struct FingerState));
    if (!rec->fingers)
        goto Error_Alloc_Fingers;
    rec->mask = valuator_mask_new(MAX_VALUATORS);
    if (!rec->mask)
        goto Error_Alloc_Mask;
    return Success;

Error_Alloc_Mask:
    free(rec->fingers);
    rec->fingers = NULL;
Error_Alloc_Fingers:
    DeleteGestureInterpreter(rec->interpreter);
    rec->interpreter = NULL;
    return BadAlloc;
}

void
Gesture_Free(GesturePtr rec)
{
    // free gesture interpreter first, this will cancel all timers.
    DeleteGestureInterpreter(rec->interpreter);
    rec->interpreter = NULL;
    rec->dev = NULL;

    valuator_mask_free(&rec->mask);

    if (rec->fingers) {
        free(rec->fingers);
        rec->fingers = NULL;
    }
    if(rec->slot_states) {
        free(rec->slot_states);
        rec->slot_states = NULL;
    }
}

void
Gesture_Device_Init(GesturePtr rec, DeviceIntPtr dev)
{
    InputInfoPtr info = dev->public.devicePrivate;
    CmtDevicePtr cmt = info->private;
    CmtPropertiesPtr props = &cmt->props;
    EventStatePtr evstate = &cmt->evstate;
    struct HardwareProperties hwprops;
    EvdevPtr evdev = &cmt->evdev;
    int i;

    /* Store the device for which to generate gestures */
    rec->dev = dev;

    /* TODO: support different models */
    hwprops.left            = props->area_left;
    hwprops.top             = props->area_top;
    hwprops.right           = props->area_right;
    hwprops.bottom          = props->area_bottom;
    hwprops.res_x           = props->res_x;
    hwprops.res_y           = props->res_y;
    hwprops.screen_x_dpi    = 133;
    hwprops.screen_y_dpi    = 133;
    hwprops.orientation_minimum = props->orientation_minimum;
    hwprops.orientation_maximum = props->orientation_maximum;
    hwprops.max_finger_cnt  = evstate->slot_count;
    hwprops.max_touch_cnt   = Event_Get_Touch_Count_Max(evdev);
    hwprops.supports_t5r2   = Event_Get_T5R2(evdev);
    hwprops.support_semi_mt = Event_Get_Semi_MT(evdev);
    /* buttonpad means a physical button under the touch surface */
    hwprops.is_button_pad   = Event_Get_Button_Pad(evdev);

    GestureInterpreterSetPropProvider(rec->interpreter, &prop_provider,
                                      rec->dev);
    GestureInterpreterInitialize(
            rec->interpreter,
            Gesture_Device_Class(cmt->evdev.info.evdev_class));
    GestureInterpreterSetHardwareProperties(rec->interpreter, &hwprops);

    rec->slot_states = malloc(sizeof(int) * evstate->slot_count);
    if (!rec->slot_states) {
        ERR(info, "BadAlloc: rec->slot_states");
        return;
    }
    for (i = 0; i < evstate->slot_count; ++i)
        rec->slot_states[i] = SLOT_STATUS_FREE;
}

void
Gesture_Device_On(GesturePtr rec)
{
    GestureInterpreterSetTimerProvider(rec->interpreter,
                                       &Gesture_GesturesTimerProvider,
                                       rec->dev);
    GestureInterpreterSetCallback(rec->interpreter, &Gesture_Gesture_Ready,
                                  rec);
}

void
Gesture_Device_Off(GesturePtr rec)
{
    GestureInterpreterSetCallback(rec->interpreter, NULL, NULL);
}

void
Gesture_Device_Close(GesturePtr rec)
{
    GestureInterpreterSetPropProvider(rec->interpreter, NULL, NULL);
    GestureInterpreterSetTimerProvider(rec->interpreter, NULL, NULL);
}

void
Gesture_Process_Slots(void* vrec,
                      EventStatePtr evstate,
                      struct timeval* tv)
{
    GesturePtr rec = vrec;
    DeviceIntPtr dev = rec->dev;
    InputInfoPtr info = dev->public.devicePrivate;
    CmtDevicePtr cmt = info->private;
    EvdevPtr evdev = &cmt->evdev;
    ValuatorMask* mask = rec->mask;
    int i;
    MtSlotPtr slot;
    struct HardwareState hwstate = { 0 };
    int current_finger;
    bool has_gesture_fingers = false;

    if (!rec->interpreter || ! rec->slot_states)
        return;

    /* zero initialize all FingerStates to clear out previous state. */
    memset(rec->fingers, 0,
           Event_Get_Slot_Count(evdev) * sizeof(struct FingerState));

    /* clear out previous state from valuator */
    valuator_mask_zero(mask);

    if (cmt->props.raw_passthrough) {
        for (i = 0; i < evstate->slot_count; i++) {
            slot = &evstate->slots[i];

            /* send TouchEnd for lifted fingers */
            if (slot->tracking_id == -1) {
                if (rec->slot_states[i] == SLOT_STATUS_RAW) {
                    xf86PostTouchEvent(dev, i, XI_TouchEnd, 0, mask);
                }
                rec->slot_states[i] = SLOT_STATUS_FREE;
                continue;
            }

            /*
             * valuators 0 (CMT_AXIS_X) and 1 (CMT_AXIS_Y) are hardcoded into
             * X.org as finger position, so we need to set those too.
             */
            valuator_mask_set_double(mask, CMT_AXIS_MT_POSITION_X,
                                     slot->position_x);
            valuator_mask_set_double(mask, CMT_AXIS_MT_POSITION_Y,
                                     slot->position_y);
            valuator_mask_set_double(mask, CMT_AXIS_MT_PRESSURE,
                                     slot->pressure);
            valuator_mask_set_double(mask, CMT_AXIS_MT_TOUCH_MAJOR,
                                     slot->touch_major);
            valuator_mask_set_double(mask, CMT_AXIS_TOUCH_TIMESTAMP,
                                     StimeFromTimeval(tv));
            valuator_mask_set_double(mask, CMT_AXIS_X, slot->position_x);
            valuator_mask_set_double(mask, CMT_AXIS_Y, slot->position_y);

            if (rec->slot_states[i] == SLOT_STATUS_RAW) {
                xf86PostTouchEvent(dev, i, XI_TouchUpdate, 0, mask);
            } else {
                /* take over STATUS_GESTURE slots too */
                if (rec->slot_states[i] == SLOT_STATUS_GESTURE)
                    has_gesture_fingers = true;
                xf86PostTouchEvent(dev, i, XI_TouchBegin, 0, mask);

            }
            rec->slot_states[i] = SLOT_STATUS_RAW;
        }

        if (has_gesture_fingers) {
            /* push empty hardware state to clear interpreter state */
            hwstate.timestamp = StimeFromTimeval(tv);
            GestureInterpreterPushHardwareState(rec->interpreter, &hwstate);
        }
        return;
    }

    current_finger = 0;
    for (i = 0; i < evstate->slot_count; i++) {
        slot = &evstate->slots[i];
        if (slot->tracking_id == -1) {
            rec->slot_states[i] = SLOT_STATUS_FREE;
            continue;
        }

        if (rec->slot_states[i] == SLOT_STATUS_FREE) {
            rec->slot_states[i] = SLOT_STATUS_GESTURE;
        } else if (rec->slot_states[i] == SLOT_STATUS_RAW) {
            /* ignore any fingers that are still present from raw mode */
            continue;
        }

        rec->fingers[current_finger].touch_major = (float)slot->touch_major;
        rec->fingers[current_finger].touch_minor = (float)slot->touch_minor;
        rec->fingers[current_finger].width_major = (float)slot->width_major;
        rec->fingers[current_finger].width_minor = (float)slot->width_minor;
        rec->fingers[current_finger].pressure    = (float)slot->pressure;
        rec->fingers[current_finger].orientation = (float)slot->orientation;
        rec->fingers[current_finger].position_x  = (float)slot->position_x;
        rec->fingers[current_finger].position_y  = (float)slot->position_y;
        rec->fingers[current_finger].tracking_id = slot->tracking_id;
        current_finger++;
    }
    hwstate.timestamp = StimeFromTimeval(tv);
    if (Event_Get_Button_Left(evdev))
        hwstate.buttons_down |= GESTURES_BUTTON_LEFT;
    if (Event_Get_Button_Middle(evdev))
        hwstate.buttons_down |= GESTURES_BUTTON_MIDDLE;
    if (Event_Get_Button_Right(evdev))
        hwstate.buttons_down |= GESTURES_BUTTON_RIGHT;
    hwstate.touch_cnt = Event_Get_Touch_Count(evdev);
    hwstate.finger_cnt = current_finger;
    hwstate.fingers = rec->fingers;
    hwstate.rel_x = evstate->rel_x;
    hwstate.rel_y = evstate->rel_y;
    hwstate.rel_wheel = evstate->rel_wheel;
    hwstate.rel_hwheel = evstate->rel_hwheel;
    GestureInterpreterPushHardwareState(rec->interpreter, &hwstate);
}

static void SetTimeValues(ValuatorMask* mask,
                          const struct Gesture* gesture,
                          DeviceIntPtr dev,
                          BOOL is_absolute)
{
    double start_time = gesture->start_time;
    double end_time = gesture->end_time;

    if (!is_absolute) {
        /*
         * We send the movement axes as relative values, which causes the
         * times to be sent as relative values too. This code computes the
         * right relative values.
         */
        start_time -= dev->last.valuators[CMT_AXIS_DBL_START_TIME];
        end_time -= dev->last.valuators[CMT_AXIS_DBL_END_TIME];
    }

    valuator_mask_set_double(mask, CMT_AXIS_DBL_START_TIME, start_time);
    valuator_mask_set_double(mask, CMT_AXIS_DBL_END_TIME, end_time);
}

static void SetOrdinalValues(ValuatorMask* mask,
                             DeviceIntPtr dev,
                             float x,
                             float y,
                             BOOL is_absolute) {
    if (!is_absolute) {
        /*
         * We send the movement axes as relative values, which causes the
         * times to be sent as relative values too. This code computes the
         * right relative values.
         */
        x -= dev->last.valuators[CMT_AXIS_ORDINAL_X];
        y -= dev->last.valuators[CMT_AXIS_ORDINAL_Y];
    }

    valuator_mask_set_double(mask, CMT_AXIS_ORDINAL_X, x);
    valuator_mask_set_double(mask, CMT_AXIS_ORDINAL_Y, y);
}

static void Gesture_Gesture_Ready(void* client_data,
                                  const struct Gesture* gesture)
{
    GesturePtr rec = client_data;
    DeviceIntPtr dev = rec->dev;
    ValuatorMask* mask = rec->mask;
    InputInfoPtr info = dev->public.devicePrivate;
    CmtDevicePtr cmt = info->private;

    if (cmt->props.raw_passthrough) {
        DBG(info, "Gesture Suppressed");
        return;
    }

    DBG(info, "Gesture Start: %f End: %f \n",
        gesture->start_time, gesture->end_time);

    valuator_mask_zero(mask);
    switch (gesture->type) {
        case kGestureTypeContactInitiated:
            /* TODO(adlr): handle contact initiated */
            break;
        case kGestureTypeMove: {
            const GestureMove* move = &gesture->details.move;
            DBG(info, "Gesture Move: (%f, %f) [%f, %f]\n",
                move->dx, move->dy, move->ordinal_dx, move->ordinal_dy);
            valuator_mask_set_double(mask, CMT_AXIS_X, move->dx);
            valuator_mask_set_double(mask, CMT_AXIS_Y, move->dy);
            SetTimeValues(mask, gesture, dev, FALSE);
            SetOrdinalValues(mask,
                             dev,
                             move->ordinal_dx,
                             move->ordinal_dy,
                             FALSE);
            xf86PostMotionEventM(dev, FALSE, mask);
            break;
        }
        case kGestureTypeScroll: {
            const GestureScroll* scroll = &gesture->details.scroll;
            DBG(info, "Gesture Scroll: (%f, %f) [%f, %f]\n",
                scroll->dx, scroll->dy, scroll->ordinal_dx, scroll->ordinal_dy);
            valuator_mask_set_double(mask, CMT_AXIS_SCROLL_X, scroll->dx);
            valuator_mask_set_double(mask, CMT_AXIS_SCROLL_Y, scroll->dy);
            valuator_mask_set_double(mask, CMT_AXIS_FINGER_COUNT, 2.0);
            SetTimeValues(mask, gesture, dev, TRUE);
            SetOrdinalValues(mask,
                             dev,
                             scroll->ordinal_dx,
                             scroll->ordinal_dy,
                             TRUE);
            xf86PostMotionEventM(dev, TRUE, mask);
            break;
        }
        case kGestureTypeButtonsChange: {
            const GestureButtonsChange* buttons = &gesture->details.buttons;
            DBG(info, "Gesture Button Change: down=0x%02x up=0x%02x\n",
                buttons->down, buttons->up);
            SetTimeValues(mask, gesture, dev, TRUE);
            if (buttons->down & GESTURES_BUTTON_LEFT)
                xf86PostButtonEventM(dev, TRUE, CMT_BTN_LEFT, 1, mask);
            if (buttons->down & GESTURES_BUTTON_MIDDLE)
                xf86PostButtonEventM(dev, TRUE, CMT_BTN_MIDDLE, 1, mask);
            if (buttons->down & GESTURES_BUTTON_RIGHT)
                xf86PostButtonEventM(dev, TRUE, CMT_BTN_RIGHT, 1, mask);
            if (buttons->up & GESTURES_BUTTON_LEFT)
                xf86PostButtonEventM(dev, TRUE, CMT_BTN_LEFT, 0, mask);
            if (buttons->up & GESTURES_BUTTON_MIDDLE)
                xf86PostButtonEventM(dev, TRUE, CMT_BTN_MIDDLE, 0, mask);
            if (buttons->up & GESTURES_BUTTON_RIGHT)
                xf86PostButtonEventM(dev, TRUE, CMT_BTN_RIGHT, 0, mask);
            break;
        }
        case kGestureTypeFling: {
            const GestureFling* fling = &gesture->details.fling;
            DBG(info, "Gesture Fling: (%f, %f) [%f, %f] fling_state=%d\n",
                fling->vx, fling->vy, fling->ordinal_vx, fling->ordinal_vy,
                fling->fling_state);
            valuator_mask_set_double(mask, CMT_AXIS_DBL_FLING_VX, fling->vx);
            valuator_mask_set_double(mask, CMT_AXIS_DBL_FLING_VY, fling->vy);
            valuator_mask_set(mask, CMT_AXIS_FLING_STATE, fling->fling_state);
            SetTimeValues(mask, gesture, dev, TRUE);
            SetOrdinalValues(mask,
                             dev,
                             fling->ordinal_vx,
                             fling->ordinal_vy,
                             TRUE);
            xf86PostMotionEventM(dev, TRUE, mask);
            break;
        }
        case kGestureTypeSwipe: {
            const GestureSwipe* swipe = &gesture->details.swipe;
            DBG(info, "Gesture Swipe: (%f, %f) [%f, %f]\n",
                swipe->dx, swipe->dy, swipe->ordinal_dx, swipe->ordinal_dy);
            valuator_mask_set_double(mask, CMT_AXIS_SCROLL_X, swipe->dx);
            valuator_mask_set_double(mask, CMT_AXIS_SCROLL_Y, swipe->dy);
            valuator_mask_set_double(mask, CMT_AXIS_FINGER_COUNT, 3.0);
            SetTimeValues(mask, gesture, dev, TRUE);
            SetOrdinalValues(mask,
                             dev,
                             swipe->ordinal_dx,
                             swipe->ordinal_dy,
                             TRUE);
            xf86PostMotionEventM(dev, TRUE, mask);
            break;
        }
        case kGestureTypeSwipeLift:
            DBG(info, "Gesture Swipe Lift\n");
            // Turn a swipe lift into a fling start.
            SetTimeValues(mask, gesture, dev, TRUE);
            valuator_mask_set_double(mask, CMT_AXIS_DBL_FLING_VX, 0);
            valuator_mask_set_double(mask, CMT_AXIS_DBL_FLING_VY, 0);
            valuator_mask_set(mask, CMT_AXIS_FLING_STATE, 0);
            xf86PostMotionEventM(dev, TRUE, mask);
            break;
        case kGestureTypePinch: {
            const GesturePinch* pinch = &gesture->details.pinch;
            DBG(info, "Gesture Pinch: dz=%f [%f]\n",
                pinch->dz, pinch->ordinal_dz);
            break;
        }
        case kGestureTypeMetrics: {
            const GestureMetrics* metrics = &gesture->details.metrics;
            DBG(info, "Gesture Metrics: [%f, %f] type=%d\n",
                metrics->data[0], metrics->data[1], metrics->type);
            valuator_mask_set_double(mask, CMT_AXIS_METRICS_DATA1,
                metrics->data[0]);
            valuator_mask_set_double(mask, CMT_AXIS_METRICS_DATA2,
                metrics->data[1]);
            valuator_mask_set(mask, CMT_AXIS_METRICS_TYPE, metrics->type);
            SetTimeValues(mask, gesture, dev, TRUE);
            xf86PostMotionEventM(dev, TRUE, mask);
            break;
        }
        default:
            ERR(info, "Unrecognized gesture type (%u)\n", gesture->type);
            break;
    }
}

static GesturesTimer*
Gesture_TimerCreate(void* provider_data)
{
    DeviceIntPtr dev = provider_data;
    InputInfoPtr info = dev->public.devicePrivate;
    CmtDevicePtr cmt = info->private;
    GesturesTimer* timer = (GesturesTimer*)calloc(1, sizeof(GesturesTimer));
    if (!timer)
        return NULL;
    timer->timer = TimerSet(NULL, 0, 0, NULL, 0);
    if (!timer->timer) {
        free(timer);
        return NULL;
    }
    timer->is_monotonic = cmt->evdev.info.is_monotonic;
    return timer;
}

static void
Gesture_TimerSet(void* provider_data,
                 GesturesTimer* timer,
                 stime_t delay,
                 GesturesTimerCallback callback,
                 void* callback_data)
{
    CARD32 ms = delay * 1000.0;

    if (!timer)
        return;
    timer->callback = callback;
    timer->callback_data = callback_data;
    if (ms == 0)
        ms = 1;
    TimerSet(timer->timer, 0, ms, Gesture_TimerCallback, timer);
}

static void
Gesture_TimerCancel(void* provider_data, GesturesTimer* timer)
{
    TimerCancel(timer->timer);
}

static void
Gesture_TimerFree(void* provider_data, GesturesTimer* timer)
{
    TimerFree(timer->timer);
    timer->timer = NULL;
    free(timer);
}

static CARD32
Gesture_TimerCallback(OsTimerPtr timer,
                      CARD32 millis,
                      pointer callback_data)
{
    GesturesTimer* tm = callback_data;
    stime_t now;
    stime_t rc;
    CARD32 next_timeout = 0;

    if (tm->is_monotonic) {
      struct timespec ts;
      clock_gettime(CLOCK_MONOTONIC, &ts);
      now = StimeFromTimespec(&ts);
    } else {
      struct timeval tv;
      gettimeofday(&tv, NULL);
      now = StimeFromTimeval(&tv);
    }

    rc = tm->callback(now, tm->callback_data);
    if (rc >= 0.0) {
        next_timeout = rc * 1000.0;
        if (next_timeout == 0)
            next_timeout = 1;
    }

    return next_timeout;
}

static enum GestureInterpreterDeviceClass
Gesture_Device_Class(EvdevClass cls) {
  switch (cls) {
    case EvdevClassMouse:
      return GESTURES_DEVCLASS_MOUSE;
    case EvdevClassMultitouchMouse:
      return GESTURES_DEVCLASS_MULTITOUCH_MOUSE;
    case EvdevClassTouchpad:
      return GESTURES_DEVCLASS_TOUCHPAD;
    case EvdevClassTouchscreen:
      return GESTURES_DEVCLASS_TOUCHSCREEN;
    default:
      return GESTURES_DEVCLASS_UNKNOWN;
  }
}

_X_EXPORT void gestures_log(int verb, const char* fmt, ...) {
  va_list args;
  va_start(args, fmt);
  if (verb > 0)
    xf86VDrvMsgVerb(-1, X_INFO, 7, fmt, args);
  else
    xf86VDrvMsgVerb(-1, X_ERROR, 0, fmt, args);
  va_end(args);
}
