/*
 * 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 "android/multitouch-port.h"

#include "android/globals.h"  /* for android_hw */
#include "android/hw-events.h"
#include "android/jpeg-compress.h"
#include "android/multitouch-screen.h"
#include "android/opengles.h"
#include "android/sdk-controller-socket.h"
#include "android/skin/charmap.h"
#include "android/utils/debug.h"
#include "android/utils/misc.h"
#include "android/utils/panic.h"

#include <assert.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
/* Framebuffer update has been received. */
#define SDKCTL_MT_FB_UPDATE_RECEIVED    7
/* Framebuffer update has been handled. */
#define SDKCTL_MT_FB_UPDATE_HANDLED     8

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

/* Last pointer up event handler. */
static void
_on_action_up(int tracking_id)
{
    multitouch_update_pointer(MTES_DEVICE, tracking_id, 0, 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, 0);
}

/* Pointer up event handler. */
static void
_on_action_pointer_up(int tracking_id)
{
    multitouch_update_pointer(MTES_DEVICE, tracking_id, 0, 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, 0);
}

/********************************************************************************
 *                          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);
            }
            /* Refresh (possibly stale) device screen. */
            multitouch_refresh_screen();
            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;

        case SDKCTL_MT_FB_UPDATE_RECEIVED:
            D("Framebuffer update ACK.");
            break;

        case SDKCTL_MT_FB_UPDATE_HANDLED:
            D("Framebuffer update handled.");
            multitouch_fb_updated();
            break;

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

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

AndroidMTSPort* mts_port_create(
        void* opaque,
        const QAndroidUserEventAgent* user_event_agent,
        const QAndroidDisplayAgent* display_agent) {
    AndroidMTSPort* mtsp;

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

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

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