/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#ifdef HAVE_FCITX_FRONTEND_H

#include <fcitx/frontend.h>
#include <unistd.h>

#include "SDL_fcitx.h"
#include "SDL_keycode.h"
#include "SDL_keyboard.h"
#include "../../events/SDL_keyboard_c.h"
#include "SDL_dbus.h"
#include "SDL_syswm.h"
#if SDL_VIDEO_DRIVER_X11
#  include "../../video/x11/SDL_x11video.h"
#endif
#include "SDL_hints.h"

#define FCITX_DBUS_SERVICE "org.fcitx.Fcitx"

#define FCITX_IM_DBUS_PATH "/inputmethod"
#define FCITX_IC_DBUS_PATH "/inputcontext_%d"

#define FCITX_IM_DBUS_INTERFACE "org.fcitx.Fcitx.InputMethod"
#define FCITX_IC_DBUS_INTERFACE "org.fcitx.Fcitx.InputContext"

#define IC_NAME_MAX 64
#define DBUS_TIMEOUT 500

typedef struct _FcitxClient
{
    SDL_DBusContext *dbus;

    char servicename[IC_NAME_MAX];
    char icname[IC_NAME_MAX];

    int id;

    SDL_Rect cursor_rect;
} FcitxClient;

static FcitxClient fcitx_client;

static int
GetDisplayNumber()
{
    const char *display = SDL_getenv("DISPLAY");
    const char *p = NULL;
    int number = 0;

    if (display == NULL)
        return 0;

    display = SDL_strchr(display, ':');
    if (display == NULL)
        return 0;

    display++;
    p = SDL_strchr(display, '.');
    if (p == NULL && display != NULL) {
        number = SDL_strtod(display, NULL);
    } else {
        char *buffer = SDL_strdup(display);
        buffer[p - display] = '\0';
        number = SDL_strtod(buffer, NULL);
        SDL_free(buffer);
    }

    return number;
}

static char*
GetAppName()
{
#if defined(__LINUX__) || defined(__FREEBSD__)
    char *spot;
    char procfile[1024];
    char linkfile[1024];
    int linksize;

#if defined(__LINUX__)
    SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/exe", getpid());
#elif defined(__FREEBSD__)
    SDL_snprintf(procfile, sizeof(procfile), "/proc/%d/file", getpid());
#endif
    linksize = readlink(procfile, linkfile, sizeof(linkfile) - 1);
    if (linksize > 0) {
        linkfile[linksize] = '\0';
        spot = SDL_strrchr(linkfile, '/');
        if (spot) {
            return SDL_strdup(spot + 1);
        } else {
            return SDL_strdup(linkfile);
        }
    }
#endif /* __LINUX__ || __FREEBSD__ */

    return SDL_strdup("SDL_App");
}

/*
 * Copied from fcitx source
 */
#define CONT(i)   ISUTF8_CB(in[i])
#define VAL(i, s) ((in[i]&0x3f) << s)

static char *
_fcitx_utf8_get_char(const char *i, uint32_t *chr)
{
    const unsigned char* in = (const unsigned char *)i;
    if (!(in[0] & 0x80)) {
        *(chr) = *(in);
        return (char *)in + 1;
    }

    /* 2-byte, 0x80-0x7ff */
    if ((in[0] & 0xe0) == 0xc0 && CONT(1)) {
        *chr = ((in[0] & 0x1f) << 6) | VAL(1, 0);
        return (char *)in + 2;
    }

    /* 3-byte, 0x800-0xffff */
    if ((in[0] & 0xf0) == 0xe0 && CONT(1) && CONT(2)) {
        *chr = ((in[0] & 0xf) << 12) | VAL(1, 6) | VAL(2, 0);
        return (char *)in + 3;
    }

    /* 4-byte, 0x10000-0x1FFFFF */
    if ((in[0] & 0xf8) == 0xf0 && CONT(1) && CONT(2) && CONT(3)) {
        *chr = ((in[0] & 0x7) << 18) | VAL(1, 12) | VAL(2, 6) | VAL(3, 0);
        return (char *)in + 4;
    }

    /* 5-byte, 0x200000-0x3FFFFFF */
    if ((in[0] & 0xfc) == 0xf8 && CONT(1) && CONT(2) && CONT(3) && CONT(4)) {
        *chr = ((in[0] & 0x3) << 24) | VAL(1, 18) | VAL(2, 12) | VAL(3, 6) | VAL(4, 0);
        return (char *)in + 5;
    }

    /* 6-byte, 0x400000-0x7FFFFFF */
    if ((in[0] & 0xfe) == 0xfc && CONT(1) && CONT(2) && CONT(3) && CONT(4) && CONT(5)) {
        *chr = ((in[0] & 0x1) << 30) | VAL(1, 24) | VAL(2, 18) | VAL(3, 12) | VAL(4, 6) | VAL(5, 0);
        return (char *)in + 6;
    }

    *chr = *in;

    return (char *)in + 1;
}

static size_t
_fcitx_utf8_strlen(const char *s)
{
    unsigned int l = 0;

    while (*s) {
        uint32_t chr;

        s = _fcitx_utf8_get_char(s, &chr);
        l++;
    }

    return l;
}

static DBusHandlerResult
DBus_MessageFilter(DBusConnection *conn, DBusMessage *msg, void *data)
{
    SDL_DBusContext *dbus = (SDL_DBusContext *)data;

    if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "CommitString")) {
        DBusMessageIter iter;
        const char *text = NULL;

        dbus->message_iter_init(msg, &iter);
        dbus->message_iter_get_basic(&iter, &text);

        if (text)
            SDL_SendKeyboardText(text);

        return DBUS_HANDLER_RESULT_HANDLED;
    }

    if (dbus->message_is_signal(msg, FCITX_IC_DBUS_INTERFACE, "UpdatePreedit")) {
        DBusMessageIter iter;
        const char *text;

        dbus->message_iter_init(msg, &iter);
        dbus->message_iter_get_basic(&iter, &text);

        if (text && *text) {
            char buf[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
            size_t text_bytes = SDL_strlen(text), i = 0;
            size_t cursor = 0;

            while (i < text_bytes) {
                size_t sz = SDL_utf8strlcpy(buf, text + i, sizeof(buf));
                size_t chars = _fcitx_utf8_strlen(buf);

                SDL_SendEditingText(buf, cursor, chars);

                i += sz;
                cursor += chars;
            }
        }

        SDL_Fcitx_UpdateTextRect(NULL);
        return DBUS_HANDLER_RESULT_HANDLED;
    }

    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}

static DBusMessage*
FcitxClientICNewMethod(FcitxClient *client,
        const char *method)
{
    SDL_DBusContext *dbus = client->dbus;
    return dbus->message_new_method_call(
            client->servicename,
            client->icname,
            FCITX_IC_DBUS_INTERFACE,
            method);
}

static void
FcitxClientICCallMethod(FcitxClient *client,
        const char *method)
{
    SDL_DBusContext *dbus = client->dbus;
    DBusMessage *msg = FcitxClientICNewMethod(client, method);

    if (msg == NULL)
        return ;

    if (dbus->connection_send(dbus->session_conn, msg, NULL)) {
        dbus->connection_flush(dbus->session_conn);
    }

    dbus->message_unref(msg);
}

static void
Fcitx_SetCapabilities(void *data,
        const char *name,
        const char *old_val,
        const char *internal_editing)
{
    FcitxClient *client = (FcitxClient *)data;
    SDL_DBusContext *dbus = client->dbus;
    Uint32 caps = CAPACITY_NONE;

    DBusMessage *msg = FcitxClientICNewMethod(client, "SetCapacity");
    if (msg == NULL)
        return ;

    if (!(internal_editing && *internal_editing == '1')) {
        caps |= CAPACITY_PREEDIT;
    }

    dbus->message_append_args(msg,
            DBUS_TYPE_UINT32, &caps,
            DBUS_TYPE_INVALID);
    if (dbus->connection_send(dbus->session_conn, msg, NULL)) {
        dbus->connection_flush(dbus->session_conn);
    }

    dbus->message_unref(msg);
}

static void
FcitxClientCreateIC(FcitxClient *client)
{
    char *appname = NULL;
    pid_t pid = 0;
    int id = 0;
    SDL_bool enable;
    Uint32 arg1, arg2, arg3, arg4;

    SDL_DBusContext *dbus = client->dbus;
    DBusMessage *reply = NULL;
    DBusMessage *msg = dbus->message_new_method_call(
            client->servicename,
            FCITX_IM_DBUS_PATH,
            FCITX_IM_DBUS_INTERFACE,
            "CreateICv3"
            );

    if (msg == NULL)
        return ;

    appname = GetAppName();
    pid = getpid();
    dbus->message_append_args(msg,
            DBUS_TYPE_STRING, &appname,
            DBUS_TYPE_INT32, &pid,
            DBUS_TYPE_INVALID);

    do {
        reply = dbus->connection_send_with_reply_and_block(
                dbus->session_conn,
                msg,
                DBUS_TIMEOUT,
                NULL);

        if (!reply)
            break;
        if (!dbus->message_get_args(reply, NULL,
                DBUS_TYPE_INT32, &id,
                DBUS_TYPE_BOOLEAN, &enable,
                DBUS_TYPE_UINT32, &arg1,
                DBUS_TYPE_UINT32, &arg2,
                DBUS_TYPE_UINT32, &arg3,
                DBUS_TYPE_UINT32, &arg4,
                DBUS_TYPE_INVALID))
            break;

        if (id < 0)
            break;
        client->id = id;

        SDL_snprintf(client->icname, IC_NAME_MAX,
                FCITX_IC_DBUS_PATH, client->id);

        dbus->bus_add_match(dbus->session_conn,
                "type='signal', interface='org.fcitx.Fcitx.InputContext'",
                NULL);
        dbus->connection_add_filter(dbus->session_conn,
                &DBus_MessageFilter, dbus,
                NULL);
        dbus->connection_flush(dbus->session_conn);

        SDL_AddHintCallback(SDL_HINT_IME_INTERNAL_EDITING, &Fcitx_SetCapabilities, client);
    }
    while (0);

    if (reply)
        dbus->message_unref(reply);
    dbus->message_unref(msg);
    SDL_free(appname);
}

static Uint32
Fcitx_ModState(void)
{
    Uint32 fcitx_mods = 0;
    SDL_Keymod sdl_mods = SDL_GetModState();

    if (sdl_mods & KMOD_SHIFT) fcitx_mods |= FcitxKeyState_Shift;
    if (sdl_mods & KMOD_CAPS)   fcitx_mods |= FcitxKeyState_CapsLock;
    if (sdl_mods & KMOD_CTRL)  fcitx_mods |= FcitxKeyState_Ctrl;
    if (sdl_mods & KMOD_ALT)   fcitx_mods |= FcitxKeyState_Alt;
    if (sdl_mods & KMOD_NUM)    fcitx_mods |= FcitxKeyState_NumLock;
    if (sdl_mods & KMOD_LGUI)   fcitx_mods |= FcitxKeyState_Super;
    if (sdl_mods & KMOD_RGUI)   fcitx_mods |= FcitxKeyState_Meta;

    return fcitx_mods;
}

SDL_bool
SDL_Fcitx_Init()
{
    fcitx_client.dbus = SDL_DBus_GetContext();

    fcitx_client.cursor_rect.x = -1;
    fcitx_client.cursor_rect.y = -1;
    fcitx_client.cursor_rect.w = 0;
    fcitx_client.cursor_rect.h = 0;

    SDL_snprintf(fcitx_client.servicename, IC_NAME_MAX,
            "%s-%d",
            FCITX_DBUS_SERVICE, GetDisplayNumber());

    FcitxClientCreateIC(&fcitx_client);

    return SDL_TRUE;
}

void
SDL_Fcitx_Quit()
{
    FcitxClientICCallMethod(&fcitx_client, "DestroyIC");
}

void
SDL_Fcitx_SetFocus(SDL_bool focused)
{
    if (focused) {
        FcitxClientICCallMethod(&fcitx_client, "FocusIn");
    } else {
        FcitxClientICCallMethod(&fcitx_client, "FocusOut");
    }
}

void
SDL_Fcitx_Reset(void)
{
    FcitxClientICCallMethod(&fcitx_client, "Reset");
    FcitxClientICCallMethod(&fcitx_client, "CloseIC");
}

SDL_bool
SDL_Fcitx_ProcessKeyEvent(Uint32 keysym, Uint32 keycode)
{
    DBusMessage *msg = NULL;
    DBusMessage *reply = NULL;
    SDL_DBusContext *dbus = fcitx_client.dbus;

    Uint32 state = 0;
    SDL_bool handled = SDL_FALSE;
    int type = FCITX_PRESS_KEY;
    Uint32 event_time = 0;

    msg = FcitxClientICNewMethod(&fcitx_client, "ProcessKeyEvent");
    if (msg == NULL)
        return SDL_FALSE;

    state = Fcitx_ModState();
    dbus->message_append_args(msg,
            DBUS_TYPE_UINT32, &keysym,
            DBUS_TYPE_UINT32, &keycode,
            DBUS_TYPE_UINT32, &state,
            DBUS_TYPE_INT32, &type,
            DBUS_TYPE_UINT32, &event_time,
            DBUS_TYPE_INVALID);

    reply = dbus->connection_send_with_reply_and_block(dbus->session_conn,
            msg,
            -1,
            NULL);

    if (reply) {
        dbus->message_get_args(reply,
                NULL,
                DBUS_TYPE_INT32, &handled,
                DBUS_TYPE_INVALID);

        dbus->message_unref(reply);
    }

    if (handled) {
        SDL_Fcitx_UpdateTextRect(NULL);
    }

    return handled;
}

void
SDL_Fcitx_UpdateTextRect(SDL_Rect *rect)
{
    SDL_Window *focused_win = NULL;
    SDL_SysWMinfo info;
    int x = 0, y = 0;
    SDL_Rect *cursor = &fcitx_client.cursor_rect;

    SDL_DBusContext *dbus = fcitx_client.dbus;
    DBusMessage *msg = NULL;
    DBusConnection *conn;

    if (rect) {
        SDL_memcpy(cursor, rect, sizeof(SDL_Rect));
    }

    focused_win = SDL_GetKeyboardFocus();
    if (!focused_win) {
        return ;
    }

    SDL_VERSION(&info.version);
    if (!SDL_GetWindowWMInfo(focused_win, &info)) {
        return;
    }

    SDL_GetWindowPosition(focused_win, &x, &y);

#if SDL_VIDEO_DRIVER_X11
    if (info.subsystem == SDL_SYSWM_X11) {
        SDL_DisplayData *displaydata = (SDL_DisplayData *) SDL_GetDisplayForWindow(focused_win)->driverdata;

        Display *x_disp = info.info.x11.display;
        Window x_win = info.info.x11.window;
        int x_screen = displaydata->screen;
        Window unused;
        X11_XTranslateCoordinates(x_disp, x_win, RootWindow(x_disp, x_screen), 0, 0, &x, &y, &unused);
    }
#endif

    if (cursor->x == -1 && cursor->y == -1 && cursor->w == 0 && cursor->h == 0) {
        // move to bottom left
        int w = 0, h = 0;
        SDL_GetWindowSize(focused_win, &w, &h);
        cursor->x = 0;
        cursor->y = h;
    }

    x += cursor->x;
    y += cursor->y;

    msg = FcitxClientICNewMethod(&fcitx_client, "SetCursorRect");
    if (msg == NULL)
        return ;

    dbus->message_append_args(msg,
            DBUS_TYPE_INT32, &x,
            DBUS_TYPE_INT32, &y,
            DBUS_TYPE_INT32, &cursor->w,
            DBUS_TYPE_INT32, &cursor->h,
            DBUS_TYPE_INVALID);

    conn = dbus->session_conn;
    if (dbus->connection_send(conn, msg, NULL))
        dbus->connection_flush(conn);

    dbus->message_unref(msg);
}

void
SDL_Fcitx_PumpEvents()
{
    SDL_DBusContext *dbus = fcitx_client.dbus;
    DBusConnection *conn = dbus->session_conn;

    dbus->connection_read_write(conn, 0);

    while (dbus->connection_dispatch(conn) == DBUS_DISPATCH_DATA_REMAINS) {
        /* Do nothing, actual work happens in DBus_MessageFilter */
        usleep(10);
    }
}

#endif /* HAVE_FCITX_FRONTEND_H */

/* vi: set ts=4 sw=4 expandtab: */
