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

/* 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;
    /* Screen width of the device that emulates multi-touch. */
    int             device_width;
    /* Screen height of the device that emulates multi-touch. */
    int             device_height;
    /* 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 void
_on_fb_sent(void* opaque, ATResult res, void* data, int size, int sent)
{
    MTSState* const mts_state = (MTSState*)opaque;

    /* 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;
    }
}

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

    /* 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;
    }

    /* 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->device_width = android_hw->hw_lcd_width;
        mts_state->device_height = android_hw->hw_lcd_height;
        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;
}

void
multitouch_set_device_screen_size(int width, int height)
{
    MTSState* const mts_state = &_MTSState;

    mts_state->device_width = width;
    mts_state->device_height = height;
}
