// SPDX-License-Identifier: GPL-2.0-or-later
// Copyright (C) 1997 Michael R. Elkins <me@cs.hmc.edu>


#include <sys/ttydefaults.h>
#include <termios.h>
#include <unistd.h>

#include "enter.h"


static cc_t Kill   = CKILL;
static cc_t Werase = CWERASE;
static cc_t Erase  = CERASE;
static cc_t Eol    = CEOL;
static cc_t Eol2 =
#ifdef CEOL2
    CEOL2;
#else
    _POSIX_VDISABLE;
#endif
void km_dokey_load_termios(void) {
	struct termios termios;
	if(!tcgetattr(0, &termios)) {
		Kill   = termios.c_cc[VKILL];
		Werase = termios.c_cc[VWERASE];
		Erase  = termios.c_cc[VERASE];
	}
}


int km_dokey(wint_t * LastKey) {
	switch(get_wch(LastKey)) {
		case ERR:
		default:
			return -1;

		case OK:
			switch(*LastKey) {
				case L'\r':
				case L'\n':
					return OP_EDITOR_DONE;
				case CTRL(L'B'):
					return OP_EDITOR_BACKWARD_CHAR;
				case CTRL(L'F'):
					return OP_EDITOR_FORWARD_CHAR;
				case CTRL(L'H'):
					return OP_EDITOR_BACKSPACE;
				case CTRL(L'D'):
					return OP_EDITOR_DELETE_CHAR;
				case CTRL(L'A'):
					return OP_EDITOR_BOL;
				case CTRL(L'E'):
					return OP_EDITOR_EOL;
				case KEY_DL:
					return OP_EDITOR_KILL_LINE;
				case CTRL(L'I'):
					return OP_EDITOR_KILL_EOL;
				case CTRL(L'G'):
					return -1;
			}
#define MAP(stty, op)                                 \
	if(*LastKey == stty && *LastKey != _POSIX_VDISABLE) \
	return op
			MAP(Kill, OP_EDITOR_KILL_LINE);
			MAP(Werase, OP_EDITOR_KILL_WORD);
			MAP(Erase, OP_EDITOR_DELETE_CHAR);
			MAP(Eol, OP_EDITOR_DONE);
			MAP(Eol2, OP_EDITOR_DONE);

			return OP_EDITOR_CHAR;

		case KEY_CODE_YES:
			switch(*LastKey) {
				case KEY_LEFT:
					return OP_EDITOR_BACKWARD_CHAR;
				case KEY_RIGHT:
					return OP_EDITOR_FORWARD_CHAR;
				case KEY_BACKSPACE:
					return OP_EDITOR_BACKSPACE;
				case KEY_DC:
					return OP_EDITOR_DELETE_CHAR;
				case KEY_HOME:
					return OP_EDITOR_BOL;
				case KEY_END:
					return OP_EDITOR_EOL;
				case KEY_DL:
					return OP_EDITOR_KILL_LINE;
				case KEY_RESIZE:
					return OP_EDITOR_RESIZE;
				default:
					return OP_EDITOR_IDK;
			}
	}
}
