/*
    Tucnak - VHF contest log
    Copyright (C) 2002-2023  Ladislav Vaiz <ok1zia@nagano.cz>
    and authors of web browser Links 0.96

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#include "header.h"

#include "kbdbind.h"
#include "kbd.h"
#include "language2.h"
#include "terminal.h"
#include "tsdl.h"


static void add_default_keybindings(void);

struct keybinding {
    struct keybinding *next;
    struct keybinding *prev;
    int act;
    long x;
    long y;
};

static struct keybinding keymaps[KM_MAX];

static void add_keybinding(int km, int act, long x, long y)
{
    struct keybinding *kb;

    foreach(kb, keymaps[km])
        if (kb->x == x && kb->y == y) {
            /* want at top of list */
            del_from_list(kb);
            goto add;
        }
    
    if ((kb = g_malloc(sizeof(struct keybinding)))) {
        add:
        kb->act = act;
        kb->x = x;
        kb->y = y;
        add_to_list(keymaps[km], kb);
    }
}


void init_keymaps(void)
{
        int i;  
    for (i = 0; i < KM_MAX; i++) init_list(keymaps[i]);
    add_default_keybindings();
}

void free_keymaps(void) 
{
    int i;
	//progress(VTEXT(T_TERM_KEYMAPS));		

    for (i = 0; i < KM_MAX; i++) {
        while (keymaps[i].next != &(keymaps[i])) {
            struct keybinding *a=(keymaps[i]).next; 
            del_from_list(a); 
            g_free(a); 
        }
    }
}

int kbd_action(int kmap, struct event *ev)
{
    struct keybinding *kb;
    if (ev->ev == EV_KBD)
        foreach(kb, keymaps[kmap]){
            if (ev->x == kb->x && ev->y == kb->y) {
            //    dbg("kbd_action=%d\n",kb->act);
                return kb->act;
            }
            if (kb->y & (KBD_CTRL|KBD_ALT)){
                if (toupper(ev->x) == toupper(kb->x) && ev->y == kb->y) {
                    return kb->act;
                }
            }
        }
    return -1;
}

/*
 * Default keybindings.
 */

struct default_kb {
    int act;
    long x;
    long y;
};

/*  !!!! CTRL needs uppercase, ALT lowercase */

static struct default_kb default_main_keymap[] = {
	{ ACT_AC_INFO, 'a', KBD_ALT },
    { ACT_BACKSPACE, KBD_BS, 0 },
    { ACT_BACKSPACE, KBD_BS, KBD_SHIFT },
    { ACT_CALLINFO, 'i', KBD_ALT },
    { ACT_CHOP, 'o', KBD_ALT },
    { ACT_CLEAR_TMPQSOS, 'y', KBD_ALT },
    { ACT_CLEAR_TMPQSOS_INPUTLINE, KBD_F3, 0 },
    { ACT_CONFIRM_CALL, 'd', KBD_ALT },
    { ACT_CONFIRM_EXC, 'e', KBD_ALT },
    { ACT_CONFIRM_WWL, 'x', KBD_ALT },
    { ACT_COPY_CLIPBOARD, 'C', KBD_CTRL },
    { ACT_COPY_CLIPBOARD, KBD_INS, KBD_CTRL },
    { ACT_CQ_0, KBD_F5, 0 },
    { ACT_CQ_1, KBD_F6, 0 },
    { ACT_CQ_2, KBD_F7, 0 },
    { ACT_CQ_3, KBD_F8, 0 },
    { ACT_CQ_4, KBD_F11, 0 },
    { ACT_CQ_5, KBD_F12, 0 },
    { ACT_DELETE, KBD_DEL, 0 },
	{ ACT_PAGE_DOWN, KBD_DOWN, KBD_CTRL },
	{ ACT_DOWN, KBD_DOWN, 0 },
    { ACT_END, KBD_END, 0 },
    { ACT_ENTER, KBD_ENTER, 0 },
	{ ACT_MAXIMIZE, KBD_F10, KBD_ALT },
    { ACT_FILE_MENU, KBD_F10 },
    { ACT_FIND_NEXT_BACK, 'N', 0 },
    { ACT_FIND_NEXT, 'n', 0 },
	{ ACT_FULLSCREEN, KBD_F11, KBD_CTRL },
   // { ACT_GRAB_BAND, 'g', KBD_ALT },
    { ACT_HOME, KBD_HOME, 0 },
    { ACT_INSERT, KBD_INS, 0 },
    { ACT_LEFT, KBD_LEFT, 0 },
    { ACT_MENU, KBD_F9, 0 },
    { ACT_MODE, 'm', KBD_ALT },
    { ACT_NEXT_SUBWIN, KBD_F4, 0 },
    { ACT_NEXT_SUBWIN, KBD_RIGHT, KBD_ALT },
	{ ACT_OPEN_NET, KBD_F3, KBD_SHIFT },
    { ACT_PREV_SUBWIN, KBD_LEFT, KBD_ALT },
    { ACT_PAGE_DOWN, KBD_PGDN, 0 },
    { ACT_PAGE_UP, KBD_PGUP,0 },
	{ ACT_PLAY_LAST, 'P', KBD_CTRL },
	{ ACT_QUIT, KBD_F4, KBD_ALT },
    { ACT_REALLYQUIT, 'q', KBD_ALT },
    { ACT_RIGHT, KBD_RIGHT, 0 },
	{ ACT_ROTAR, 'r', KBD_ALT },
	{ ACT_ROTAR_STOP, 'S', KBD_CTRL },
	{ ACT_RUNMODE, 'R', KBD_CTRL },
    { ACT_RX, KBD_ESC, 0 },
    { ACT_RXTX, KBD_TAB, 0 },
    { ACT_SAVE_ALL, KBD_F2, 0 },
    { ACT_SCREENSHOT, KBD_F1, 0 },
    { ACT_SCROLL_LEFT, '[', 0 },
    { ACT_SCROLL_RIGHT, ']', 0 },
    { ACT_SEARCH, '/', 0 },
    { ACT_SEARCH_BACK, '?', 0 },
    { ACT_SEEK_A, 'A', KBD_CTRL },
    { ACT_SEEK_B, 'B', KBD_CTRL },
    { ACT_SKED, 's', KBD_ALT },
    { ACT_SKED_QRG, 'f', KBD_ALT },
    { ACT_SWAP_CALL, 'c', KBD_ALT },
    { ACT_SWAP_WWL, 'v', KBD_ALT },
	{ ACT_TOGGLE_SPLIT_VFO, '`', 0 },
    { ACT_TUNE, 't', KBD_ALT },
    { ACT_UNFINISHED, 'u', KBD_ALT },
	{ ACT_PAGE_UP, KBD_UP, KBD_CTRL },
	{ ACT_UP, KBD_UP, 0 },
    { ACT_WINDOWSHOT, KBD_F1, KBD_ALT },
    { ACT_AC_CQ, 'j', KBD_ALT },
	{ ACT_ZOOMIN, '+', KBD_CTRL },
	{ ACT_ZOOMIN, '=', KBD_CTRL },
	{ ACT_ZOOMOUT, '-', KBD_CTRL },
	{ ACT_ZOOM0, '0', KBD_CTRL },
    { 0, 0, 0 }
};

static struct default_kb default_edit_keymap[] = {
	{ ACT_AC_INFO, 'a', KBD_ALT },
	{ ACT_LEFT, KBD_LEFT, 0 },
    { ACT_RIGHT, KBD_RIGHT, 0 },
    { ACT_HOME, KBD_HOME, 0 },
    { ACT_END, KBD_END, 0 },
    { ACT_COPY_CLIPBOARD, KBD_INS, KBD_CTRL },
    { ACT_ENTER, KBD_ENTER, 0 },
    { ACT_BACKSPACE, KBD_BS, 0 },
    { ACT_BACKSPACE, KBD_BS, KBD_SHIFT },
    { ACT_DELETE, KBD_DEL, 0 },
    { ACT_KILL_LINE, 'Y', KBD_CTRL },
    { ACT_PREV_HISTORY, 'p', KBD_ALT },
    { ACT_NEXT_HISTORY, 'n', KBD_ALT },
    { ACT_SHOW_HISTORY, 'h', KBD_ALT },
    { ACT_LASTCALL_KST, 'k', KBD_ALT },
    { ACT_NEWCALL_KST, 'K', KBD_CTRL },
/* ACT_KILL_TO_BOL, 'U', KBD_CTRL },
    { ACT_KILL_TO_EOL, 'K', KBD_CTRL },*/
    { 0, 0, 0 }
};

static struct default_kb default_menu_keymap[] = {
    { ACT_LEFT, KBD_LEFT, 0 },
    { ACT_RIGHT, KBD_RIGHT, 0 },
    { ACT_HOME, KBD_HOME, 0 },
    { ACT_HOME, 'A', KBD_CTRL },
    { ACT_UP, KBD_UP, 0 },
    { ACT_DOWN, KBD_DOWN, 0 },
    { ACT_END, KBD_END, 0 },
    { ACT_END, 'E', KBD_CTRL },
    { ACT_ENTER, KBD_ENTER, 0 },
    { ACT_PAGE_DOWN, KBD_PGDN, 0 },
    { ACT_PAGE_DOWN, 'F', KBD_CTRL },
    { ACT_PAGE_UP, KBD_PGUP, 0 },
    { ACT_PAGE_UP, 'B', KBD_CTRL },
    { 0, 0, 0}
};

static void add_default_keybindings(void)
{
    struct default_kb *kb;
    for (kb = default_main_keymap; kb->x; kb++) add_keybinding(KM_MAIN, kb->act, kb->x, kb->y);
        for (kb = default_edit_keymap; kb->x; kb++) add_keybinding(KM_EDIT, kb->act, kb->x, kb->y);
        for (kb = default_menu_keymap; kb->x; kb++) add_keybinding(KM_MENU, kb->act, kb->x, kb->y);
}
