#include <exec/types.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include <devices/keymap.h>
#include <proto/graphics.h>

#include "main.h"
#include "keymap.h"

UBYTE ret[] = { 1,4,2,6,'\x0D','\x0A',SS3,'M' };
UBYTE enter[] = { 2,4,1,6,SS3,'M','\x0D','\x0A' };
csi_12(ccu,'A','2');
csi_12(ccd,'B','5');
csi_12(ccr,'C','6');
csi_12(ccl,'D','4');
ss3_12(acu,'A','2');
ss3_12(acd,'B','5');
ss3_12(acr,'C','6');
ss3_12(acl,'D','4');
UBYTE del[] = { 4,8,3,12,1,15,1,16,CSI,'2','9','~',CSI,'1','~',127,127 };
UBYTE help[] = { 4,4,3,8,CSI,'2','8','~',CSI,'3','~' };
csi_03(f1,0x8B,'2','3');
csi_03(f2,0x8C,'2','4');
csi_03(f3,0x93,'2','5');
csi_03(f4,0x91,'2','6');
csi_03(f5,0x92,'2','8');
csi_33(f6,'1','7','2','9');
css_31(f7,'1','8','3','1','P');
css_31(f8,'1','9','3','2','Q');
css_31(f9,'2','0','3','3','R');
css_31(f10,'2','1','3','4','S');
ss3_10(pf1,'P','[');
ss3_10(pf2,'Q',']');
ss3_10(pf3,'R','/');
ss3_10(pf4,'S','*');
ss3_10(nnum0,'0','p');
ss3_10(nnum1,'1','q');
ss3_10(nnum2,'2','r');
ss3_10(nnum3,'3','s');
ss3_10(nnum4,'4','t');
ss3_10(nnum5,'5','u');
ss3_10(nnum6,'6','v');
ss3_10(nnum7,'7','w');
ss3_10(nnum8,'8','x');
ss3_10(nnum9,'9','y');
ss3_10(nnumcomma,'+','l');
ss3_10(nnumminus,'-','m');
ss3_10(nnumperiod,'.','n');
ss3_10(anum0,'p','0');
ss3_10(anum1,'q','1');
ss3_10(anum2,'r','2');
ss3_10(anum3,'s','3');
ss3_10(anum4,'t','4');
ss3_10(anum5,'u','5');
ss3_10(anum6,'v','6');
ss3_10(anum7,'w','7');
ss3_10(anum8,'x','8');
ss3_10(anum9,'y','9');
ss3_10(anumcomma,'l','+');
ss3_10(anumminus,'m','-');
ss3_10(anumperiod,'n','.');

UBYTE fkey[] = { 0,'f',0,'F',DPF_DEAD,DPF_R,DPF_DEAD,DPF_R,0,6,0,6,0,0x86,0,0x86 };
UBYTE gkey[] = { 0,'g',0,'G',DPF_DEAD,DPF_L,DPF_DEAD,DPF_L,0,7,0,7,0,0x87,0,0x87 };
UBYTE hkey[] = { 0,'h',0,'H',DPF_DEAD,DPF_H,DPF_DEAD,DPF_H,0,8,0,8,0,0x88,0,0x88 };
UBYTE jkey[] = { 0,'j',0,'J',DPF_DEAD,DPF_A,DPF_DEAD,DPF_A,0,10,0,10,0,0x8A,0,0x8A };
UBYTE kkey[] = { 0,'k',0,'K',DPF_DEAD,DPF_D,DPF_DEAD,DPF_D,0,11,0,11,0,0x8B,0,0x8B };

MKEY(akey,'\xe6','\xc6','a','\xe1','\xe0','\xe2','\xe3','\xe4','A','\xc1','\xc0','\xc2','\xc3','\xc4');
MKEY(ekey,'\xa9','\xa9','e','\xe9','\xe8','\xea','e','\xeb','E','\xc9','\xc8','\xca','E','\xcb');
MKEY(ikey,'\xa1','\xa6','i','\xed','\xec','\xee','i','\xef','I','\xcd','\xcc','\xce','I','\xcf');
MKEY(okey,'\xf8','\xd8','o','o','\xf2','\xf4','\xf5','\xf6','O','O','\xd2','\xd4','\xd5','\xd6');
MKEY(nkey,'\xad','\xaf','n','\xf1','n','n','n','n','N','\xd1','N','N','N','N');
MKEY(ukey,'\xb5','\xb5','u','\xfa','\xf9','\xfb','u','\xfc','U','\xda','\xd9','\xdb','U','\xdc');

UBYTE aoacc[] = { DPF_DEAD,DPF_A,0,'\xb0' };
UBYTE ahacc[] = { DPF_DEAD,DPF_A,DPF_DEAD,DPF_H };
UBYTE rlacc[] = { DPF_DEAD,DPF_R,DPF_DEAD,DPF_L };
UBYTE laacc[] = { DPF_DEAD,DPF_L,DPF_DEAD,DPF_A };
UBYTE hdacc[] = { DPF_DEAD,DPF_H,DPF_DEAD,DPF_D };
UBYTE lhacc[] = { DPF_DEAD,DPF_L,DPF_DEAD,DPF_H };
UBYTE hlacc[] = { DPF_DEAD,DPF_H,DPF_DEAD,DPF_L };
UBYTE dhacc[] = { DPF_DEAD,DPF_D,DPF_DEAD,DPF_H };
UBYTE daacc[] = { DPF_DEAD,DPF_D,DPF_DEAD,DPF_A };
UBYTE rdacc[] = { DPF_DEAD,DPF_R,DPF_DEAD,DPF_D };
UBYTE caacc[] = { 0,'\xe7',DPF_DEAD,DPF_A };
UBYTE ital8[] = { DPF_DEAD,DPF_H,0,'8' };

UBYTE lotypes[] = {
    KCF_SHIFT|KCF_ALT,                              /* 0  ` */
    KCF_SHIFT|KCF_ALT,                              /* 1  1 */
    KCF_SHIFT|KCF_ALT,                              /* 2  2 */
    KCF_SHIFT|KCF_ALT,                              /* 3  3 */
    KCF_SHIFT|KCF_ALT,                              /* 4  4 */
    KCF_SHIFT|KCF_CONTROL,                          /* 5  5 */
    KCF_SHIFT|KCF_ALT,                              /* 6  6 */
    KCF_SHIFT|KCF_ALT,                              /* 7  7 */
    KCF_SHIFT|KCF_ALT,                              /* 8  8 */
    KCF_SHIFT|KCF_ALT,                              /* 9  9 */
    KCF_SHIFT|KCF_ALT,                              /* 10 0 */
    KCF_SHIFT|KCF_ALT,                              /* 11 + */
    KCF_SHIFT|KCF_ALT,                              /* 12 ' */
    KCF_SHIFT|KCF_CONTROL,                          /* 13 \ */
    0,                                              /* 14 */
    KCF_SHIFT|KCF_STRING,                           /* 15 0N */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 16 q */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 17 w */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 18 e */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 19 r */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 20 t */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 21 y */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 22 u */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 23 i */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 24 o */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 25 p */
    KCF_SHIFT|KCF_ALT,                              /* 26 [  */
    KCF_SHIFT|KCF_ALT,                              /* 27 ] */
    0,                                              /* 28 */
    KCF_SHIFT|KCF_STRING,                           /* 29 1N */
    KCF_SHIFT|KCF_STRING,                           /* 30 2N */
    KCF_SHIFT|KCF_STRING,                           /* 31 3N */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 32 a */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 33 s */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 34 d */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 35 f */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 36 g */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 37 h */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 38 j */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 39 k */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 40 l */
    KCF_SHIFT|KCF_ALT,                              /* 41 ö */
    KCF_SHIFT|KCF_ALT,                              /* 42 ä */
    KCF_SHIFT|KCF_ALT,                              /* 43 ' */
    0,                                              /* 44 */
    KCF_SHIFT|KCF_STRING,                           /* 45 4N */
    KCF_SHIFT|KCF_STRING,                           /* 46 5N */
    KCF_SHIFT|KCF_STRING,                           /* 47 6N */
    KCF_SHIFT|KCF_ALT,                              /* 48 < */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 49 z */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 50 x */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 51 c */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 52 v */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 53 b */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT|KCF_DEAD,         /* 54 n */
    KCF_SHIFT|KCF_CONTROL|KCF_ALT,                  /* 55 m */
    KCF_SHIFT|KCF_ALT,                              /* 56 , */
    KCF_SHIFT|KCF_ALT,                              /* 57 . */
    KCF_SHIFT|KCF_ALT,                              /* 58 - */
    0,                                              /* 59 */
    KCF_SHIFT|KCF_STRING,                           /* 60 .N */
    KCF_SHIFT|KCF_STRING,                           /* 61 7N */
    KCF_SHIFT|KCF_STRING,                           /* 62 8N */
    KCF_SHIFT|KCF_STRING };                         /* 63 9N */

ULONG *lokeymap[] = {
    KEY('~','`','~','`'),           /* 0  ` */
    KEY('!','1','!','1'),           /* 1  1 */
    KEY('\xb0','2','@','2'),        /* 2  2 */
    KEY('£','3','#','3'),           /* 3  3 */
    KEY('$','4','$','4'),           /* 4  4 */
    KEY('\x1e','\x1d','%','5'),     /* 5  5 */
    KEY('^','6','^','6'),           /* 6  6 */
    KEY('&','7','&','7'),           /* 7  7 */
    KEY('*','8','*','8'),           /* 8  8 */
    KEY('(','9','(','9'),           /* 9  9 */
    KEY(')','0',')','0'),           /* 10 0 */
    KEY('_','-','_','-'),           /* 11 + */
    KEY('+','=','+','='),           /* 12 ' */
    KEY(28,28,'|','\\'),            /* 13 \ */
    NULKEY,                         /* 14 */
    STR(&nnum0),                    /* 15 0N */
    KEY('\xc5','\xe5','Q','q'),     /* 16 q */
    KEY('\xb0','\xb0','W','w'),     /* 17 w */
    STR(&ekey),                     /* 18 e */
    KEY('\xae','\xae','R','r'),     /* 19 r */
    KEY('\xde','\xfe','T','t'),     /* 20 t */
    KEY('\xa5','\xa4','Y','y'),     /* 21 y */
    STR(&ukey),                     /* 22 u */
    STR(&ikey),                     /* 23 i */
    STR(&okey),                     /* 24 o */
    KEY('\xb6','\xb6','P','p'),     /* 25 p */
    KEY('{','[','{','['),           /* 26 [  */
    KEY('}',']','}',']'),           /* 27 ] */
    NULKEY,                         /* 28 */
    STR(&nnum1),                    /* 29 1N */
    STR(&nnum2),                    /* 30 2N */
    STR(&nnum3),                    /* 31 3N */
    STR(&akey),                     /* 32 a */
    KEY('\xa7','\xdf','S','s'),     /* 33 s */
    KEY('\xd0','\xf0','D','d'),     /* 34 d */
    STR(&fkey),                     /* 35 f */
    STR(&gkey),                     /* 36 g */
    STR(&hkey),                     /* 37 h */
    STR(&jkey),                     /* 38 j */
    STR(&kkey),                     /* 39 k */
    KEY('\xa3','\xa3','L','l'),     /* 40 l */
    KEY(':',';',':',';'),           /* 41 ö */
    KEY('"','\x27','"','\x27'),     /* 42 ä */
    KEY('|','\\','|','\\'),         /* 43 ' */
    NULKEY,                         /* 44 */
    STR(&nnum4),                    /* 45 4N */
    STR(&nnum5),                    /* 46 5N */
    STR(&nnum6),                    /* 47 6N */
    KEY('\xbb','\xab','>','<'),     /* 48 < */
    KEY('\xac','\xb1','Z','z'),     /* 49 z */
    KEY('\xf7','\xd7','X','x'),     /* 50 x */
    KEY('\xc7','\xe7','C','c'),     /* 51 c */
    KEY('\xfd','\xaa','V','v'),     /* 52 v */
    KEY('\xff','\xba','B','b'),     /* 53 b */
    STR(&nkey),                     /* 54 n */
    KEY('\xbf','\xb8','M','m'),     /* 55 m */
    KEY(',',',',',',','),           /* 56 , */
    KEY('.','.','.','.'),           /* 57 . */
    KEY('?','/','?','/'),           /* 58 - */
    NULKEY,                         /* 59 */
    STR(&nnumperiod),               /* 60 .N */
    STR(&nnum7),                    /* 61 7N */
    STR(&nnum8),                    /* 62 8N */
    STR(&nnum9) };                  /* 63 9N */

UBYTE locapsaple[] = { 0,0,0xFF,0x03,0xFF,0x07,0xFE,0 };
UBYTE lorepeatable[] = { 0xFF,0x3F,0xFF,0x0F,0xFF,0x0F,0xFF,0x07 };

UBYTE hitypes[] = {
    KCF_CONTROL,                    /* 64 SPC */
    KC_NOQUAL,                      /* 65 BS */
    KC_NOQUAL,                      /* 66 TAB */
    KCF_STRING,                     /* 67 ENT */
    KCF_STRING,                     /* 68 RET */
    KC_NOQUAL,                      /* 69 ESC */
    KCF_STRING|KCF_SHIFT|KCF_ALT,   /* 70 DEL */
    0,                              /* 71 */
    0,                              /* 72 */
    0,                              /* 73 */
    KCF_STRING|KCF_SHIFT,           /* 74 -N */
    0,                              /* 75 */
    KCF_STRING|KCF_SHIFT,           /* 76 UP */
    KCF_STRING|KCF_SHIFT,           /* 77 DOWN */
    KCF_STRING|KCF_SHIFT,           /* 78 FORWARD */
    KCF_STRING|KCF_SHIFT,           /* 79 BACKWARD */
    KCF_STRING|KCF_SHIFT,           /* 80 F1 */
    KCF_STRING|KCF_SHIFT,           /* 81 F2 */
    KCF_STRING|KCF_SHIFT,           /* 82 F3 */
    KCF_STRING|KCF_SHIFT,           /* 83 F4 */
    KCF_STRING|KCF_SHIFT,           /* 84 F5 */
    KCF_STRING|KCF_SHIFT,           /* 85 F6 */
    KCF_STRING|KCF_SHIFT|KCF_ALT,   /* 86 F7 */
    KCF_STRING|KCF_SHIFT|KCF_ALT,   /* 87 F8 */
    KCF_STRING|KCF_SHIFT|KCF_ALT,   /* 88 F9 */
    KCF_STRING|KCF_SHIFT|KCF_ALT,   /* 89 F10 */
    KCF_STRING|KCF_SHIFT,           /* 90 PF1 */
    KCF_STRING|KCF_SHIFT,           /* 91 PF2 */
    KCF_STRING|KCF_SHIFT,           /* 92 PF3 */
    KCF_STRING|KCF_SHIFT,           /* 93 PF4 */
    KCF_STRING|KCF_SHIFT,           /* 94 ,N (+) */
    KCF_STRING|KCF_SHIFT,           /* 95 HELP */
    KCF_NOP,                        /* 96 L SHIFT */
    KCF_NOP,                        /* 97 R SHIFT */
    KCF_NOP,                        /* 98 CAPS LOCK */
    KCF_NOP,                        /* 99 CONTROL */
    KCF_NOP,                        /* 100 L ALT */
    KCF_NOP,                        /* 101 R ALT */
    KCF_NOP,                        /* 102 L AMIGA */
    KCF_NOP };                      /* 103 R AMIGA */

ULONG *hikeymap[] = {
    KEY(0,0,0,' '),                 /* 64 SPC */
    KEY(0,0,0,127),                 /* 65 BS */
    KEY(0,0,0,9),                   /* 66 TAB */
    STR(ret),                       /* 67 ENT */
    STR(ret),                       /* 68 RET */
    KEY(0,0,0,27),                  /* 69 ESC */
    STR(del),                       /* 70 DEL */
    NULKEY,                         /* 71 */
    NULKEY,                         /* 72 */
    NULKEY,                         /* 73 */
    STR(&nnumminus),                /* 74 -N */
    NULKEY,                         /* 75 */
    STR(&ccu),                      /* 76 UP */
    STR(&ccd),                      /* 77 DOWN */
    STR(&ccr),                      /* 78 FORWARD */
    STR(&ccl),                      /* 79 BACKWARD */
    STR(&f1),                       /* 80 F1 */
    STR(&f2),                       /* 81 F2 */
    STR(&f3),                       /* 82 F3 */
    STR(&f4),                       /* 83 F4 */
    STR(&f5),                       /* 84 F5 */
    STR(&f6),                       /* 85 F6 */
    STR(&f7),                       /* 86 F7 */
    STR(&f8),                       /* 87 F8 */
    STR(&f9),                       /* 88 F9 */
    STR(&f10),                      /* 89 F10 */
    STR(&pf1),                      /* 90 PF1 */
    STR(&pf2),                      /* 91 PF2 */
    STR(&pf3),                      /* 92 PF3 */
    STR(&pf4),                      /* 93 PF4 */
    STR(&nnumcomma),                /* 94 ,N (+) */
    STR(help),                      /* 95 HELP */
    NULKEY,                         /* 96 L SHIFT */
    NULKEY,                         /* 97 R SHIFT */
    NULKEY,                         /* 98 CAPS LOCK */
    NULKEY,                         /* 99 CONTROL */
    NULKEY,                         /* 100 L ALT */
    NULKEY,                         /* 101 R ALT */
    NULKEY,                         /* 102 L AMIGA */
    NULKEY };                       /* 103 R AMIGA */

UBYTE hicapsaple[] = { 0,0,0,0,0,0,0,0 };
UBYTE hirepeatable[] = { 0x47,0xF4,0,0x40,0,0,0,0 };

struct KeyMap keymap = {
    lotypes,(ULONG *)lokeymap,locapsaple,lorepeatable,
    hitypes,(ULONG *)hikeymap,hicapsaple,hirepeatable };

entermode(int set)
{
if (set) {
    ret[0] = 2;
    enter[2] = 2;
    }
else {
    ret[0] = 1;
    enter[2] = 1;
    }
return(0);
}

keypadmode(int set)
{
if (set) {
    lokeymap[15] = STR(&anum0);
    lokeymap[29] = STR(&anum1);
    lokeymap[30] = STR(&anum2);
    lokeymap[31] = STR(&anum3);
    lokeymap[45] = STR(&anum4);
    lokeymap[46] = STR(&anum5);
    lokeymap[47] = STR(&anum6);
    lokeymap[60] = STR(&anumperiod);
    lokeymap[61] = STR(&anum7);
    lokeymap[62] = STR(&anum8);
    lokeymap[63] = STR(&anum9);
    hikeymap[3]  = STR(enter);
    hikeymap[10] = STR(&anumminus);
    hikeymap[30] = STR(&anumcomma);
    }
else {
    lokeymap[15] = STR(&nnum0);
    lokeymap[29] = STR(&nnum1);
    lokeymap[30] = STR(&nnum2);
    lokeymap[31] = STR(&nnum3);
    lokeymap[45] = STR(&nnum4);
    lokeymap[46] = STR(&nnum5);
    lokeymap[47] = STR(&nnum6);
    lokeymap[60] = STR(&nnumperiod);
    lokeymap[61] = STR(&nnum7);
    lokeymap[62] = STR(&nnum8);
    lokeymap[63] = STR(&nnum9);
    hikeymap[3]  = STR(ret);
    hikeymap[10] = STR(&nnumminus);
    hikeymap[30] = STR(&nnumcomma);
    }
return(0);
}

cursormode(int set)
{
if (set) {
    hikeymap[12] = STR(&ccu);
    hikeymap[13] = STR(&ccd);
    hikeymap[14] = STR(&ccr);
    hikeymap[15] = STR(&ccl);
    }
else {
    hikeymap[12] = STR(&acu);
    hikeymap[13] = STR(&acd);
    hikeymap[14] = STR(&acr);
    hikeymap[15] = STR(&acl);
    }
return(0);
}
