/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "android/skin/keyboard.h"
#include "android/utils/debug.h"
#include "android/utils/bufprint.h"
#include "android/utils/system.h"
#include "android/android.h"

#define  DEBUG  1

#if DEBUG
#  define  D(...)  VERBOSE_PRINT(keys,__VA_ARGS__)
#else
#  define  D(...)  ((void)0)
#endif


/** LAST PRESSED KEYS
 ** a small buffer of last pressed keys, this is used to properly
 ** implement the Unicode keyboard mode (SDL key up event always have
 ** their .unicode field set to 0
 **/
typedef struct {
    int  unicode;  /* Unicode of last pressed key        */
    int  sym;      /* SDL key symbol value (e.g. SDLK_a) */
    int  mod;      /* SDL key modifier value             */
} LastKey;

#define  MAX_LAST_KEYS  16
#define  MAX_KEYCODES   256*2

struct SkinKeyboard {
    const AKeyCharmap*  charmap;
    SkinKeyset*         kset;
    char                enabled;
    char                raw_keys;
    char                last_count;
    int                 keycode_count;

    SkinRotation        rotation;

    SkinKeyCommandFunc  command_func;
    void*               command_opaque;
    SkinKeyEventFunc    press_func;
    void*               press_opaque;

    LastKey             last_keys[ MAX_LAST_KEYS ];
    int                 keycodes[ MAX_KEYCODES ];
};


void
skin_keyboard_set_keyset( SkinKeyboard*  keyboard, SkinKeyset*  kset )
{
    if (kset == NULL)
        return;
    if (keyboard->kset && keyboard->kset != android_keyset) {
        skin_keyset_free(keyboard->kset);
    }
    keyboard->kset = kset;
}


const char*
skin_keyboard_charmap_name( SkinKeyboard*  keyboard )
{
    if (keyboard && keyboard->charmap)
        return keyboard->charmap->name;

    return "qwerty";
}

void
skin_keyboard_set_rotation( SkinKeyboard*     keyboard,
                            SkinRotation      rotation )
{
    keyboard->rotation = (rotation & 3);
}

void
skin_keyboard_on_command( SkinKeyboard*  keyboard, SkinKeyCommandFunc  cmd_func, void*  cmd_opaque )
{
    keyboard->command_func   = cmd_func;
    keyboard->command_opaque = cmd_opaque;
}

void
skin_keyboard_on_key_press( SkinKeyboard*  keyboard, SkinKeyEventFunc  press_func, void*  press_opaque )
{
    keyboard->press_func   = press_func;
    keyboard->press_opaque = press_opaque;
}

void
skin_keyboard_add_key_event( SkinKeyboard*  kb,
                             unsigned       code,
                             unsigned       down )
{
    if (code != 0 && kb->keycode_count < MAX_KEYCODES) {
        //dprint("add keycode %d, down %d\n", code % 0x1ff, down );
        kb->keycodes[(int)kb->keycode_count++] = ( (code & 0x1ff) | (down ? 0x200 : 0) );
    }
}


void
skin_keyboard_flush( SkinKeyboard*  kb )
{
    if (kb->keycode_count > 0) {
        if (VERBOSE_CHECK(keys)) {
            int  nn;
            printf(">> KEY" );
            for (nn = 0; nn < kb->keycode_count; nn++) {
                int  code = kb->keycodes[nn];
                printf(" [0x%03x,%s]", (code & 0x1ff), (code & 0x200) ? "down" : " up " );
            }
            printf( "\n" );
        }
        kbd_put_keycodes(kb->keycodes, kb->keycode_count);
        kb->keycode_count = 0;
    }
}


static void
skin_keyboard_cmd( SkinKeyboard*   keyboard,
                   SkinKeyCommand  command,
                   int             param )
{
    if (keyboard->command_func) {
        keyboard->command_func( keyboard->command_opaque, command, param );
    }
}


static LastKey*
skin_keyboard_find_last( SkinKeyboard*  keyboard,
                         int            sym )
{
    LastKey*  k   = keyboard->last_keys;
    LastKey*  end = k + keyboard->last_count;

    for ( ; k < end; k++ ) {
        if (k->sym == sym)
            return k;
    }
    return NULL;
}

static void
skin_keyboard_add_last( SkinKeyboard*  keyboard,
                        int            sym,
                        int            mod,
                        int            unicode )
{
    LastKey*  k = keyboard->last_keys + keyboard->last_count;

    if (keyboard->last_count < MAX_LAST_KEYS) {
        k->sym     = sym;
        k->mod     = mod;
        k->unicode = unicode;

        keyboard->last_count += 1;
    }
}

static void
skin_keyboard_remove_last( SkinKeyboard*  keyboard,
                           int            sym )
{
    LastKey*  k   = keyboard->last_keys;
    LastKey*  end = k + keyboard->last_count;

    for ( ; k < end; k++ ) {
        if (k->sym == sym) {
           /* we don't need a sorted array, so place the last
            * element in place at the position of the removed
            * one... */
            k[0] = end[-1];
            keyboard->last_count -= 1;
            break;
        }
    }
}

static void
skin_keyboard_clear_last( SkinKeyboard*  keyboard )
{
    keyboard->last_count = 0;
}

static int
skin_keyboard_rotate_sym( SkinKeyboard*  keyboard,
                          int            sym )
{
    switch (keyboard->rotation) {
        case SKIN_ROTATION_90:
            switch (sym) {
                case SDLK_LEFT:  sym = SDLK_DOWN; break;
                case SDLK_RIGHT: sym = SDLK_UP; break;
                case SDLK_UP:    sym = SDLK_LEFT; break;
                case SDLK_DOWN:  sym = SDLK_RIGHT; break;
            }
            break;

        case SKIN_ROTATION_180:
            switch (sym) {
                case SDLK_LEFT:  sym = SDLK_RIGHT; break;
                case SDLK_RIGHT: sym = SDLK_LEFT; break;
                case SDLK_UP:    sym = SDLK_DOWN; break;
                case SDLK_DOWN:  sym = SDLK_UP; break;
            }
            break;

        case SKIN_ROTATION_270:
            switch (sym) {
                case SDLK_LEFT:  sym = SDLK_UP; break;
                case SDLK_RIGHT: sym = SDLK_DOWN; break;
                case SDLK_UP:    sym = SDLK_RIGHT; break;
                case SDLK_DOWN:  sym = SDLK_LEFT; break;
            }
            break;

        default: ;
    }
    return  sym;
}

static AndroidKeyCode
skin_keyboard_key_to_code( SkinKeyboard*  keyboard,
                           unsigned       sym,
                           int            mod,
                           int            down )
{
    AndroidKeyCode  code   = 0;
    int             mod0   = mod;
    SkinKeyCommand  command;

    /* first, handle the arrow keys directly */
    /* rotate them if necessary */
    sym  = skin_keyboard_rotate_sym(keyboard, sym);
    mod &= (KMOD_CTRL | KMOD_ALT | KMOD_SHIFT);

    switch (sym) {
        case SDLK_LEFT:       code = kKeyCodeDpadLeft; break;
        case SDLK_RIGHT:      code = kKeyCodeDpadRight; break;
        case SDLK_UP:         code = kKeyCodeDpadUp; break;
        case SDLK_DOWN:       code = kKeyCodeDpadDown; break;
        default: ;
    }

    if (code != 0) {
        D("handling arrow (sym=%d mod=%d)", sym, mod);
        if (!keyboard->raw_keys) {
            int  doCapL, doCapR, doAltL, doAltR;

            if (!down) {
                LastKey*  k = skin_keyboard_find_last(keyboard, sym);
                if (k != NULL) {
                    mod = k->mod;
                    skin_keyboard_remove_last( keyboard, sym );
                }
            } else {
                skin_keyboard_add_last( keyboard, sym, mod, 0);
            }

            doCapL = (mod & 0x7ff) & KMOD_LSHIFT;
            doCapR = (mod & 0x7ff) & KMOD_RSHIFT;
            doAltL = (mod & 0x7ff) & KMOD_LALT;
            doAltR = (mod & 0x7ff) & KMOD_RALT;

            if (down) {
                if (doAltL) skin_keyboard_add_key_event( keyboard, kKeyCodeAltLeft, 1 );
                if (doAltR) skin_keyboard_add_key_event( keyboard, kKeyCodeAltRight, 1 );
                if (doCapL) skin_keyboard_add_key_event( keyboard, kKeyCodeCapLeft, 1 );
                if (doCapR) skin_keyboard_add_key_event( keyboard, kKeyCodeCapRight, 1 );
            }
            skin_keyboard_add_key_event(keyboard, code, down);

            if (!down) {
                if (doCapR) skin_keyboard_add_key_event( keyboard, kKeyCodeCapRight, 0 );
                if (doCapL) skin_keyboard_add_key_event( keyboard, kKeyCodeCapLeft, 0 );
                if (doAltR) skin_keyboard_add_key_event( keyboard, kKeyCodeAltRight, 0 );
                if (doAltL) skin_keyboard_add_key_event( keyboard, kKeyCodeAltLeft, 0 );
            }
            code = 0;
        }
        return code;
    }

    /* special case for keypad keys, ignore them here if numlock is on */
    if ((mod0 & KMOD_NUM) != 0) {
        switch (sym) {
            case SDLK_KP0:
            case SDLK_KP1:
            case SDLK_KP2:
            case SDLK_KP3:
            case SDLK_KP4:
            case SDLK_KP5:
            case SDLK_KP6:
            case SDLK_KP7:
            case SDLK_KP8:
            case SDLK_KP9:
            case SDLK_KP_PLUS:
            case SDLK_KP_MINUS:
            case SDLK_KP_MULTIPLY:
            case SDLK_KP_DIVIDE:
            case SDLK_KP_EQUALS:
            case SDLK_KP_PERIOD:
            case SDLK_KP_ENTER:
                return 0;
        }
    }

    /* now try all keyset combos */
    command = skin_keyset_get_command( keyboard->kset, sym, mod );
    if (command != SKIN_KEY_COMMAND_NONE) {
        D("handling command %s from (sym=%d, mod=%d, str=%s)",
          skin_key_command_to_str(command), sym, mod, skin_key_symmod_to_str(sym,mod));
        skin_keyboard_cmd( keyboard, command, down );
        return 0;
    }
    D("could not handle (sym=%d, mod=%d, str=%s)", sym, mod,
      skin_key_symmod_to_str(sym,mod));
    return -1;
}

/* this gets called only if the reverse unicode mapping didn't work
 * or wasn't used (when in raw keys mode)
 */
static AndroidKeyCode
skin_keyboard_raw_key_to_code(SkinKeyboard*  kb, unsigned sym, int  down)
{
    switch(sym){
    case SDLK_1:          return kKeyCode1;
    case SDLK_2:          return kKeyCode2;
    case SDLK_3:          return kKeyCode3;
    case SDLK_4:          return kKeyCode4;
    case SDLK_5:          return kKeyCode5;
    case SDLK_6:          return kKeyCode6;
    case SDLK_7:          return kKeyCode7;
    case SDLK_8:          return kKeyCode8;
    case SDLK_9:          return kKeyCode9;
    case SDLK_0:          return kKeyCode0;

    case SDLK_q:          return kKeyCodeQ;
    case SDLK_w:          return kKeyCodeW;
    case SDLK_e:          return kKeyCodeE;
    case SDLK_r:          return kKeyCodeR;
    case SDLK_t:          return kKeyCodeT;
    case SDLK_y:          return kKeyCodeY;
    case SDLK_u:          return kKeyCodeU;
    case SDLK_i:          return kKeyCodeI;
    case SDLK_o:          return kKeyCodeO;
    case SDLK_p:          return kKeyCodeP;
    case SDLK_a:          return kKeyCodeA;
    case SDLK_s:          return kKeyCodeS;
    case SDLK_d:          return kKeyCodeD;
    case SDLK_f:          return kKeyCodeF;
    case SDLK_g:          return kKeyCodeG;
    case SDLK_h:          return kKeyCodeH;
    case SDLK_j:          return kKeyCodeJ;
    case SDLK_k:          return kKeyCodeK;
    case SDLK_l:          return kKeyCodeL;
    case SDLK_z:          return kKeyCodeZ;
    case SDLK_x:          return kKeyCodeX;
    case SDLK_c:          return kKeyCodeC;
    case SDLK_v:          return kKeyCodeV;
    case SDLK_b:          return kKeyCodeB;
    case SDLK_n:          return kKeyCodeN;
    case SDLK_m:          return kKeyCodeM;
    case SDLK_COMMA:      return kKeyCodeComma;
    case SDLK_PERIOD:     return kKeyCodePeriod;
    case SDLK_SPACE:      return kKeyCodeSpace;
    case SDLK_SLASH:      return kKeyCodeSlash;
    case SDLK_RETURN:     return kKeyCodeNewline;
    case SDLK_BACKSPACE:  return kKeyCodeDel;

/* these are qwerty keys not on a device keyboard */
    case SDLK_TAB:        return kKeyCodeTab;
    case SDLK_BACKQUOTE:  return kKeyCodeGrave;
    case SDLK_MINUS:      return kKeyCodeMinus;
    case SDLK_EQUALS:     return kKeyCodeEquals;
    case SDLK_LEFTBRACKET: return kKeyCodeLeftBracket;
    case SDLK_RIGHTBRACKET: return kKeyCodeRightBracket;
    case SDLK_BACKSLASH:  return kKeyCodeBackslash;
    case SDLK_SEMICOLON:  return kKeyCodeSemicolon;
    case SDLK_QUOTE:      return kKeyCodeApostrophe;

    case SDLK_RSHIFT:     return kKeyCodeCapRight;
    case SDLK_LSHIFT:     return kKeyCodeCapLeft;
    case SDLK_RMETA:      return kKeyCodeSym;
    case SDLK_LMETA:      return kKeyCodeSym;
    case SDLK_RALT:       return kKeyCodeAltRight;
    case SDLK_LALT:       return kKeyCodeAltLeft;
    case SDLK_RCTRL:      return kKeyCodeSym;
    case SDLK_LCTRL:      return kKeyCodeSym;

    default:
        /* fprintf(stderr,"* unknown sdl keysym %d *\n", sym); */
        return -1;
    }
}


static void
skin_keyboard_do_key_event( SkinKeyboard*   kb,
                            AndroidKeyCode  code,
                            int             down )
{
    if (kb->press_func) {
        kb->press_func( kb->press_opaque, code, down );
    }
    skin_keyboard_add_key_event(kb, code, down);
}


int
skin_keyboard_process_unicode_event( SkinKeyboard*  kb,  unsigned int  unicode, int  down )
{
    const AKeyCharmap*  cmap = kb->charmap;
    int                 n;

    if (unicode == 0)
        return 0;

    /* check base keys */
    for (n = 0; n < cmap->num_entries; n++) {
        if (cmap->entries[n].base == unicode) {
            skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
            return 1;
        }
    }

    /* check caps + keys */
    for (n = 0; n < cmap->num_entries; n++) {
        if (cmap->entries[n].caps == unicode) {
            if (down)
                skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
            skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
            if (!down)
                skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
            return 2;
        }
    }

    /* check fn + keys */
    for (n = 0; n < cmap->num_entries; n++) {
        if (cmap->entries[n].fn == unicode) {
            if (down)
                skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
            skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
            if (!down)
                skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
            return 2;
        }
    }

    /* check caps + fn + keys */
    for (n = 0; n < cmap->num_entries; n++) {
        if (cmap->entries[n].caps_fn == unicode) {
            if (down) {
                skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
                skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
            }
            skin_keyboard_add_key_event(kb, cmap->entries[n].code, down);
            if (!down) {
                skin_keyboard_add_key_event(kb, kKeyCodeCapLeft, down);
                skin_keyboard_add_key_event(kb, kKeyCodeAltLeft, down);
            }
            return 3;
        }
    }

    /* no match */
    return 0;
}


void
skin_keyboard_enable( SkinKeyboard*  keyboard,
                      int            enabled )
{
    keyboard->enabled = enabled;
    if (enabled) {
        SDL_EnableUNICODE(!keyboard->raw_keys);
        SDL_EnableKeyRepeat(0,0);
    }
}

void
skin_keyboard_process_event( SkinKeyboard*  kb, SDL_Event*  ev, int  down )
{
    unsigned         code;
    int              unicode = ev->key.keysym.unicode;
    int              sym     = ev->key.keysym.sym;
    int              mod     = ev->key.keysym.mod;

    /* ignore key events if we're not enabled */
    if (!kb->enabled) {
        printf( "ignoring key event sym=%d mod=0x%x unicode=%d\n",
                sym, mod, unicode );
        return;
    }

    /* first, try the keyboard-mode-independent keys */
    code = skin_keyboard_key_to_code( kb, sym, mod, down );
    if (code == 0)
        return;

    if ((int)code > 0) {
        skin_keyboard_do_key_event(kb, code, down);
        skin_keyboard_flush(kb);
        return;
    }

    /* Ctrl-K is used to switch between 'unicode' and 'raw' modes */
    if (sym == SDLK_k)
    {
        int  mod2 = mod & 0x7ff;

        if ( mod2 == KMOD_LCTRL || mod2 == KMOD_RCTRL ) {
            if (down) {
                skin_keyboard_clear_last(kb);
                kb->raw_keys = !kb->raw_keys;
                SDL_EnableUNICODE(!kb->raw_keys);
                D( "switching keyboard to %s mode", kb->raw_keys ? "raw" : "unicode" );
            }
            return;
        }
    }

    if (!kb->raw_keys) {
       /* ev->key.keysym.unicode is only valid on keydown events, and will be 0
        * on the corresponding keyup ones, so remember the set of last pressed key
        * syms to "undo" the job
        */
        if ( !down && unicode == 0 ) {
            LastKey*  k = skin_keyboard_find_last(kb, sym);
            if (k != NULL) {
                unicode = k->unicode;
                skin_keyboard_remove_last(kb, sym);
            }
        }
    }
    if (!kb->raw_keys &&
        skin_keyboard_process_unicode_event( kb, unicode, down ) > 0)
    {
        if (down)
            skin_keyboard_add_last( kb, sym, mod, unicode );

        skin_keyboard_flush( kb );
        return;
    }

    code = skin_keyboard_raw_key_to_code( kb, sym, down );

    if ( !kb->raw_keys &&
         (code == kKeyCodeAltLeft  || code == kKeyCodeAltRight ||
          code == kKeyCodeCapLeft  || code == kKeyCodeCapRight ||
          code == kKeyCodeSym) )
        return;

    if (code == -1) {
        D("ignoring keysym %d", sym );
    } else if (code > 0) {
        skin_keyboard_do_key_event(kb, code, down);
        skin_keyboard_flush(kb);
    }
}

static SkinKeyboard*
skin_keyboard_create_from_charmap_name(const char*  charmap_name,
                                       int  use_raw_keys)
{
    SkinKeyboard*  kb;
    int  nn;

    ANEW0(kb);

    // Find charmap by its name in the array of available charmaps.
    for (nn = 0; nn < android_charmap_count; nn++) {
        if (!strcmp(android_charmaps[nn]->name, charmap_name)) {
            kb->charmap = android_charmaps[nn];
            break;
        }
    }

    if (!kb->charmap) {
        // Charmap name was not found. Default to the first charmap in the array.
        fprintf(stderr, "### warning, skin requires unknown '%s' charmap, reverting to '%s'\n",
                charmap_name, android_charmaps[0]->name );
        kb->charmap = android_charmaps[0];
    }
    kb->raw_keys = use_raw_keys;
    kb->enabled  = 0;

    /* add default keyset */
    if (android_keyset)
        kb->kset = android_keyset;
    else
        kb->kset = skin_keyset_new_from_text( skin_keyset_get_default() );

    return kb;
}

SkinKeyboard*
skin_keyboard_create_from_aconfig( AConfig*  aconfig, int  use_raw_keys )
{
    const char*    charmap_name = "qwerty";
    AConfig*       node = aconfig_find( aconfig, "keyboard" );
    if (node != NULL) {
        charmap_name = aconfig_str(node, "charmap", charmap_name);
    }
    return skin_keyboard_create_from_charmap_name(charmap_name, use_raw_keys);
}

SkinKeyboard*
skin_keyboard_create_from_kcm( const char*  kcm_file_path, int  use_raw_keys )
{
    char charmap_name[AKEYCHARMAP_NAME_SIZE];
    kcm_extract_charmap_name(kcm_file_path, charmap_name,
                             sizeof(charmap_name));
    return skin_keyboard_create_from_charmap_name(charmap_name, use_raw_keys);
}

void
skin_keyboard_free( SkinKeyboard*  keyboard )
{
    if (keyboard) {
        AFREE(keyboard);
    }
}
