/*
 * 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 "utils/panic.h"
#include "android/hw-events.h"
#include "android/charmap.h"
#include "android/multitouch-screen.h"
#include "android/sdk-controller-socket.h"
#include "android/multitouch-port.h"
#include "android/globals.h"  /* for android_hw */
#include "android/opengles.h"
#include "android/utils/misc.h"
#include "android/utils/jpeg-compress.h"
#include "android/utils/debug.h"

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

#define TRACE_ON    1

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

/* Timeout (millisec) to use when communicating with SDK controller. */
#define SDKCTL_MT_TIMEOUT      3000

/*
 * Message types used in multi-touch emulation.
 */

/* Pointer move message. */
#define SDKCTL_MT_MOVE          1
/* First pointer down message. */
#define SDKCTL_MT_FISRT_DOWN    2
/* Last pointer up message. */
#define SDKCTL_MT_LAST_UP       3
/* Pointer down message. */
#define SDKCTL_MT_POINTER_DOWN  4
/* Pointer up message. */
#define SDKCTL_MT_POINTER_UP    5
/* Sends framebuffer update. */
#define SDKCTL_MT_FB_UPDATE     6

/* Multi-touch port descriptor. */
struct AndroidMTSPort {
    /* Caller identifier. */
    void*               opaque;
    /* Communication socket. */
    SDKCtlSocket*       sdkctl;
    /* Initialized JPEG compressor instance. */
    AJPEGDesc*          jpeg_compressor;
    /* Direct packet descriptor for framebuffer updates. */
    SDKCtlDirectPacket* fb_packet;
};

/* Data sent with SDKCTL_MT_QUERY_START */
typedef struct QueryDispData {
    /* Width of the emulator display. */
    int     width;
    /* Height of the emulator display. */
    int     height;
} QueryDispData;

/* Multi-touch event structure received from SDK controller port. */
typedef struct AndroidMTEvent {
    /* Pointer identifier. */
    int     pid;
    /* Pointer 'x' coordinate. */
    int     x;
    /* Pointer 'y' coordinate. */
    int     y;
    /* Pointer pressure. */
    int     pressure;
} AndroidMTEvent;

/* Multi-touch pointer descriptor received from SDK controller port. */
typedef struct AndroidMTPtr {
    /* Pointer identifier. */
    int     pid;
} AndroidMTPtr;

/* Destroys and frees the descriptor. */
static void
_mts_port_free(AndroidMTSPort* mtsp)
{
    if (mtsp != NULL) {
        if (mtsp->fb_packet != NULL) {
            sdkctl_direct_packet_release(mtsp->fb_packet);
        }
        if (mtsp->jpeg_compressor != NULL) {
            jpeg_compressor_destroy(mtsp->jpeg_compressor);
        }
        if (mtsp->sdkctl != NULL) {
            sdkctl_socket_release(mtsp->sdkctl);
        }
        AFREE(mtsp);
    }
}

/********************************************************************************
 *                          Multi-touch action handlers
 *******************************************************************************/

/*
 * Although there are a lot of similarities in the way the handlers below are
 * implemented, for the sake of tracing / debugging it's better to have a
 * separate handler for each distinctive action.
 */

/* First pointer down event handler. */
static void
_on_action_down(int tracking_id, int x, int y, int pressure)
{
    multitouch_update_pointer(MTES_DEVICE, tracking_id, x, y, pressure);
}

/* Last pointer up event handler. */
static void
_on_action_up(int tracking_id)
{
    multitouch_update_pointer(MTES_DEVICE, tracking_id, 0, 0, 0);
}

/* Pointer down event handler. */
static void
_on_action_pointer_down(int tracking_id, int x, int y, int pressure)
{
    multitouch_update_pointer(MTES_DEVICE, tracking_id, x, y, pressure);
}

/* Pointer up event handler. */
static void
_on_action_pointer_up(int tracking_id)
{
    multitouch_update_pointer(MTES_DEVICE, tracking_id, 0, 0, 0);
}

/* Pointer move event handler. */
static void
_on_action_move(int tracking_id, int x, int y, int pressure)
{
    multitouch_update_pointer(MTES_DEVICE, tracking_id, x, y, pressure);
}

/********************************************************************************
 *                          Multi-touch event handlers
 *******************************************************************************/

/* Handles "pointer move" event.
 * Param:
 *  param - Array of moving pointers.
 *  pointers_count - Number of pointers in the array.
 */
static void
_on_move(const AndroidMTEvent* param, int pointers_count)
{
    int n;
    for (n = 0; n < pointers_count; n++, param++) {
        T("Multi-touch: MOVE(%d): %d-> %d:%d:%d",
          n, param->pid, param->x, param->y, param->pressure);
         _on_action_move(param->pid, param->x, param->y, param->pressure);
    }
}

/* Handles "first pointer down" event. */
static void
_on_down(const AndroidMTEvent* param)
{
    T("Multi-touch: 1-ST DOWN: %d-> %d:%d:%d",
      param->pid, param->x, param->y, param->pressure);
    _on_action_down(param->pid, param->x, param->y, param->pressure);
}

/* Handles "last pointer up" event. */
static void
_on_up(const AndroidMTPtr* param)
{
    T("Multi-touch: LAST UP: %d", param->pid);
    _on_action_up(param->pid);
}

/* Handles "next pointer down" event. */
static void
_on_pdown(const AndroidMTEvent* param)
{
    T("Multi-touch: DOWN: %d-> %d:%d:%d",
      param->pid, param->x, param->y, param->pressure);
    _on_action_pointer_down(param->pid, param->x, param->y, param->pressure);
}

/* Handles "next pointer up" event. */
static void
_on_pup(const AndroidMTPtr* param)
{
    T("Multi-touch: UP: %d", param->pid);
    _on_action_pointer_up(param->pid);
}

/********************************************************************************
 *                      Device communication callbacks
 *******************************************************************************/

/* A callback that is invoked on SDK controller socket connection events. */
static AsyncIOAction
_on_multitouch_socket_connection(void* opaque,
                                 SDKCtlSocket* sdkctl,
                                 AsyncIOState status)
{
    if (status == ASIO_STATE_FAILED) {
        /* Reconnect (after timeout delay) on failures */
        if (sdkctl_socket_is_handshake_ok(sdkctl)) {
            sdkctl_socket_reconnect(sdkctl, SDKCTL_DEFAULT_TCP_PORT,
                                    SDKCTL_MT_TIMEOUT);
        }
    }
    return ASIO_ACTION_DONE;
}

/* A callback that is invoked on SDK controller port connection events. */
static void
_on_multitouch_port_connection(void* opaque,
                               SDKCtlSocket* sdkctl,
                               SdkCtlPortStatus status)
{
    switch (status) {
        case SDKCTL_PORT_CONNECTED:
            D("Multi-touch: SDK Controller is connected");
            break;

        case SDKCTL_PORT_DISCONNECTED:
            D("Multi-touch: SDK Controller is disconnected");
            // Disable OpenGLES framebuffer updates.
            if (android_hw->hw_gpu_enabled) {
                android_setPostCallback(NULL, NULL);
            }
            break;

        case SDKCTL_PORT_ENABLED:
            D("Multi-touch: SDK Controller port is enabled.");
            // Enable OpenGLES framebuffer updates.
            if (android_hw->hw_gpu_enabled) {
                android_setPostCallback(multitouch_opengles_fb_update, NULL);
            }
            break;

        case SDKCTL_PORT_DISABLED:
            D("Multi-touch: SDK Controller port is disabled.");
            // Disable OpenGLES framebuffer updates.
            if (android_hw->hw_gpu_enabled) {
                android_setPostCallback(NULL, NULL);
            }
            break;

        case SDKCTL_HANDSHAKE_CONNECTED:
            D("Multi-touch: Handshake succeeded with connected port.");
            break;

        case SDKCTL_HANDSHAKE_NO_PORT:
            D("Multi-touch: Handshake succeeded with disconnected port.");
            break;

        case SDKCTL_HANDSHAKE_DUP:
            W("Multi-touch: Handshake failed due to port duplication.");
            sdkctl_socket_disconnect(sdkctl);
            break;

        case SDKCTL_HANDSHAKE_UNKNOWN_QUERY:
            W("Multi-touch: Handshake failed due to unknown query.");
            sdkctl_socket_disconnect(sdkctl);
            break;

        case SDKCTL_HANDSHAKE_UNKNOWN_RESPONSE:
        default:
            W("Multi-touch: Handshake failed due to unknown reason.");
            sdkctl_socket_disconnect(sdkctl);
            break;
    }
}

/* A callback that is invoked when a message is received from the device. */
static void
_on_multitouch_message(void* client_opaque,
                       SDKCtlSocket* sdkctl,
                       SDKCtlMessage* message,
                       int msg_type,
                       void* msg_data,
                       int msg_size)
{
    switch (msg_type) {
        case SDKCTL_MT_MOVE: {
            assert((msg_size / sizeof(AndroidMTEvent)) && !(msg_size % sizeof(AndroidMTEvent)));
            _on_move((const AndroidMTEvent*)msg_data, msg_size / sizeof(AndroidMTEvent));
            break;
        }

        case SDKCTL_MT_FISRT_DOWN:
            assert(msg_size / sizeof(AndroidMTEvent) && !(msg_size % sizeof(AndroidMTEvent)));
            _on_down((const AndroidMTEvent*)msg_data);
            break;

        case SDKCTL_MT_LAST_UP:
            _on_up((const AndroidMTPtr*)msg_data);
            break;

        case SDKCTL_MT_POINTER_DOWN:
            assert(msg_size / sizeof(AndroidMTEvent) && !(msg_size % sizeof(AndroidMTEvent)));
            _on_pdown((const AndroidMTEvent*)msg_data);
            break;

        case SDKCTL_MT_POINTER_UP:
            _on_pup((const AndroidMTPtr*)msg_data);
            break;

        default:
            W("Multi-touch: Unknown message %d", msg_type);
            break;
    }
}

/********************************************************************************
 *                          MTS port API
 *******************************************************************************/

AndroidMTSPort*
mts_port_create(void* opaque)
{
    AndroidMTSPort* mtsp;

    ANEW0(mtsp);
    mtsp->opaque                = opaque;

    /* Initialize default MTS descriptor. */
    multitouch_init(mtsp);

    /* Create JPEG compressor. Put message header + MTFrameHeader in front of the
     * compressed data. this way we will have entire query ready to be
     * transmitted to the device. */
    mtsp->jpeg_compressor =
        jpeg_compressor_create(sdkctl_message_get_header_size() + sizeof(MTFrameHeader), 4096);

    mtsp->sdkctl = sdkctl_socket_new(SDKCTL_MT_TIMEOUT, "multi-touch",
                                     _on_multitouch_socket_connection,
                                     _on_multitouch_port_connection,
                                     _on_multitouch_message, mtsp);
    sdkctl_init_recycler(mtsp->sdkctl, 64, 8);

    /* Create a direct packet that will wrap up framebuffer updates. Note that
     * we need to do this after we have initialized the recycler! */
    mtsp->fb_packet = sdkctl_direct_packet_new(mtsp->sdkctl);

    /* Now we can initiate connection witm MT port on the device. */
    sdkctl_socket_connect(mtsp->sdkctl, SDKCTL_DEFAULT_TCP_PORT,
                          SDKCTL_MT_TIMEOUT);

    return mtsp;
}

void
mts_port_destroy(AndroidMTSPort* mtsp)
{
    _mts_port_free(mtsp);
}

/********************************************************************************
 *                       Handling framebuffer updates
 *******************************************************************************/

/* Compresses a framebuffer region into JPEG image.
 * Param:
 *  mtsp - Multi-touch port descriptor with initialized JPEG compressor.
 *  fmt Descriptor for framebuffer region to compress.
 *  fb Beginning of the framebuffer.
 *  jpeg_quality JPEG compression quality. A number from 1 to 100. Note that
 *      value 10 provides pretty decent image for the purpose of multi-touch
 *      emulation.
 */
static void
_fb_compress(const AndroidMTSPort* mtsp,
             const MTFrameHeader* fmt,
             const uint8_t* fb,
             int jpeg_quality,
             int ydir)
{
    T("Multi-touch: compressing %d bytes frame buffer", fmt->w * fmt->h * fmt->bpp);

    jpeg_compressor_compress_fb(mtsp->jpeg_compressor, fmt->x, fmt->y, fmt->w,
                                fmt->h, fmt->disp_height, fmt->bpp, fmt->bpl,
                                fb, jpeg_quality, ydir);
}

int
mts_port_send_frame(AndroidMTSPort* mtsp,
                    MTFrameHeader* fmt,
                    const uint8_t* fb,
                    on_sdkctl_direct_cb cb,
                    void* cb_opaque,
                    int ydir)
{
    /* Make sure that port is connected. */
    if (!sdkctl_socket_is_port_ready(mtsp->sdkctl)) {
        return -1;
    }

    /* Compress framebuffer region. 10% quality seems to be sufficient. */
    fmt->format = MTFB_JPEG;
    _fb_compress(mtsp, fmt, fb, 10, ydir);

    /* Total size of the update data: header + JPEG image. */
    const int update_size =
        sizeof(MTFrameHeader) + jpeg_compressor_get_jpeg_size(mtsp->jpeg_compressor);

    /* Update message starts at the beginning of the buffer allocated by the
     * compressor's destination manager. */
    uint8_t* const msg = (uint8_t*)jpeg_compressor_get_buffer(mtsp->jpeg_compressor);

    /* Initialize message header. */
    sdkctl_init_message_header(msg, SDKCTL_MT_FB_UPDATE, update_size);

    /* Copy framebuffer update header to the message. */
    memcpy(msg + sdkctl_message_get_header_size(), fmt, sizeof(MTFrameHeader));

    /* Compression rate... */
    const float comp_rate = ((float)jpeg_compressor_get_jpeg_size(mtsp->jpeg_compressor) / (fmt->w * fmt->h * fmt->bpp)) * 100;

    /* Zeroing the rectangle in the update header we indicate that it contains
     * no updates. */
    fmt->x = fmt->y = fmt->w = fmt->h = 0;

    /* Send update to the device. */
    sdkctl_direct_packet_send(mtsp->fb_packet, msg, cb, cb_opaque);

    T("Multi-touch: Sent %d bytes in framebuffer update. Compression rate is %.2f%%",
      update_size, comp_rate);

    return 0;
}
