/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "qemu-common.h"
#include "user-events.h"
#include "android/display-core.h"
#include "android/hw-events.h"
#include "android/charmap.h"
#include "android/globals.h"  /* for android_hw */
#include "android/utils/misc.h"
#include "android/utils/debug.h"
#include "android/multitouch-screen.h"

#define  E(...)    derror(__VA_ARGS__)
#define  W(...)    dwarning(__VA_ARGS__)
#define  D(...)    VERBOSE_PRINT(mtscreen,__VA_ARGS__)
#define  D_ACTIVE  VERBOSE_CHECK(mtscreen)

#define TRACE_ON    1

#if TRACE_ON
#define  T(...)    VERBOSE_PRINT(mtscreen,__VA_ARGS__)
#else
#define  T(...)
#endif


/* Maximum number of pointers, supported by multi-touch emulation. */
#define MTS_POINTERS_NUM    10
/* Signals that pointer is not tracked (or is "up"). */
#define MTS_POINTER_UP      -1
/* Special tracking ID for a mouse pointer. */
#define MTS_POINTER_MOUSE   -2

/* Describes state of a multi-touch pointer  */
typedef struct MTSPointerState {
    /* Tracking ID assigned to the pointer by an app emulating multi-touch. */
    int tracking_id;
    /* X - coordinate of the tracked pointer. */
    int x;
    /* Y - coordinate of the tracked pointer. */
    int y;
    /* Current pressure value. */
    int pressure;
} MTSPointerState;

/* Describes state of an emulated multi-touch screen. */
typedef struct MTSState {
    /* Multi-touch port connected to the device. */
    AndroidMTSPort* mtsp;
    /* Emulator's display state. */
    DisplayState*   ds;
    /* Number of tracked pointers. */
    int             tracked_ptr_num;
    /* Index in the 'tracked_pointers' array of the last pointer for which
     * ABS_MT_SLOT was sent. -1 indicates that no slot selection has been made
     * yet. */
    int             current_slot;
    /* Accumulator for ABS_TOUCH_MAJOR value. */
    int             touch_major;
    /* Array of multi-touch pointers. */
    MTSPointerState tracked_pointers[MTS_POINTERS_NUM];
    /* Header collecting framebuffer information and updates. */
    MTFrameHeader   fb_header;
    /* Boolean value indicating if framebuffer updates are currently being
     * transferred to the application running on the device. */
    int             fb_transfer_in_progress;
    /* Indicates direction in which lines are arranged in the framebuffer. If
     * this value is negative, lines are arranged in bottom-up format (i.e. the
     * bottom line is at the beginning of the buffer). */
    int             ydir;
    /* Current framebuffer pointer. */
    uint8_t*        current_fb;
} MTSState;

/* Default multi-touch screen descriptor */
static MTSState _MTSState;

/* Pushes event to the event device. */
static void
_push_event(int type, int code, int value)
{
    user_event_generic(type, code, value);
}

/* Gets an index in the MTS's tracking pointers array MTS for the given
 * tracking id.
 * Return:
 *  Index of a matching entry in the MTS's tracking pointers array, or -1 if
 *  matching entry was not found.
 */
static int
_mtsstate_get_pointer_index(const MTSState* mts_state, int tracking_id)
{
    int index;
    for (index = 0; index < MTS_POINTERS_NUM; index++) {
        if (mts_state->tracked_pointers[index].tracking_id == tracking_id) {
            return index;
        }
    }
    return -1;
}

/* Gets an index of the first untracking pointer in the MTS's tracking pointers
 * array.
 * Return:
 *  An index of the first untracking pointer, or -1 if all pointers are tracked.
 */
static int
_mtsstate_get_available_pointer_index(const MTSState* mts_state)
{
    return _mtsstate_get_pointer_index(mts_state, MTS_POINTER_UP);
}

/* Handles a "pointer down" event
 * Param:
 *  mts_state - MTS state descriptor.
 *  tracking_id - Tracking ID of the "downed" pointer.
 *  x, y - "Downed" pointer coordinates,
 *  pressure - Pressure value for the pointer.
 */
static void
_mts_pointer_down(MTSState* mts_state, int tracking_id, int x, int y, int pressure)
{
    /* Get first available slot for the new pointer. */
    const int slot_index = _mtsstate_get_available_pointer_index(mts_state);

    /* Make sure there is a place for the pointer. */
    if (slot_index >= 0) {
        /* Initialize pointer's entry. */
        mts_state->tracked_ptr_num++;
        mts_state->tracked_pointers[slot_index].tracking_id = tracking_id;
        mts_state->tracked_pointers[slot_index].x = x;
        mts_state->tracked_pointers[slot_index].y = y;
        mts_state->tracked_pointers[slot_index].pressure = pressure;

        /* Send events indicating a "pointer down" to the EventHub */
        /* Make sure that correct slot is selected. */
        if (slot_index != mts_state->current_slot) {
            _push_event(EV_ABS, ABS_MT_SLOT, slot_index);
        }
        _push_event(EV_ABS, ABS_MT_TRACKING_ID, slot_index);
        _push_event(EV_ABS, ABS_MT_TOUCH_MAJOR, ++mts_state->touch_major);
        _push_event(EV_ABS, ABS_MT_PRESSURE, pressure);
        _push_event(EV_ABS, ABS_MT_POSITION_X, x);
        _push_event(EV_ABS, ABS_MT_POSITION_Y, y);
        _push_event(EV_SYN, SYN_REPORT, 0);
        mts_state->current_slot = slot_index;
    } else {
        D("MTS pointer count is exceeded.");
        return;
    }
}

/* Handles a "pointer up" event
 * Param:
 *  mts_state - MTS state descriptor.
 *  slot_index - Pointer's index in the MTS's array of tracked pointers.
 */
static void
_mts_pointer_up(MTSState* mts_state, int slot_index)
{
    /* Make sure that correct slot is selected. */
    if (slot_index != mts_state->current_slot) {
        _push_event(EV_ABS, ABS_MT_SLOT, slot_index);
    }

    /* Send event indicating "pointer up" to the EventHub. */
    _push_event(EV_ABS, ABS_MT_TRACKING_ID, -1);
    _push_event(EV_SYN, SYN_REPORT, 0);

    /* Update MTS descriptor, removing the tracked pointer. */
    mts_state->tracked_pointers[slot_index].tracking_id = MTS_POINTER_UP;
    mts_state->tracked_pointers[slot_index].x = 0;
    mts_state->tracked_pointers[slot_index].y = 0;
    mts_state->tracked_pointers[slot_index].pressure = 0;

    /* Since current slot is no longer tracked, make sure we will do a "select"
     * next time we send events to the EventHub. */
    mts_state->current_slot = -1;
    mts_state->tracked_ptr_num--;
    assert(mts_state->tracked_ptr_num >= 0);
}

/* Handles a "pointer move" event
 * Param:
 *  mts_state - MTS state descriptor.
 *  slot_index - Pointer's index in the MTS's array of tracked pointers.
 *  x, y - New pointer coordinates,
 *  pressure - Pressure value for the pointer.
 */
static void
_mts_pointer_move(MTSState* mts_state, int slot_index, int x, int y, int pressure)
{
    MTSPointerState* ptr_state = &mts_state->tracked_pointers[slot_index];

    /* Make sure that coordinates have really changed. */
    if (ptr_state->x == x && ptr_state->y == y) {
        /* Coordinates didn't change. Bail out. */
        return;
    }

    /* Make sure that the right slot is selected. */
    if (slot_index != mts_state->current_slot) {
        _push_event(EV_ABS, ABS_MT_SLOT, slot_index);
        mts_state->current_slot = slot_index;
    }

    /* Push the changes down. */
    if (ptr_state->pressure != pressure && pressure != 0) {
        _push_event(EV_ABS, ABS_MT_PRESSURE, pressure);
        ptr_state->pressure = pressure;
    }
    if (ptr_state->x != x) {
        _push_event(EV_ABS, ABS_MT_POSITION_X, x);
        ptr_state->x = x;
    }
    if (ptr_state->y != y) {
        _push_event(EV_ABS, ABS_MT_POSITION_Y, y);
        ptr_state->y = y;
    }
    _push_event(EV_SYN, SYN_REPORT, 0);
}

/********************************************************************************
 *                       Multi-touch API
 *******************************************************************************/

/* Multi-touch service initialization flag. */
static int _is_mt_initialized = 0;

/* Callback that is invoked when framebuffer update has been transmitted to the
 * device. */
static AsyncIOAction
_on_fb_sent(void* opaque, SDKCtlDirectPacket* packet, AsyncIOState status)
{
    MTSState* const mts_state = (MTSState*)opaque;

    if (status == ASIO_STATE_SUCCEEDED) {
        /* Lets see if we have accumulated more changes while transmission has been
         * in progress. */
        if (mts_state->fb_header.w && mts_state->fb_header.h) {
            /* Send accumulated updates. */
            if (mts_port_send_frame(mts_state->mtsp, &mts_state->fb_header,
                                    mts_state->current_fb, _on_fb_sent, mts_state,
                                    mts_state->ydir)) {
                mts_state->fb_transfer_in_progress = 0;
            }
        } else {
            /* Framebuffer transfer is completed, and no more updates are pending. */
            mts_state->fb_transfer_in_progress = 0;
        }
    }

    return ASIO_ACTION_DONE;
}

/* Common handler for framebuffer updates invoked by both, software, and OpenGLES
 * renderers.
 */
static void
_mt_fb_common_update(MTSState* mts_state, int x, int y, int w, int h)
{
    if (mts_state->fb_header.w == 0 && mts_state->fb_header.h == 0) {
        /* First update after previous one has been transmitted to the device. */
        mts_state->fb_header.x = x;
        mts_state->fb_header.y = y;
        mts_state->fb_header.w = w;
        mts_state->fb_header.h = h;
    } else {
        /*
         * Accumulate framebuffer changes in the header.
         */

        /* "right" and "bottom" coordinates of the current update. */
        int right = mts_state->fb_header.x + mts_state->fb_header.w;
        int bottom = mts_state->fb_header.y + mts_state->fb_header.h;

        /* "right" and "bottom" coordinates of the new update. */
        const int new_right = x + w;
        const int new_bottom = y + h;

        /* Accumulate changed rectangle coordinates in the header. */
        if (mts_state->fb_header.x > x) {
            mts_state->fb_header.x = x;
        }
        if (mts_state->fb_header.y > y) {
            mts_state->fb_header.y = y;
        }
        if (right < new_right) {
            right = new_right;
        }
        if (bottom < new_bottom) {
            bottom = new_bottom;
        }
        mts_state->fb_header.w = right - mts_state->fb_header.x;
        mts_state->fb_header.h = bottom - mts_state->fb_header.y;
    }

    /* We will send updates to the device only after previous transmission is
     * completed. */
    if (!mts_state->fb_transfer_in_progress) {
        mts_state->fb_transfer_in_progress = 1;
        if (mts_port_send_frame(mts_state->mtsp, &mts_state->fb_header,
                                mts_state->current_fb, _on_fb_sent, mts_state,
                                mts_state->ydir)) {
            mts_state->fb_transfer_in_progress = 0;
        }
    }
}

/* A callback invoked on framebuffer updates by software renderer.
 * Param:
 *  opaque - MTSState instance.
 *  x, y, w, h - Defines an updated rectangle inside the framebuffer.
 */
static void
_mt_fb_update(void* opaque, int x, int y, int w, int h)
{
    MTSState* const mts_state = (MTSState*)opaque;
    const DisplaySurface* const surface = mts_state->ds->surface;

    T("Multi-touch: Software renderer framebuffer update: %d:%d -> %dx%d",
      x, y, w, h);

    /* TODO: For sofware renderer general framebuffer properties can change on
     * the fly. Find a callback that can catch that. For now, just copy FB
     * properties over in every FB update. */
    mts_state->fb_header.bpp = surface->pf.bytes_per_pixel;
    mts_state->fb_header.bpl = surface->linesize;
    mts_state->fb_header.disp_width = surface->width;
    mts_state->fb_header.disp_height = surface->height;
    mts_state->current_fb = surface->data;
    mts_state->ydir = 1;

    _mt_fb_common_update(mts_state, x, y, w, h);
}

void
multitouch_opengles_fb_update(void* context,
                              int w, int h, int ydir,
                              int format, int type,
                              unsigned char* pixels)
{
    MTSState* const mts_state = &_MTSState;

    /* Make sure MT port is initialized. */
    if (!_is_mt_initialized) {
        return;
    }

    T("Multi-touch: openGLES framebuffer update: 0:0 -> %dx%d", w, h);

    /* GLES format is always RGBA8888 */
    mts_state->fb_header.bpp = 4;
    mts_state->fb_header.bpl = 4 * w;
    mts_state->fb_header.disp_width = w;
    mts_state->fb_header.disp_height = h;
    mts_state->current_fb = pixels;
    mts_state->ydir = ydir;

    /* GLES emulator alwas update the entire framebuffer. */
    _mt_fb_common_update(mts_state, 0, 0, w, h);
}

void
multitouch_init(AndroidMTSPort* mtsp)
{
    if (!_is_mt_initialized) {
        MTSState* const mts_state = &_MTSState;
        DisplayState* const ds = get_displaystate();
        DisplayUpdateListener* dul;
        int index;

        /*
         * Initialize the descriptor.
         */

        memset(mts_state, 0, sizeof(MTSState));
        mts_state->tracked_ptr_num = 0;
        mts_state->current_slot = -1;
        for (index = 0; index < MTS_POINTERS_NUM; index++) {
            mts_state->tracked_pointers[index].tracking_id = MTS_POINTER_UP;
        }
        mts_state->mtsp = mtsp;
        mts_state->fb_header.header_size = sizeof(MTFrameHeader);
        mts_state->fb_transfer_in_progress = 0;

        /*
         * Set framebuffer update listener.
         */

        ANEW0(dul);
        dul->opaque = &_MTSState;
        dul->dpy_update = _mt_fb_update;

        /* Initialize framebuffer information in the screen descriptor. */
        mts_state->ds = ds;
        mts_state->fb_header.disp_width = ds->surface->width;
        mts_state->fb_header.disp_height = ds->surface->height;
        mts_state->fb_header.x = mts_state->fb_header.y = 0;
        mts_state->fb_header.w = mts_state->fb_header.h = 0;
        mts_state->fb_header.bpp = ds->surface->pf.bytes_per_pixel;
        mts_state->fb_header.bpl = ds->surface->linesize;
        mts_state->fb_transfer_in_progress = 0;

        register_displayupdatelistener(ds, dul);

        _is_mt_initialized = 1;
    }
}

void
multitouch_update_pointer(MTESource source,
                          int tracking_id,
                          int x,
                          int y,
                          int pressure)
{
    MTSState* const mts_state = &_MTSState;

    /* Assign a fixed tracking ID to the mouse pointer. */
    if (source == MTES_MOUSE) {
        tracking_id = MTS_POINTER_MOUSE;
    }

    /* Find the tracked pointer for the tracking ID. */
    const int slot_index = _mtsstate_get_pointer_index(mts_state, tracking_id);
    if (slot_index < 0) {
        /* This is the first time the pointer is seen. Must be "pressed",
         * otherwise it's "hoovering", which we don't support yet. */
        if (pressure == 0) {
            if (tracking_id != MTS_POINTER_MOUSE) {
                D("Unexpected MTS pointer update for tracking id: %d",
                   tracking_id);
            }
            return;
        }

        /* This is a "pointer down" event */
        _mts_pointer_down(mts_state, tracking_id, x, y, pressure);
    } else if (pressure == 0) {
        /* This is a "pointer up" event */
        _mts_pointer_up(mts_state, slot_index);
    } else {
        /* This is a "pointer move" event */
        _mts_pointer_move(mts_state, slot_index, x, y, pressure);
    }
}

int
multitouch_get_max_slot()
{
    return MTS_POINTERS_NUM - 1;
}
