/* 
 * w3m func.h
 */

#ifndef FUNC_H
#define FUNC_H

#include <btri.h>
#include "textlist.h"

#define K_CTL_ATMARK (0x00)

#define K_CTL_A (0x01)
#define K_CTL_B (0x02)
#define K_CTL_C (0x03)
#define K_CTL_D (0x04)
#define K_CTL_E (0x05)
#define K_CTL_F (0x06)
#define K_CTL_G (0x07)
#define K_CTL_H (0x08)
#define K_CTL_I (0x09)
#define K_CTL_J (0x0A)
#define K_CTL_K (0x0B)
#define K_CTL_L (0x0C)
#define K_CTL_M (0x0D)
#define K_CTL_N (0x0E)
#define K_CTL_O (0x0F)
#define K_CTL_P (0x10)
#define K_CTL_Q (0x11)
#define K_CTL_R (0x12)
#define K_CTL_S (0x13)
#define K_CTL_T (0x14)
#define K_CTL_U (0x15)
#define K_CTL_V (0x16)
#define K_CTL_W (0x17)
#define K_CTL_X (0x18)
#define K_CTL_Y (0x19)
#define K_CTL_Z (0x1A)

#define K_CTL_LBRACKET (0x1B)
#define K_CTL_BACKSLASH (0x1C)
#define K_CTL_RBRACKET (0x1D)
#define K_CTL_HAT (0x1F)

#define K_SPACE (0x20)

#define K_SYM_EXCLM (0x21)
#define K_SYM_DQ (0x22)
#define K_SYM_SHARP (0x23)
#define K_SYM_DOLLAR (0x24)
#define K_SYM_PERCENT (0x25)
#define K_SYM_AMP (0x26)
#define K_SYM_SQ (0x27)
#define K_SYM_LPAREN (0x28)
#define K_SYM_RPAREN (0x29)
#define K_SYM_AST (0x2A)
#define K_SYM_PLUS (0x2B)
#define K_SYM_COMMA (0x2C)
#define K_SYM_MINUS (0x2D)
#define K_SYM_DOT (0x2E)
#define K_SYM_SLASH (0x2F)

#define K_DIGIT_0 (0x30)
#define K_DIGIT_1 (0x31)
#define K_DIGIT_2 (0x32)
#define K_DIGIT_3 (0x33)
#define K_DIGIT_4 (0x34)
#define K_DIGIT_5 (0x35)
#define K_DIGIT_6 (0x36)
#define K_DIGIT_7 (0x37)
#define K_DIGIT_8 (0x38)
#define K_DIGIT_9 (0x39)

#define K_SYM_COLON (0x3A)
#define K_SYM_SEMICOLON (0x3B)
#define K_SYM_LT (0x3C)
#define K_SYM_EQ (0x3D)
#define K_SYM_GT (0x3E)
#define K_SYM_QUESTION (0x3F)
#define K_SYM_ATMARK (0x40)

#define K_ALPHA_A (0x41)
#define K_ALPHA_B (0x42)
#define K_ALPHA_C (0x43)
#define K_ALPHA_D (0x44)
#define K_ALPHA_E (0x45)
#define K_ALPHA_F (0x46)
#define K_ALPHA_G (0x47)
#define K_ALPHA_H (0x48)
#define K_ALPHA_I (0x49)
#define K_ALPHA_J (0x4A)
#define K_ALPHA_K (0x4B)
#define K_ALPHA_L (0x4C)
#define K_ALPHA_M (0x4D)
#define K_ALPHA_N (0x4E)
#define K_ALPHA_O (0x4F)
#define K_ALPHA_P (0x50)
#define K_ALPHA_Q (0x51)
#define K_ALPHA_R (0x52)
#define K_ALPHA_S (0x53)
#define K_ALPHA_T (0x54)
#define K_ALPHA_U (0x55)
#define K_ALPHA_V (0x56)
#define K_ALPHA_W (0x57)
#define K_ALPHA_X (0x58)
#define K_ALPHA_Y (0x59)
#define K_ALPHA_Z (0x5A)

#define K_SYM_LBRACKET (0x5B)
#define K_SYM_BACKSLASH (0x5C)
#define K_SYM_RBRACKET (0x5D)
#define K_SYM_HAT (0x5E)
#define K_SYM_USCORE (0x5F)
#define K_SYM_BQ (0x60)

#define K_ALPHA_a (0x61)
#define K_ALPHA_b (0x62)
#define K_ALPHA_c (0x63)
#define K_ALPHA_d (0x64)
#define K_ALPHA_e (0x65)
#define K_ALPHA_f (0x66)
#define K_ALPHA_g (0x67)
#define K_ALPHA_h (0x68)
#define K_ALPHA_i (0x69)
#define K_ALPHA_j (0x6A)
#define K_ALPHA_k (0x6B)
#define K_ALPHA_l (0x6C)
#define K_ALPHA_m (0x6D)
#define K_ALPHA_n (0x6E)
#define K_ALPHA_o (0x6F)
#define K_ALPHA_p (0x70)
#define K_ALPHA_q (0x71)
#define K_ALPHA_r (0x72)
#define K_ALPHA_s (0x73)
#define K_ALPHA_t (0x74)
#define K_ALPHA_u (0x75)
#define K_ALPHA_v (0x76)
#define K_ALPHA_w (0x77)
#define K_ALPHA_x (0x78)
#define K_ALPHA_y (0x79)
#define K_ALPHA_z (0x7A)

#define K_SYM_LBRACE (0x7B)
#define K_SYM_VBAR (0x7C)
#define K_SYM_RBRACE (0x7D)
#define K_SYM_TILDE (0x7E)

#define K_DELETE (0x7F)

#define K_ESC_POS (7)
#define K_ESC_LEN (2)
#define K_ESC_MASK (((1U << K_ESC_LEN) - 1U) << K_ESC_POS)
#define K_ESC_NONE (0U << K_ESC_POS)
#define K_ESC (1U << K_ESC_POS)
#define K_ESCB (2U << K_ESC_POS)
#define K_ESCD (3U << K_ESC_POS)

#define K_UP (K_ESCB | 0x41)
#define K_DOWN (K_ESCB | 0x42)
#define K_RIGHT (K_ESCB | 0x43)
#define K_LEFT (K_ESCB | 0x44)
#define K_PocketBSD_INS (K_ESCB | 0x45)
#define K_END (K_ESCB | 0x46)
#define K_PGDN (K_ESCB | 0x47)
#define K_HOME (K_ESCB | 0x48)
#define K_PGUP (K_ESCB | 0x49)
#define K_FreeBSD_CONSOLE_INS (K_ESCB | 0x4C)

#define K_XTERM_MOUSE (K_ESCB | 0x4D)

#define K_PAD_HOME (K_ESCD | 0x01) /* fixme */
#define K_PAD_INS (K_ESCD | 0x02)
#define K_PAD_END (K_ESCD | 0x04) /* fixme */
#define K_PAD_PGUP (K_ESCD | 0x05)
#define K_PAD_PGDN (K_ESCD | 0x06)
#define K_PAD_F1 (K_ESCD | 0x0B)
#define K_PAD_F2 (K_ESCD | 0x0C)
#define K_PAD_F3 (K_ESCD | 0x0D)
#define K_PAD_F4 (K_ESCD | 0x0E)
#define K_PAD_F5 (K_ESCD | 0x0F)
#define K_PAD_F6 (K_ESCD | 0x11)
#define K_PAD_F7 (K_ESCD | 0x12)
#define K_PAD_F8 (K_ESCD | 0x13)
#define K_PAD_F9 (K_ESCD | 0x14)
#define K_PAD_F10 (K_ESCD | 0x15)
#define K_PAD_HELP (K_ESCD | 0x1C)

#ifdef USE_MOUSE
#define K_MOUSE_CLICK (0)
#define K_MOUSE_DCLICK (1)
#define K_MOUSE_DRAG (2)
#define K_MOUSE_MOVE (3)
#define K_MOUSE_NBTNS (5)
#define K_MOUSE(op) (K_ESCD | (100 + K_MOUSE_ ## op * K_MOUSE_NBTNS))
#endif

#define K_ONE_LEN (K_ESC_POS + K_ESC_LEN)

#define K_LEN_LEN (2)
#define K_LEN_MASK ((1U << K_LEN_LEN) - 1U)
#define K_LEN(k) ((k) & K_LEN_MASK)

#define K_LEN_MAX (2)

#define K_CMP_LEN ((K_ONE_LEN) * K_LEN_MAX + K_LEN_LEN)
#define K_CMP_MASK (~(~0U << K_CMP_LEN))
#define K_CMP(x, op, y) ((x) & K_CMP_MASK) op ((y) & K_CMP_MASK)

#define K_SET_FUNC(k, f) (((f) << K_CMP_LEN) | (k))
#define K_GET_FUNC(k) ((k) >> K_CMP_LEN)
#define K_FUNC_MAX (~(~0 << (sizeof(int) * CHAR_BIT - 1 - K_CMP_LEN)))

#define K_GEN(old, cur) \
((((old) << K_ONE_LEN) & (~0U << (K_ONE_LEN + K_LEN_LEN))) | \
 (((cur) & ~(~0U << K_ONE_LEN)) << K_LEN_LEN) | \
 (((old) & K_LEN_MASK) + 1U))

#define K_OVER(old, cur) (((old) & ~(~(~0U << K_ONE_LEN) << K_LEN_LEN)) | (((cur) & ~(~0U << K_ONE_LEN)) << K_LEN_LEN))

struct _InputLineEnv;

typedef struct _FuncList {
  char *id;
  union {
    void (*main_func)(void);
    void (*edit_func)(int, struct _InputLineEnv *);
    int (*menu_func)(int);
  } func;
} FuncList;

typedef int KeyTabItem;

typedef struct _KeyTabList {
  struct _KeyTabList *next;
  KeyTabItem *key_table;
  int nitem, size;
} KeyTabList;

extern btri_string_tab_t w3mFuncTab[];

#endif				/* not FUNC_H */
