/*
 * Copyright (c) 2024 Florian "sp1rit" <sp1rit@disroot.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 */

#pragma once

#include <gdk/gdk.h>

#include <android/keycodes.h>

inline static guint
gdk_android_keysyms_translate_keycode (gint32 keycode)
{
  switch (keycode)
    {
    case AKEYCODE_BACK:
      return GDK_KEY_Back;
    case AKEYCODE_0:
      return GDK_KEY_0;
    case AKEYCODE_1:
      return GDK_KEY_1;
    case AKEYCODE_2:
      return GDK_KEY_2;
    case AKEYCODE_3:
      return GDK_KEY_3;
    case AKEYCODE_4:
      return GDK_KEY_4;
    case AKEYCODE_5:
      return GDK_KEY_5;
    case AKEYCODE_6:
      return GDK_KEY_6;
    case AKEYCODE_7:
      return GDK_KEY_7;
    case AKEYCODE_8:
      return GDK_KEY_8;
    case AKEYCODE_9:
      return GDK_KEY_9;
    case AKEYCODE_STAR:
      return GDK_KEY_asterisk;
    case AKEYCODE_POUND:
      return GDK_KEY_numbersign;
    case AKEYCODE_DPAD_UP:
      return GDK_KEY_Up;
    case AKEYCODE_DPAD_DOWN:
      return GDK_KEY_Down;
    case AKEYCODE_DPAD_LEFT:
      return GDK_KEY_Left;
    case AKEYCODE_DPAD_RIGHT:
      return GDK_KEY_Right;
      /*case AKEYCODE_DPAD_CENTER:
          return GDK_KEY_VoidSymbol;*/
    case AKEYCODE_VOLUME_UP:
      return GDK_KEY_AudioRaiseVolume;
    case AKEYCODE_VOLUME_DOWN:
      return GDK_KEY_AudioLowerVolume;
    case AKEYCODE_POWER:
      return GDK_KEY_Suspend;
    case AKEYCODE_CAMERA:
      return GDK_KEY_WebCam;
    case AKEYCODE_CLEAR:
      return GDK_KEY_Clear;
    case AKEYCODE_A:
      return GDK_KEY_a;
    case AKEYCODE_B:
      return GDK_KEY_b;
    case AKEYCODE_C:
      return GDK_KEY_c;
    case AKEYCODE_D:
      return GDK_KEY_d;
    case AKEYCODE_E:
      return GDK_KEY_e;
    case AKEYCODE_F:
      return GDK_KEY_f;
    case AKEYCODE_G:
      return GDK_KEY_g;
    case AKEYCODE_H:
      return GDK_KEY_h;
    case AKEYCODE_I:
      return GDK_KEY_i;
    case AKEYCODE_J:
      return GDK_KEY_j;
    case AKEYCODE_K:
      return GDK_KEY_k;
    case AKEYCODE_L:
      return GDK_KEY_l;
    case AKEYCODE_M:
      return GDK_KEY_m;
    case AKEYCODE_N:
      return GDK_KEY_n;
    case AKEYCODE_O:
      return GDK_KEY_o;
    case AKEYCODE_P:
      return GDK_KEY_p;
    case AKEYCODE_Q:
      return GDK_KEY_q;
    case AKEYCODE_R:
      return GDK_KEY_r;
    case AKEYCODE_S:
      return GDK_KEY_s;
    case AKEYCODE_T:
      return GDK_KEY_t;
    case AKEYCODE_U:
      return GDK_KEY_u;
    case AKEYCODE_V:
      return GDK_KEY_v;
    case AKEYCODE_W:
      return GDK_KEY_w;
    case AKEYCODE_X:
      return GDK_KEY_x;
    case AKEYCODE_Y:
      return GDK_KEY_y;
    case AKEYCODE_Z:
      return GDK_KEY_z;
    case AKEYCODE_COMMA:
      return GDK_KEY_comma;
    case AKEYCODE_PERIOD:
      return GDK_KEY_period;
    case AKEYCODE_ALT_LEFT:
      return GDK_KEY_Alt_L;
    case AKEYCODE_ALT_RIGHT:
      return GDK_KEY_Alt_R;
    case AKEYCODE_SHIFT_LEFT:
      return GDK_KEY_Shift_L;
    case AKEYCODE_SHIFT_RIGHT:
      return GDK_KEY_Shift_R;
    case AKEYCODE_TAB:
      return GDK_KEY_Tab;
    case AKEYCODE_SPACE:
      return GDK_KEY_space;
    case AKEYCODE_EXPLORER:
      return GDK_KEY_Explorer;
    case AKEYCODE_ENVELOPE:
      return GDK_KEY_Mail;
    case AKEYCODE_ENTER:
      return GDK_KEY_Return;
    case AKEYCODE_DEL:
      return GDK_KEY_BackSpace;
    case AKEYCODE_GRAVE:
      return GDK_KEY_grave;
    case AKEYCODE_MINUS:
      return GDK_KEY_minus;
    case AKEYCODE_EQUALS:
      return GDK_KEY_equal;
    case AKEYCODE_LEFT_BRACKET:
      return GDK_KEY_bracketleft;
    case AKEYCODE_RIGHT_BRACKET:
      return GDK_KEY_bracketright;
    case AKEYCODE_BACKSLASH:
      return GDK_KEY_backslash;
    case AKEYCODE_SEMICOLON:
      return GDK_KEY_semicolon;
    case AKEYCODE_APOSTROPHE:
      return GDK_KEY_apostrophe;
    case AKEYCODE_SLASH:
      return GDK_KEY_slash;
    case AKEYCODE_AT:
      return GDK_KEY_at;
    case AKEYCODE_NUM: // Number modifier key (not numlock)
      return GDK_KEY_Alt_L;
    case AKEYCODE_PLUS:
      return GDK_KEY_plus;
    case AKEYCODE_MENU:
      return GDK_KEY_Menu;
    case AKEYCODE_SEARCH:
      return GDK_KEY_Search;
    case AKEYCODE_MEDIA_PLAY_PAUSE:
      return GDK_KEY_AudioMedia; // is that correct?
    case AKEYCODE_MEDIA_STOP:
      return GDK_KEY_AudioStop;
    case AKEYCODE_MEDIA_NEXT:
      return GDK_KEY_AudioNext;
    case AKEYCODE_MEDIA_PREVIOUS:
      return GDK_KEY_AudioPrev;
    case AKEYCODE_MEDIA_REWIND:
      return GDK_KEY_AudioRewind;
    case AKEYCODE_MEDIA_FAST_FORWARD:
      return GDK_KEY_AudioForward;
    case AKEYCODE_MUTE:
      return GDK_KEY_AudioMicMute;
    case AKEYCODE_PAGE_UP:
      return GDK_KEY_Page_Up;
    case AKEYCODE_PAGE_DOWN:
      return GDK_KEY_Page_Down;
    case AKEYCODE_SWITCH_CHARSET:
      return GDK_KEY_Mode_switch;
    case AKEYCODE_ESCAPE:
      return GDK_KEY_Escape;
    case AKEYCODE_FORWARD_DEL:
      return GDK_KEY_Delete;
    case AKEYCODE_CTRL_LEFT:
      return GDK_KEY_Control_L;
    case AKEYCODE_CTRL_RIGHT:
      return GDK_KEY_Control_R;
    case AKEYCODE_CAPS_LOCK:
      return GDK_KEY_Caps_Lock;
    case AKEYCODE_SCROLL_LOCK:
      return GDK_KEY_Scroll_Lock;
    case AKEYCODE_META_LEFT:
      return GDK_KEY_Meta_L;
    case AKEYCODE_META_RIGHT:
      return GDK_KEY_Meta_R;
    case AKEYCODE_FUNCTION:
      return GDK_KEY_function;
    case AKEYCODE_SYSRQ:
      return GDK_KEY_Sys_Req;
    case AKEYCODE_BREAK: // what is this key? is it correct?
      return GDK_KEY_Break;
    case AKEYCODE_MOVE_HOME:
      return GDK_KEY_Home;
    case AKEYCODE_MOVE_END:
      return GDK_KEY_End;
    case AKEYCODE_INSERT:
      return GDK_KEY_Insert;
    case AKEYCODE_FORWARD:
      return GDK_KEY_Forward;
    case AKEYCODE_MEDIA_PLAY:
      return GDK_KEY_AudioPlay;
    case AKEYCODE_MEDIA_PAUSE:
      return GDK_KEY_AudioPause;
    case AKEYCODE_MEDIA_CLOSE:
      return GDK_KEY_Close; // this is probably incorrect (close the ejected cd tray)
    case AKEYCODE_MEDIA_EJECT:
      return GDK_KEY_Eject;
    case AKEYCODE_MEDIA_RECORD:
      return GDK_KEY_AudioRecord;
    case AKEYCODE_F1:
      return GDK_KEY_F1;
    case AKEYCODE_F2:
      return GDK_KEY_F2;
    case AKEYCODE_F3:
      return GDK_KEY_F3;
    case AKEYCODE_F4:
      return GDK_KEY_F4;
    case AKEYCODE_F5:
      return GDK_KEY_F5;
    case AKEYCODE_F6:
      return GDK_KEY_F6;
    case AKEYCODE_F7:
      return GDK_KEY_F7;
    case AKEYCODE_F8:
      return GDK_KEY_F8;
    case AKEYCODE_F9:
      return GDK_KEY_F9;
    case AKEYCODE_F10:
      return GDK_KEY_F10;
    case AKEYCODE_F11:
      return GDK_KEY_F11;
    case AKEYCODE_F12:
      return GDK_KEY_F12;
    case AKEYCODE_NUM_LOCK:
      return GDK_KEY_Num_Lock;
    case AKEYCODE_NUMPAD_0:
      return GDK_KEY_KP_0;
    case AKEYCODE_NUMPAD_1:
      return GDK_KEY_KP_1;
    case AKEYCODE_NUMPAD_2:
      return GDK_KEY_KP_2;
    case AKEYCODE_NUMPAD_3:
      return GDK_KEY_KP_3;
    case AKEYCODE_NUMPAD_4:
      return GDK_KEY_KP_4;
    case AKEYCODE_NUMPAD_5:
      return GDK_KEY_KP_5;
    case AKEYCODE_NUMPAD_6:
      return GDK_KEY_KP_6;
    case AKEYCODE_NUMPAD_7:
      return GDK_KEY_KP_7;
    case AKEYCODE_NUMPAD_8:
      return GDK_KEY_KP_8;
    case AKEYCODE_NUMPAD_9:
      return GDK_KEY_KP_9;
    case AKEYCODE_NUMPAD_DIVIDE:
      return GDK_KEY_KP_Divide;
    case AKEYCODE_NUMPAD_MULTIPLY:
      return GDK_KEY_KP_Multiply;
    case AKEYCODE_NUMPAD_SUBTRACT:
      return GDK_KEY_KP_Subtract;
    case AKEYCODE_NUMPAD_ADD:
      return GDK_KEY_KP_Add;
    case AKEYCODE_NUMPAD_DOT:
      return GDK_KEY_KP_Decimal; // potential mismatch (DOT|COMMA) --> (Decimal,Separator)
    case AKEYCODE_NUMPAD_COMMA:
      return GDK_KEY_KP_Separator;
    case AKEYCODE_NUMPAD_ENTER:
      return GDK_KEY_KP_Enter;
    case AKEYCODE_NUMPAD_EQUALS:
      return GDK_KEY_KP_Equal;
    case AKEYCODE_NUMPAD_LEFT_PAREN: // GDK doesn't seem to have keycodes for this
      return GDK_KEY_parenleft;
    case AKEYCODE_NUMPAD_RIGHT_PAREN:
      return GDK_KEY_parenright;
    case AKEYCODE_VOLUME_MUTE:
      return GDK_KEY_AudioMute;
    case AKEYCODE_LANGUAGE_SWITCH:
      return GDK_KEY_Mode_switch;
    case AKEYCODE_CALENDAR:
      return GDK_KEY_Calendar;
    case AKEYCODE_MUSIC:
      return GDK_KEY_Music;
    case AKEYCODE_CALCULATOR:
      return GDK_KEY_Calculator;
    case AKEYCODE_ZENKAKU_HANKAKU:
      return GDK_KEY_Zenkaku_Hankaku;
    case AKEYCODE_EISU:
      return GDK_KEY_Eisu_Shift;
    case AKEYCODE_MUHENKAN:
      return GDK_KEY_Muhenkan;
    case AKEYCODE_HENKAN:
      return GDK_KEY_Henkan;
    case AKEYCODE_KATAKANA_HIRAGANA:
      return GDK_KEY_Hiragana_Katakana;
    case AKEYCODE_YEN:
      return GDK_KEY_yen;
    case AKEYCODE_RO:
      return GDK_KEY_Romaji;
    case AKEYCODE_KANA:
      return GDK_KEY_Kana_Shift;
    case AKEYCODE_BRIGHTNESS_DOWN:
      return GDK_KEY_MonBrightnessDown;
    case AKEYCODE_BRIGHTNESS_UP:
      return GDK_KEY_MonBrightnessUp;
    case AKEYCODE_MEDIA_AUDIO_TRACK:
      return GDK_KEY_AudioCycleTrack;
    case AKEYCODE_SLEEP:
      return GDK_KEY_Sleep;
    case AKEYCODE_WAKEUP:
      return GDK_KEY_WakeUp;
    case AKEYCODE_MEDIA_TOP_MENU:
      return GDK_KEY_TopMenu;
    case AKEYCODE_HELP:
      return GDK_KEY_Help;
    case AKEYCODE_NAVIGATE_PREVIOUS:
      return GDK_KEY_Back;
    case AKEYCODE_NAVIGATE_NEXT:
      return GDK_KEY_Forward;
    case AKEYCODE_NAVIGATE_IN:
      return GDK_KEY_ZoomIn;
    case AKEYCODE_NAVIGATE_OUT:
      return GDK_KEY_ZoomOut;
    case AKEYCODE_CUT:
      return GDK_KEY_Cut;
    case AKEYCODE_COPY:
      return GDK_KEY_Copy;
    case AKEYCODE_PASTE:
      return GDK_KEY_Paste;
    case AKEYCODE_REFRESH:
      return GDK_KEY_Refresh;
    case AKEYCODE_KEYBOARD_BACKLIGHT_DOWN:
      return GDK_KEY_KbdBrightnessDown;
    case AKEYCODE_KEYBOARD_BACKLIGHT_UP:
      return GDK_KEY_KbdBrightnessUp;
    case AKEYCODE_KEYBOARD_BACKLIGHT_TOGGLE:
      return GDK_KEY_KbdLightOnOff;
    default:
      g_warning ("Gdk.Android: Encountered unsupported keycode %d", keycode);
      return GDK_KEY_VoidSymbol;
    }
}

inline static guint
gdk_android_keysyms_translate_keycode_shifted (gint32 keycode)
{
  switch (keycode)
    {
    case AKEYCODE_0:
      return GDK_KEY_parenright;
    case AKEYCODE_1:
      return GDK_KEY_exclam;
    case AKEYCODE_2:
      return GDK_KEY_at;
    case AKEYCODE_3:
      return GDK_KEY_numbersign;
    case AKEYCODE_4:
      return GDK_KEY_dollar;
    case AKEYCODE_5:
      return GDK_KEY_percent;
    case AKEYCODE_6:
      return GDK_KEY_asciicircum;
    case AKEYCODE_7:
      return GDK_KEY_ampersand;
    case AKEYCODE_8:
      return GDK_KEY_asterisk;
    case AKEYCODE_9:
      return GDK_KEY_parenleft;
    case AKEYCODE_A:
      return GDK_KEY_A;
    case AKEYCODE_B:
      return GDK_KEY_B;
    case AKEYCODE_C:
      return GDK_KEY_C;
    case AKEYCODE_D:
      return GDK_KEY_D;
    case AKEYCODE_E:
      return GDK_KEY_E;
    case AKEYCODE_F:
      return GDK_KEY_F;
    case AKEYCODE_G:
      return GDK_KEY_G;
    case AKEYCODE_H:
      return GDK_KEY_H;
    case AKEYCODE_I:
      return GDK_KEY_I;
    case AKEYCODE_J:
      return GDK_KEY_J;
    case AKEYCODE_K:
      return GDK_KEY_K;
    case AKEYCODE_L:
      return GDK_KEY_L;
    case AKEYCODE_M:
      return GDK_KEY_M;
    case AKEYCODE_N:
      return GDK_KEY_N;
    case AKEYCODE_O:
      return GDK_KEY_O;
    case AKEYCODE_P:
      return GDK_KEY_P;
    case AKEYCODE_Q:
      return GDK_KEY_Q;
    case AKEYCODE_R:
      return GDK_KEY_R;
    case AKEYCODE_S:
      return GDK_KEY_S;
    case AKEYCODE_T:
      return GDK_KEY_T;
    case AKEYCODE_U:
      return GDK_KEY_U;
    case AKEYCODE_V:
      return GDK_KEY_V;
    case AKEYCODE_W:
      return GDK_KEY_W;
    case AKEYCODE_X:
      return GDK_KEY_X;
    case AKEYCODE_Y:
      return GDK_KEY_Y;
    case AKEYCODE_Z:
      return GDK_KEY_Z;
    case AKEYCODE_COMMA:
      return GDK_KEY_less;
    case AKEYCODE_PERIOD:
      return GDK_KEY_greater;
    case AKEYCODE_GRAVE:
      return GDK_KEY_asciitilde;
    case AKEYCODE_MINUS:
      return GDK_KEY_underscore;
    case AKEYCODE_EQUALS:
      return GDK_KEY_plus;
    case AKEYCODE_LEFT_BRACKET:
      return GDK_KEY_braceleft;
    case AKEYCODE_RIGHT_BRACKET:
      return GDK_KEY_braceright;
    case AKEYCODE_BACKSLASH:
      return GDK_KEY_bar;
    case AKEYCODE_SEMICOLON:
      return GDK_KEY_colon;
    case AKEYCODE_APOSTROPHE:
      return GDK_KEY_quotedbl;
    case AKEYCODE_SLASH:
      return GDK_KEY_question;
    default:
      return gdk_android_keysyms_translate_keycode (keycode);
    }
}
