/*
 * MultiMail offline mail reader
 * help windows

 Copyright (c) 1996 Kolossvary Tamas <thomas@vma.bme.hu>
 Copyright (c) 1999 William McBrine <wmcbrine@clark.net>

 Distributed under the GNU General Public License.
 For details, see the file COPYING in the parent directory. */

#include "interfac.h"

HelpWindow::HelpWindow()
{
	baseReset();
}

void HelpWindow::newHelpMenu(const char **keys, const char **func, int it)
{
	int x, y, z, end;

	items = it;

	menu = new Win(3, COLS - 2, LINES - 4, C_HELP2);

	midpos = (COLS / 2) - 6;
	endpos = COLS - 21;

	if (items < 10)
		end = items;
	else {
		end = base + 8;
		if (end > items)
			end = items;
	}
	for (z = base; z < end; z++) {
		if (keys[z]) {
			x = (z - base) / 3;
			switch ((z - base) % 3) {
			case 0:
				y = 2;
				break;
			case 1:
				y = midpos;
				break;
			default:
				y = endpos;
			}
			menu->attrib(C_HELP1);
			menu->put(x, y, ": ");
			menu->put(x, y + 2, func[z]);

			y -= strlen(keys[z]);

			menu->attrib(C_HELP2);
			menu->put(x, y, keys[z]);
		}
	}
	if (items > 9) {
		menu->put(2, endpos - 1, "O");
		menu->attrib(C_HELP1);
		menu->put(2, endpos, ": Other functions");
	}
	menu->delay_update();
}

void HelpWindow::h_packetlist()
{
	static const char *keys[] = {
		"Q", "Enter", "S, $",
		"K", "A", "^T",
		"U", "/, .", 

		"-", "+", 0,
		"B", "Space, F"
	}, *func[] = {
		"Quit", "select packet", "change Sort type", 
		"Kill packet", "Addressbook", "Tagline editor",
		"Update list", "search / next",

		"alias for Left", "alias for Right", 0,
		"alias for PgUp", "aliases for PgDn"
	};

	newHelpMenu(keys, func, 13);
}

void HelpWindow::h_arealist()
{
	static const char *keys[] = {
		"Q", "Enter", "F2, !",
		"E", "A", "^T",
		"L", "Left", "Right"
	}, *func[] = {
		"back to packet list", "select area", "Make reply packet",
		"Enter letter in area", "Addressbook", "Tagline editor",
		"Long/short area list",  "prev non-empty", "next non-empty"
	};

	newHelpMenu(keys, func, 9);
}

void HelpWindow::h_letterlist()
{
	static const char *keys[] = {
		"L", "Enter", "$",
		"E",  "^F", "S",
		"U", "M",

		0, "A", "^T", 
		0, "Left", "Right"
	}, *func[] = {
		"List all/unread", "read letter", "change sort type",
		"Enter letter in area", "Forward letter", "Save (all/marked)",
		"Unread/read toggle", "Mark/unmark",

		0, "Addressbook", "Tagline editor",
		0, "previous unread", "next unread"
	}, *repkeys[] = {
		"K", "Enter", "$",
		"E", "^F", "S",
		0, "A", "^T"
	}, *repfunc[] = {
		"Kill letter", "read letter", "change sort type", 
		"Edit letter", "Forward letter", "Save (all/marked)",
		0, "Addressbook", "Tagline editor"
	};

	if (!mm.areaList->isReplyArea())
		newHelpMenu(keys, func, 14);
	else
		newHelpMenu(repkeys, repfunc, 9);
}

void HelpWindow::h_letter(bool isAnsi)
{
	const int width = 60, citems = 14, regitems = 7,
		repitems = 2, ansitems = 9;

	static const char *common[citems] = {
		"S - Save letter",
		"A - Addressbook",
		"C - toggle Character set",
		"D - Decrypt (rot13) toggle",
		"X - eXtra (hidden) lines",
		"^T - Tagline editor",
		"^F - Forward letter",
		"V, ^V, ^A - ANSI viewer",
		"/ - start a search",
		". - repeat last search",
		"Left - previous letter",
		"Right, Enter - next letter",
		"Space - page through area",
		"Q - back to letter list"
	}, *regular[] = {
		"E - Enter letter",
		"R - Reply to letter",
		"O - reply to Original sender",
		"N - Netmail/Internet reply",
		"T - Take tagline",
		"M - Mark/unmark letter",
		"U - Unread/read toggle"
	}, *reply[] = {
		"K - Kill letter",
		"E, R - [Re-]Edit letter"
	}, *ansi[] = {
		"S - Save to file",
		"C - toggle Character set",
		"V, ^V, ^A - Animate",
		"/ - start a search",
		". - repeat last search",
		"Space - page down/next",
		"Left - previous",
		"Right - next",
		"Q - Quit ANSI viewer"
	};

	int base = isAnsi ? ansitems : mm.areaList->isReplyArea() ?
		repitems : regitems;
	int usecommon = isAnsi ? 0 : citems;
	int height = ((base + usecommon + 1) >> 1) + 4;

	menu = new ShadowedWin(height, width, (LINES - height) >> 1,
		C_HELP3);
	menu->attrib(C_HELP4);

	const char **basechar = isAnsi ? ansi :
		((base == 7) ? regular : reply);

	int line = 0;

	for (int x = 0; x < base; x++) {
		if (!(x & 1))
			line++;
		menu->put(line, (x & 1) ? (width >> 1) + 2 : 2,
			basechar[x]);
	}

	for (int x = base; x < usecommon + base; x++) {
		if (!(x & 1))
			line++;
		menu->put(line, (x & 1) ? (width >> 1) + 2 : 2,
			common[x - base]);
	}

	menu->put(line + 2, 2,
		"Plus the standard direction keys");

	menu->wtouch();
}

void HelpWindow::MakeActive()
{
	switch (interface->active()) {
	case ansi_help:
		h_letter(true);
		break;
	case letter_help:
		h_letter(false);
		break;
	case letterlist:
		h_letterlist();
		break;
	case arealist:
		h_arealist();
		break;
	case packetlist:
		h_packetlist();
	default:;
	}
}

void HelpWindow::Delete()
{
	switch (interface->active()) {
	case ansi_help:
	case letter_help:
		delete (ShadowedWin *) menu;
		break;
	case letterlist:
	case arealist:
	case packetlist:
		delete menu;
	default:;
	}
}

void HelpWindow::baseNext()
{
	if (items > 9) {
		base += 8;
		if (base > (items - 1))
			base = 0;
	}
	Delete();
	MakeActive();
}

void HelpWindow::baseReset()
{
	base = 0;
}
