// Copyright 2016 The Fuchsia 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 <assert.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <hid/acer12.h>
#include <hid/paradise.h>
#include <hid/usages.h>

#include <zircon/device/console.h>
#include <zircon/device/display.h>
#include <zircon/device/input.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#define DEV_INPUT       "/dev/class/input"
#define FRAMEBUFFER     "/dev/class/framebuffer/000"
#define CLEAR_BTN_SIZE 50
#define I2C_HID_DEBUG 0

enum touch_panel_type {
    TOUCH_PANEL_UNKNOWN,
    TOUCH_PANEL_ACER12,
    TOUCH_PANEL_PARADISE,
};

// Array of colors for each finger
static uint32_t colors[] = {
    0x00ff0000,
    0x0000ff00,
    0x000000ff,
    0x00ffff00,
    0x00ff00ff,
    0x0000ffff,
    0x00000000,
    0x00f0f0f0,
    0x00f00f00,
    0x000ff000,
};

static void acer12_touch_dump(acer12_touch_t* rpt) {
    printf("report id: %u\n", rpt->rpt_id);
    for (int i = 0; i < 5; i++) {
        printf("finger %d\n", i);
        printf("  finger_id: %u\n", rpt->fingers[i].finger_id);
        printf("    tswitch: %u\n", acer12_finger_id_tswitch(rpt->fingers[i].finger_id));
        printf("    contact: %u\n", acer12_finger_id_contact(rpt->fingers[i].finger_id));
        printf("  width:  %u\n", rpt->fingers[i].width);
        printf("  height: %u\n", rpt->fingers[i].height);
        printf("  x:      %u\n", rpt->fingers[i].x);
        printf("  y:      %u\n", rpt->fingers[i].y);
    }
    printf("scan_time: %u\n", rpt->scan_time);
    printf("contact count: %u\n", rpt->contact_count);
}

static void paradise_touch_dump(paradise_touch_t* rpt) {
    printf("report id: %u\n", rpt->rpt_id);
    printf("pad: %#02x\n", rpt->pad);
    printf("contact count: %u\n", rpt->contact_count);
    for (int i = 0; i < 5; i++) {
        printf("finger %d\n", i);
        printf("  flags: %#02x\n", rpt->fingers[i].flags);
        printf("    tswitch: %u\n", paradise_finger_flags_tswitch(rpt->fingers[i].flags));
        printf("    confidence: %u\n", paradise_finger_flags_confidence(rpt->fingers[i].flags));
        printf("  finger_id: %u\n", rpt->fingers[i].finger_id);
        printf("  x:      %u\n", rpt->fingers[i].x);
        printf("  y:      %u\n", rpt->fingers[i].y);
    }
    printf("scan_time: %u\n", rpt->scan_time);
}

static uint32_t scale32(uint32_t z, uint32_t screen_dim, uint32_t rpt_dim) {
    return (z * screen_dim) / rpt_dim;
}

static void draw_points(uint32_t* pixels, uint32_t color, uint32_t x, uint32_t y, uint8_t width, uint8_t height, uint32_t fbwidth, uint32_t fbheight) {
    uint32_t xrad = (width + 1) / 2;
    uint32_t yrad = (height + 1) / 2;

    uint32_t xmin = (xrad > x) ? 0 : x - xrad;
    uint32_t xmax = (xrad > fbwidth - x) ? fbwidth : x + xrad;
    uint32_t ymin = (yrad > y) ? 0 : y - yrad;
    uint32_t ymax = (yrad > fbheight - y) ? fbheight : y + yrad;

    for (uint32_t px = xmin; px < xmax; px++) {
        for (uint32_t py = ymin; py < ymax; py++) {
            *(pixels + py * fbwidth + px) = color;
        }
    }
}

static uint32_t get_color(uint8_t c) {
    return colors[c];
}

static void clear_screen(void* buf, ioctl_display_get_fb_t* fb) {
    memset(buf, 0xff, fb->info.pixelsize * fb->info.stride * fb->info.height);
    draw_points((uint32_t*)buf, 0xff00ff, fb->info.stride - (CLEAR_BTN_SIZE / 2), (CLEAR_BTN_SIZE / 2),
            CLEAR_BTN_SIZE, CLEAR_BTN_SIZE, fb->info.stride, fb->info.height);
}

static void process_acer12_touchscreen_input(void* buf, size_t len, int vcfd, uint32_t* pixels,
        ioctl_display_get_fb_t* fb) {
    acer12_touch_t* rpt = buf;
    if (len < sizeof(*rpt)) {
        printf("bad report size: %zd < %zd\n", len, sizeof(*rpt));
        return;
    }
#if I2C_HID_DEBUG
    acer12_touch_dump(rpt);
#endif
    for (uint8_t c = 0; c < 5; c++) {
        if (!acer12_finger_id_tswitch(rpt->fingers[c].finger_id % 10)) continue;
        uint32_t x = scale32(rpt->fingers[c].x, fb->info.width, ACER12_X_MAX);
        uint32_t y = scale32(rpt->fingers[c].y, fb->info.height, ACER12_Y_MAX);
        uint32_t width = 2 * rpt->fingers[c].width;
        uint32_t height = 2 * rpt->fingers[c].height;
        uint32_t color = get_color(acer12_finger_id_contact(rpt->fingers[c].finger_id));
        draw_points(pixels, color, x, y, width, height, fb->info.stride, fb->info.height);
    }

    if (acer12_finger_id_tswitch(rpt->fingers[0].finger_id)) {
        uint32_t x = scale32(rpt->fingers[0].x, fb->info.width, ACER12_X_MAX);
        uint32_t y = scale32(rpt->fingers[0].y, fb->info.height, ACER12_Y_MAX);
        if (x + CLEAR_BTN_SIZE > fb->info.width && y < CLEAR_BTN_SIZE) {
            clear_screen(pixels, fb);
        }
    }
    ssize_t ret = ioctl_display_flush_fb(vcfd);
    if (ret < 0) {
        printf("failed to flush: %zd\n", ret);
    }
}

static void process_paradise_touchscreen_input(void* buf, size_t len, int vcfd, uint32_t* pixels,
        ioctl_display_get_fb_t* fb) {
    paradise_touch_t* rpt = buf;
    if (len < sizeof(*rpt)) {
        printf("bad report size: %zd < %zd\n", len, sizeof(*rpt));
        return;
    }
#if I2C_HID_DEBUG
    paradise_touch_dump(rpt);
#endif
    for (uint8_t c = 0; c < 5; c++) {
        if (!paradise_finger_flags_tswitch(rpt->fingers[c].flags)) continue;
        uint32_t x = scale32(rpt->fingers[c].x, fb->info.width, PARADISE_X_MAX);
        uint32_t y = scale32(rpt->fingers[c].y, fb->info.height, PARADISE_Y_MAX);
        uint32_t width = 10;
        uint32_t height = 10;
        uint32_t color = get_color(c);
        draw_points(pixels, color, x, y, width, height, fb->info.stride, fb->info.height);
    }

    if (paradise_finger_flags_tswitch(rpt->fingers[0].flags)) {
        uint32_t x = scale32(rpt->fingers[0].x, fb->info.width, PARADISE_X_MAX);
        uint32_t y = scale32(rpt->fingers[0].y, fb->info.height, PARADISE_Y_MAX);
        if (x + CLEAR_BTN_SIZE > fb->info.width && y < CLEAR_BTN_SIZE) {
            clear_screen(pixels, fb);
        }
    }
    ssize_t ret = ioctl_display_flush_fb(vcfd);
    if (ret < 0) {
        printf("failed to flush: %zd\n", ret);
    }
}

static void process_acer12_stylus_input(void* buf, size_t len, int vcfd, uint32_t* pixels,
        ioctl_display_get_fb_t* fb) {
    acer12_stylus_t* rpt = buf;
    if (len < sizeof(*rpt)) {
        printf("bad report size: %zd < %zd\n", len, sizeof(*rpt));
        return;
    }
    // Don't draw for out of range or hover with no switches.
    if (!rpt->status || rpt->status == ACER12_STYLUS_STATUS_INRANGE) return;

    uint32_t x = scale32(rpt->x, fb->info.width, ACER12_STYLUS_X_MAX);
    uint32_t y = scale32(rpt->y, fb->info.height, ACER12_STYLUS_Y_MAX);
    // Pressing the clear button requires contact (not just hover).
    if (acer12_stylus_status_tswitch(rpt->status)) {
        if (x + CLEAR_BTN_SIZE > fb->info.width && y < CLEAR_BTN_SIZE) {
            clear_screen(pixels, fb);
            goto flush;
        }
    }
    uint32_t size, color;
    size = acer12_stylus_status_tswitch(rpt->status) ? rpt->pressure >> 4 : 4;
    switch (rpt->status) {
    case 3: // in_range | tip_switch
        color = get_color(0);
        break;
    case 5: // in_range | barrel_switch
        color = get_color(1);
        break;
    case 7: // in_range | tip_switch | barrel_switch
        color = get_color(4);
        break;
    case 9: // in_range | invert
        color = get_color(5);
        break;
    case 17: // in_range | erase (== tip_switch | invert)
        color = 0x00ffffff;
        size = 32;  // fixed size eraser
        break;
    default:
        printf("unknown rpt->status=%u\n", rpt->status);
        color = get_color(6);
        break;
    }

    draw_points(pixels, color, x, y, size, size, fb->info.stride, fb->info.height);

flush: ;
    ssize_t ret = ioctl_display_flush_fb(vcfd);
    if (ret < 0) {
        printf("failed to flush: %zd\n", ret);
    }
}

int main(int argc, char* argv[]) {
    int vcfd = open(FRAMEBUFFER, O_RDWR);
    if (vcfd < 0) {
        printf("failed to open %s: %d\n", FRAMEBUFFER, errno);
        return -1;
    }

    ioctl_display_get_fb_t fb;
    ssize_t ret = ioctl_display_get_fb(vcfd, &fb);
    if (ret < 0) {
        printf("failed to get FB: %zd\n", ret);
        return -1;
    }
    if (fb.info.pixelsize != 4) {
        printf("only 32-bit framebuffers are supported for now!\n");
        return -1;
    }

    printf("format = %d\n", fb.info.format);
    printf("width = %d\n", fb.info.width);
    printf("height = %d\n", fb.info.height);
    printf("stride = %d\n", fb.info.stride);
    printf("pixelsize = %d\n", fb.info.pixelsize);
    printf("flags = 0x%x\n", fb.info.flags);


    size_t size = fb.info.stride * fb.info.pixelsize * fb.info.height;
    uintptr_t fbo;

    zx_status_t status = _zx_vmar_map(zx_vmar_root_self(), 0, fb.vmo, 0, size,
                                      ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE, &fbo);
    if (status < 0) {
        printf("couldn't map fb: %d\n", status);
        return -1;
    }
    uint32_t* pixels32 = (uint32_t*)fbo;

    // Scan /dev/class/input to find the touchscreen
    struct dirent* de;
    DIR* dir = opendir(DEV_INPUT);
    if (!dir) {
        printf("failed to open %s: %d\n", DEV_INPUT, errno);
        return -1;
    }

    int touchfd = -1;
    size_t rpt_desc_len = 0;
    uint8_t* rpt_desc = NULL;
    enum touch_panel_type panel = TOUCH_PANEL_UNKNOWN;
    while ((de = readdir(dir)) != NULL) {
        char devname[128];

        if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
            continue;
        }

        snprintf(devname, sizeof(devname), "%s/%s", DEV_INPUT, de->d_name);
        touchfd = open(devname, O_RDONLY);
        if (touchfd < 0) {
            printf("failed to open %s: %d\n", devname, errno);
            continue;
        }

        ret = ioctl_input_get_report_desc_size(touchfd, &rpt_desc_len);
        if (ret < 0) {
            printf("failed to get report descriptor length for %s: %zd\n", devname, ret);
            goto next_node;
        }

        rpt_desc = malloc(rpt_desc_len);
        if (rpt_desc == NULL) {
            printf("no memory!\n");
            exit(-1);
        }

        ret = ioctl_input_get_report_desc(touchfd, rpt_desc, rpt_desc_len);
        if (ret < 0) {
            printf("failed to get report descriptor for %s: %zd\n", devname, ret);
            goto next_node;
        }

        if (is_acer12_touch_report_desc(rpt_desc, rpt_desc_len)) {
            panel = TOUCH_PANEL_ACER12;
            // Found the touchscreen
            printf("touchscreen: %s\n", devname);
            break;
        }

        if (is_paradise_touch_report_desc(rpt_desc, rpt_desc_len)) {
            panel = TOUCH_PANEL_PARADISE;
            // Found the touchscreen
            printf("touchscreen: %s\n", devname);
            break;
        }

next_node:
        rpt_desc_len = 0;

        if (rpt_desc != NULL) {
            free(rpt_desc);
            rpt_desc = NULL;
        }

        if (touchfd >= 0) {
            close(touchfd);
            touchfd = -1;
        }
    }
    closedir(dir);

    if (touchfd < 0) {
        printf("could not find a touchscreen!\n");
        return -1;
    }
    assert(rpt_desc_len > 0);
    assert(rpt_desc);

    input_report_size_t max_rpt_sz = 0;
    ret = ioctl_input_get_max_reportsize(touchfd, &max_rpt_sz);
    if (ret < 0) {
        printf("failed to get max report size: %zd\n", ret);
        return -1;
    }
    void* buf = malloc(max_rpt_sz);
    if (buf == NULL) {
        printf("no memory!\n");
        return -1;
    }

    ret = ioctl_console_set_active_vc(vcfd);
    if (ret < 0) {
        printf("could not set active console: %zd\n", ret);
        // not a fatal error
        printf("press Alt-Tab to switch consoles\n");
    }

    clear_screen((void*)fbo, &fb);
    while (1) {
        ssize_t r = read(touchfd, buf, max_rpt_sz);
        if (r < 0) {
            printf("touchscreen read error: %zd (errno=%d)\n", r, errno);
            break;
        }
        if (panel == TOUCH_PANEL_ACER12) {
            if (*(uint8_t*)buf == ACER12_RPT_ID_TOUCH) {
                process_acer12_touchscreen_input(buf, r, vcfd, pixels32, &fb);
            } else if (*(uint8_t*)buf == ACER12_RPT_ID_STYLUS) {
                process_acer12_stylus_input(buf, r, vcfd, pixels32, &fb);
            }
        } else if (panel == TOUCH_PANEL_PARADISE) {
            if (*(uint8_t*)buf == PARADISE_RPT_ID_TOUCH) {
                process_paradise_touchscreen_input(buf, r, vcfd, pixels32, &fb);
            }
        }
    }

    free(buf);
    free(rpt_desc);
    close(touchfd);
    _zx_vmar_unmap(zx_vmar_root_self(), fbo, size);
    close(vcfd);
    return 0;
}
