// SPDX-License-Identifier: GPL-2.0+
/* speakup_keyhelp.c
 * help module for speakup
 *
 *written by David Borowski.
 *
 *  Copyright (C) 2003  David Borowski.
 */

#include <linux/keyboard.h>
#include <linux/ctype.h>
#include "spk_priv.h"
#include "speakup.h"

#define MAXFUNCS 130
#define MAXKEYS 256
static const int num_key_names = MSG_KEYNAMES_END - MSG_KEYNAMES_START + 1;
static u16 key_offsets[MAXFUNCS], key_data[MAXKEYS];
static u16 masks[] = { 32, 16, 8, 4, 2, 1 };

static short letter_offsets[26] = {
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1, -1, -1, -1, -1, -1, -1,
	-1, -1 };

static u_char funcvals[] = {
	ATTRIB_BLEEP_DEC, ATTRIB_BLEEP_INC, BLEEPS_DEC, BLEEPS_INC,
	SAY_FIRST_CHAR, SAY_LAST_CHAR, SAY_CHAR, SAY_CHAR_NUM,
	SAY_NEXT_CHAR, SAY_PHONETIC_CHAR, SAY_PREV_CHAR, SPEAKUP_PARKED,
	SPEAKUP_CUT, EDIT_DELIM, EDIT_EXNUM, EDIT_MOST,
	EDIT_REPEAT, EDIT_SOME, SPEAKUP_GOTO, BOTTOM_EDGE,
	LEFT_EDGE, RIGHT_EDGE, TOP_EDGE, SPEAKUP_HELP,
	SAY_LINE, SAY_NEXT_LINE, SAY_PREV_LINE, SAY_LINE_INDENT,
	SPEAKUP_PASTE, PITCH_DEC, PITCH_INC, PUNCT_DEC,
	PUNCT_INC, PUNC_LEVEL_DEC, PUNC_LEVEL_INC, SPEAKUP_QUIET,
	RATE_DEC, RATE_INC, READING_PUNC_DEC, READING_PUNC_INC,
	SAY_ATTRIBUTES, SAY_FROM_LEFT, SAY_FROM_TOP, SAY_POSITION,
	SAY_SCREEN, SAY_TO_BOTTOM, SAY_TO_RIGHT, SPK_KEY,
	SPK_LOCK, SPEAKUP_OFF, SPEECH_KILL, SPELL_DELAY_DEC,
	SPELL_DELAY_INC, SPELL_WORD, SPELL_PHONETIC, TONE_DEC,
	TONE_INC, VOICE_DEC, VOICE_INC, VOL_DEC,
	VOL_INC, CLEAR_WIN, SAY_WIN, SET_WIN,
	ENABLE_WIN, SAY_WORD, SAY_NEXT_WORD, SAY_PREV_WORD, 0
};

static u_char *state_tbl;
static int cur_item, nstates;

static void build_key_data(void)
{
	u_char *kp, counters[MAXFUNCS], ch, ch1;
	u16 *p_key, key;
	int i, offset = 1;

	nstates = (int)(state_tbl[-1]);
	memset(counters, 0, sizeof(counters));
	memset(key_offsets, 0, sizeof(key_offsets));
	kp = state_tbl + nstates + 1;
	while (*kp++) {
		/* count occurrences of each function */
		for (i = 0; i < nstates; i++, kp++) {
			if (!*kp)
				continue;
			if ((state_tbl[i] & 16) != 0 && *kp == SPK_KEY)
				continue;
			counters[*kp]++;
		}
	}
	for (i = 0; i < MAXFUNCS; i++) {
		if (counters[i] == 0)
			continue;
		key_offsets[i] = offset;
		offset += (counters[i] + 1);
		if (offset >= MAXKEYS)
			break;
	}
/* leave counters set so high keycodes come first.
 * this is done so num pad and other extended keys maps are spoken before
 * the alpha with speakup type mapping.
 */
	kp = state_tbl + nstates + 1;
	while ((ch = *kp++)) {
		for (i = 0; i < nstates; i++) {
			ch1 = *kp++;
			if (!ch1)
				continue;
			if ((state_tbl[i] & 16) != 0 && ch1 == SPK_KEY)
				continue;
			key = (state_tbl[i] << 8) + ch;
			counters[ch1]--;
			offset = key_offsets[ch1];
			if (!offset)
				continue;
			p_key = key_data + offset + counters[ch1];
			*p_key = key;
		}
	}
}

static void say_key(int key)
{
	int i, state = key >> 8;

	key &= 0xff;
	for (i = 0; i < 6; i++) {
		if (state & masks[i])
			synth_printf(" %s", spk_msg_get(MSG_STATES_START + i));
	}
	if ((key > 0) && (key <= num_key_names))
		synth_printf(" %s\n",
			     spk_msg_get(MSG_KEYNAMES_START + (key - 1)));
}

static void help_init(void)
{
	char start = SPACE;
	int i;
	int num_funcs = MSG_FUNCNAMES_END - MSG_FUNCNAMES_START + 1;

	state_tbl = spk_our_keys[0] + SHIFT_TBL_SIZE + 2;
	for (i = 0; i < num_funcs; i++) {
		char *cur_funcname = spk_msg_get(MSG_FUNCNAMES_START + i);
		char first_letter;

		first_letter = tolower(*cur_funcname);

		/* Accept only 'a'..'z' to index letter_offsets[] safely */
		if (first_letter < 'a' || first_letter > 'z')
			continue;

		if (start == first_letter)
			continue;
		start = first_letter;
		letter_offsets[(start & 31) - 1] = i;
	}
}

int spk_handle_help(struct vc_data *vc, u_char type, u_char ch, u16 key)
{
	int i, n;
	char *name;
	u_char func, *kp;
	u16 *p_keys, val;

	if (letter_offsets[0] == -1)
		help_init();
	if (type == KT_LATIN) {
		if (ch == SPACE) {
			spk_special_handler = NULL;
			synth_printf("%s\n", spk_msg_get(MSG_LEAVING_HELP));
			return 1;
		}
		ch = tolower(ch);
		if (ch < 'a' || ch > 'z')
			return -1;
		if (letter_offsets[ch - 'a'] == -1) {
			synth_printf(spk_msg_get(MSG_NO_COMMAND), ch);
			synth_printf("\n");
			return 1;
		}
		cur_item = letter_offsets[ch - 'a'];
	} else if (type == KT_CUR) {
		if (ch == 0 &&
		    (MSG_FUNCNAMES_START + cur_item + 1) <= MSG_FUNCNAMES_END)
			cur_item++;
		else if (ch == 3 && cur_item > 0)
			cur_item--;
		else
			return -1;
	} else if (type == KT_SPKUP && ch == SPEAKUP_HELP &&
		   !spk_special_handler) {
		spk_special_handler = spk_handle_help;
		synth_printf("%s\n", spk_msg_get(MSG_HELP_INFO));
		build_key_data(); /* rebuild each time in case new mapping */
		return 1;
	} else {
		name = NULL;
		if ((type != KT_SPKUP) && (key > 0) && (key <= num_key_names)) {
			synth_printf("%s\n",
				     spk_msg_get(MSG_KEYNAMES_START + key - 1));
			return 1;
		}
		for (i = 0; funcvals[i] != 0 && !name; i++) {
			if (ch == funcvals[i])
				name = spk_msg_get(MSG_FUNCNAMES_START + i);
		}
		if (!name)
			return -1;
		kp = spk_our_keys[key] + 1;
		for (i = 0; i < nstates; i++) {
			if (ch == kp[i])
				break;
		}
		key += (state_tbl[i] << 8);
		say_key(key);
		synth_printf(spk_msg_get(MSG_KEYDESC), name);
		synth_printf("\n");
		return 1;
	}
	name = spk_msg_get(MSG_FUNCNAMES_START + cur_item);
	func = funcvals[cur_item];
	synth_printf("%s", name);
	if (key_offsets[func] == 0) {
		synth_printf(" %s\n", spk_msg_get(MSG_IS_UNASSIGNED));
		return 1;
	}
	p_keys = key_data + key_offsets[func];
	for (n = 0; p_keys[n]; n++) {
		val = p_keys[n];
		if (n > 0)
			synth_printf("%s ", spk_msg_get(MSG_DISJUNCTION));
		say_key(val);
	}
	return 1;
}
