/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 "config.h"
#include "keyboard.h"

/**
 * The X11 keysym for the dead key which types a grave (`).
 */
#define DEAD_GRAVE 0xFE50

/**
 * The X11 keysym for the dead key which types an acute (´). Note that this is
 * NOT equivalent to an apostrophe or single quote.
 */
#define DEAD_ACUTE 0xFE51

/**
 * The X11 keysym for the dead key which types a circumflex/caret (^).
 */
#define DEAD_CIRCUMFLEX 0xFE52

/**
 * The X11 keysym for the dead key which types a tilde (~).
 */
#define DEAD_TILDE 0xFE53

/**
 * The X11 keysym for the dead key which types a dieresis/umlaut (¨).
 */
#define DEAD_DIERESIS 0xFE57

/**
 * The X11 keysym for the dead key which types an abovering (˚). Note that this
 * is NOT equivalent to the degree symbol.
 */
#define DEAD_ABOVERING 0xFE58

/**
 * The decomposed form of a key that can be typed using two keypresses: a dead
 * key followed by a base key. For example, on a keyboard which lacks a single
 * dedicated key for doing the same, "ó" would be typed using the dead acute
 * key followed by the "o" key. The dead key and base key are pressed and
 * released in sequence; they are not held down.
 */
typedef struct guac_rdp_decomposed_key {

    /**
     * The keysym of the dead key which must first be pressed and released to
     * begin typing the desired character. The dead key defines the diacritic
     * which will be applied to the character typed by the base key.
     */
    int dead_keysym;

    /**
     * The keysym of the base key which must be pressed and released to finish
     * typing the desired character. The base key defines the normal form of
     * the character (the form which lacks any diacritic) to which the
     * diacritic defined by the previously-pressed dead key will be applied.
     */
    int base_keysym;

} guac_rdp_decomposed_key;

/**
 * A lookup table of all known decomposed forms of various keysyms. Keysyms map
 * directly to entries within this table. A keysym which has no entry within
 * this table does not have a defined decomposed form (or at least does not
 * have a decomposed form relevant to RDP).
 */
guac_rdp_decomposed_key guac_rdp_decomposed_keys[256] = {

    /* ^ */ [0x005E] = { DEAD_CIRCUMFLEX, ' ' },
    /* ` */ [0x0060] = { DEAD_GRAVE,      ' ' },
    /* ~ */ [0x007E] = { DEAD_TILDE,      ' ' },
    /* ¨ */ [0x00A8] = { DEAD_DIERESIS,   ' ' },
    /* ´ */ [0x00B4] = { DEAD_ACUTE,      ' ' },
    /* À */ [0x00C0] = { DEAD_GRAVE,      'A' },
    /* Á */ [0x00C1] = { DEAD_ACUTE,      'A' },
    /* Â */ [0x00C2] = { DEAD_CIRCUMFLEX, 'A' },
    /* Ã */ [0x00C3] = { DEAD_TILDE,      'A' },
    /* Ä */ [0x00C4] = { DEAD_DIERESIS,   'A' },
    /* Å */ [0x00C5] = { DEAD_ABOVERING,  'A' },
    /* È */ [0x00C8] = { DEAD_GRAVE,      'E' },
    /* É */ [0x00C9] = { DEAD_ACUTE,      'E' },
    /* Ê */ [0x00CA] = { DEAD_CIRCUMFLEX, 'E' },
    /* Ë */ [0x00CB] = { DEAD_DIERESIS,   'E' },
    /* Ì */ [0x00CC] = { DEAD_GRAVE,      'I' },
    /* Í */ [0x00CD] = { DEAD_ACUTE,      'I' },
    /* Î */ [0x00CE] = { DEAD_CIRCUMFLEX, 'I' },
    /* Ï */ [0x00CF] = { DEAD_DIERESIS,   'I' },
    /* Ñ */ [0x00D1] = { DEAD_TILDE,      'N' },
    /* Ò */ [0x00D2] = { DEAD_GRAVE,      'O' },
    /* Ó */ [0x00D3] = { DEAD_ACUTE,      'O' },
    /* Ô */ [0x00D4] = { DEAD_CIRCUMFLEX, 'O' },
    /* Õ */ [0x00D5] = { DEAD_TILDE,      'O' },
    /* Ö */ [0x00D6] = { DEAD_DIERESIS,   'O' },
    /* Ù */ [0x00D9] = { DEAD_GRAVE,      'U' },
    /* Ú */ [0x00DA] = { DEAD_ACUTE,      'U' },
    /* Û */ [0x00DB] = { DEAD_CIRCUMFLEX, 'U' },
    /* Ü */ [0x00DC] = { DEAD_DIERESIS,   'U' },
    /* Ý */ [0x00DD] = { DEAD_ACUTE,      'Y' },
    /* à */ [0x00E0] = { DEAD_GRAVE,      'a' },
    /* á */ [0x00E1] = { DEAD_ACUTE,      'a' },
    /* â */ [0x00E2] = { DEAD_CIRCUMFLEX, 'a' },
    /* ã */ [0x00E3] = { DEAD_TILDE,      'a' },
    /* ä */ [0x00E4] = { DEAD_DIERESIS,   'a' },
    /* å */ [0x00E5] = { DEAD_ABOVERING,  'a' },
    /* è */ [0x00E8] = { DEAD_GRAVE,      'e' },
    /* é */ [0x00E9] = { DEAD_ACUTE,      'e' },
    /* ê */ [0x00EA] = { DEAD_CIRCUMFLEX, 'e' },
    /* ë */ [0x00EB] = { DEAD_DIERESIS,   'e' },
    /* ì */ [0x00EC] = { DEAD_GRAVE,      'i' },
    /* í */ [0x00ED] = { DEAD_ACUTE,      'i' },
    /* î */ [0x00EE] = { DEAD_CIRCUMFLEX, 'i' },
    /* ï */ [0x00EF] = { DEAD_DIERESIS,   'i' },
    /* ñ */ [0x00F1] = { DEAD_TILDE,      'n' },
    /* ò */ [0x00F2] = { DEAD_GRAVE,      'o' },
    /* ó */ [0x00F3] = { DEAD_ACUTE,      'o' },
    /* ô */ [0x00F4] = { DEAD_CIRCUMFLEX, 'o' },
    /* õ */ [0x00F5] = { DEAD_TILDE,      'o' },
    /* ö */ [0x00F6] = { DEAD_DIERESIS,   'o' },
    /* ù */ [0x00F9] = { DEAD_GRAVE,      'u' },
    /* ú */ [0x00FA] = { DEAD_ACUTE,      'u' },
    /* û */ [0x00FB] = { DEAD_CIRCUMFLEX, 'u' },
    /* ü */ [0x00FC] = { DEAD_DIERESIS,   'u' },
    /* ý */ [0x00FD] = { DEAD_ACUTE,      'y' },
    /* ÿ */ [0x00FF] = { DEAD_DIERESIS,   'y' } 

};

int guac_rdp_decompose_keysym(guac_rdp_keyboard* keyboard, int keysym) {

    /* Verify keysym is within range of lookup table */
    if (keysym < 0x00 || keysym > 0xFF)
        return 1;

    /* Verify keysym is actually defined within lookup table */
    guac_rdp_decomposed_key* key = &guac_rdp_decomposed_keys[keysym];
    if (!key->dead_keysym)
        return 1;

    /* Cannot type using decomposed keys if those keys are not defined within
     * the current layout */
    if (!guac_rdp_keyboard_is_defined(keyboard, key->dead_keysym)
            || !guac_rdp_keyboard_is_defined(keyboard, key->base_keysym))
        return 1;

    /* Press dead key */
    guac_rdp_keyboard_send_event(keyboard, key->dead_keysym, 1);
    guac_rdp_keyboard_send_event(keyboard, key->dead_keysym, 0);

    /* Press base key */
    guac_rdp_keyboard_send_event(keyboard, key->base_keysym, 1);
    guac_rdp_keyboard_send_event(keyboard, key->base_keysym, 0);

    /* Decomposed key successfully typed */
    return 0;

}

