Skip to content
Snippets Groups Projects
DDMsgReader.js 699 KiB
Newer Older
						}
					}
					// Set the hotkey help line again, as this sub-board might have
					// different settings for whether messages can be edited or deleted,
					// then refresh it on the screen.
					var oldHotkeyHelpLine = this.enhReadHelpLine;
					this.SetEnhancedReaderHelpLine();
					// If a search is is specified that would populate the search
					// results, then populate this.msgSearchHdrs for the current
					// sub-board if there is search text specified.  If there
					// are no search results, then ask the user if they want
					// to continue searching the message areas.
					if (this.SearchTypePopulatesSearchResults())
					{
						if (this.PopulateHdrsIfSearch_DispErrorIfNoMsgs(false, true, false))
						{
							retObj.changedMsgArea = true;
							continueGoingToNextSubBoard = false;
							retObj.msgIndex = 0;
							if (this.scrollingReaderInterface && console.term_supports(USER_ANSI))
								this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, pAllowChgMsgArea);
						}
						else // No search results in this sub-board
						{
							continueGoingToNextSubBoard = !console.noyes("Continue searching");
							if (!continueGoingToNextSubBoard)
							{
								retObj.shouldStopReading = true;
								return retObj;
							}
						}
					}
				}
				else // The message base failed to open
				{
					console.clear("\1n");
					console.print("\1h\1y* \1wUnable to open message sub-board:");
					console.crlf();
					console.print(subBoardGrpAndName(this.subBoardCode));
					console.crlf();
					console.pause();
					retObj.shouldStopReading = true;
					continueGoingToNextSubBoard = false;
					return retObj;
				}
			}
			else
			{
				// Didn't find later sub-board with readable messages.
				// We could stop and exit the script here by doing the following,
				// but I'd rather let the user exit when they want to.
				//retObj.shouldStopReading = true;
				//return retObj;

				continueGoingToNextSubBoard = false;
				// Show a message telling the user that there are no more
				// messages or sub-boards.  Then, refresh the hotkey help line.
				writeWithPause(this.msgAreaLeft, console.screen_rows,
									"\1n\1h\1y* No more messages or message areas.",
									ERROR_PAUSE_WAIT_MS, "\1n", true);
				if (this.scrollingReaderInterface && console.term_supports(USER_ANSI))
					this.DisplayEnhancedMsgReadHelpLine(console.screen_rows, pAllowChgMsgArea);
			}
		}
	}

	return retObj;
}

// For the DigDistMsgReader Class: Prepares the variables that keep track of the
// traditional-interface message list position, current messsage number, etc.
function DigDistMsgReader_SetUpTraditionalMsgListVars()
{
	// If a search is specified, then just start at the first message.
	// If no search is specified, then get the index of the user's last read
	// message.  Then, figure out which page it's on and set the lightbar list
	// index & cursor position variables accordingly.
	var lastReadMsgIdx = 0;
	if (!this.SearchingAndResultObjsDefinedForCurSub())
	{
		lastReadMsgIdx = this.GetLastReadMsgIdx();
		if (lastReadMsgIdx == -1)
			lastReadMsgIdx = 0;
	}
	var pageNum = findPageNumOfItemNum(lastReadMsgIdx+1, this.tradMsgListNumLines, this.NumMessages(),
	this.CalcTraditionalMsgListTopIdx(pageNum);
	if (!this.reverseListOrder && (this.tradListTopMsgIdx > lastReadMsgIdx))
		this.tradListTopMsgIdx -= this.tradMsgListNumLines;
}

// For the DigDistMsgReader Class: Prepares the variables that keep track of the
// lightbar message list position, current messsage number, etc.
function DigDistMsgReader_SetUpLightbarMsgListVars()
{
	// If no search is specified or if reading personal email, then get the index
	// of the user's last read message.  Then, figure out which page it's on and
	// set the lightbar list index & cursor position variables accordingly.
	if (!this.SearchingAndResultObjsDefinedForCurSub() || this.readingPersonalEmail)
	{
		lastReadMsgIdx = this.GetLastReadMsgIdx();
		if (lastReadMsgIdx == -1)
			lastReadMsgIdx = 0;
	}
	else
	{
		// A search was specified.  If reading personal email, then set the
		// message index to the last read message.
		if (this.readingPersonalEmail)
		{
			lastReadMsgIdx = this.GetLastReadMsgIdx();
			if (lastReadMsgIdx == -1)
				lastReadMsgIdx = 0;
		}
	}
	var pageNum = findPageNumOfItemNum(lastReadMsgIdx+1, this.lightbarMsgListNumLines, this.NumMessages(),
	this.CalcLightbarMsgListTopIdx(pageNum);
	var initialCursorRow = 0;
		initialCursorRow = this.lightbarMsgListStartScreenRow+(this.lightbarListTopMsgIdx-lastReadMsgIdx);
	else
	{
		if (this.lightbarListTopMsgIdx > lastReadMsgIdx)
			this.lightbarListTopMsgIdx -= this.lightbarMsgListNumLines;
		initialCursorRow = this.lightbarMsgListStartScreenRow+(lastReadMsgIdx-this.lightbarListTopMsgIdx);
	}
	this.lightbarListSelectedMsgIdx = lastReadMsgIdx;
	this.lightbarListCurPos = { x: 1, y: initialCursorRow };
}

// For the DigDistMsgReader Class: Writes the message list column headers at the
// top of the screen.
function DigDistMsgReader_WriteMsgListScreenTopHeader()
{
	console.home();

	// If we will be displaying the message group and sub-board in the
	// header at the top of the screen (an additional 2 lines), then
	// update nMaxLines and nListStartLine to account for this.
	if (this.displayBoardInfoInHeader && canDoHighASCIIAndANSI()) // console.term_supports(USER_ANSI)
	{
		var curpos = console.getxy();
		var msgGroupName = "";
		// For the message group name, we can also use this.msgbase.cfg.grp_name in
		// Synchronet 3.12 and higher.
		if (this.msgbase.cfg != null)
			msgGroupName = msg_area.grp_list[this.msgbase.cfg.grp_number].description;
		else
			msgGroupName = "Unspecified";
		// Figure out the sub-board name
		var subBoardName = "";
		if (this.msgbase.cfg != null)
			subBoardName = this.msgbase.cfg.description;
		else if ((this.msgbase.subnum == -1) || (this.msgbase.subnum == 65535))
			subBoardName = "Electronic Mail";
		else
			subBoardName = "Unspecified";
		// Display the message group name
		console.print(this.colors["msgListHeaderMsgGroupTextColor"] + "Msg group: " +
		this.colors["msgListHeaderMsgGroupNameColor"] + msgGroupName);
		console.cleartoeol(); // Fill to the end of the line with the current colors
		// Display the sub-board name on the next line
		++curpos.y;
		console.gotoxy(curpos);
		console.print(this.colors["msgListHeaderSubBoardTextColor"] + "Sub-board: " +
		this.colors["msgListHeaderMsgSubBoardName"] + subBoardName);
		console.cleartoeol(); // Fill to the end of the line with the current colors
		++curpos.y;
		console.gotoxy(curpos);
	}

	// Write the message listing column headers
	printf(this.colors["msgListColHeader"] + this.sHdrFormatStr, "Msg#", "From", "To", "Subject", "Date", "Time");

	// Set the normal text attribute
	console.print("\1n");
}
// For the DigDistMsgReader Class: Lists a screenful of message header information.
//
// Parameters:
//  pTopIndex: The index (offset) of the top message
//  pMaxLines: The maximum number of lines to output to the screen
//
// Return value: Boolean, whether or not the last message output to the
//               screen is the last message in the sub-board.
function DigDistMsgReader_ListScreenfulOfMessages(pTopIndex, pMaxLines)
{

	var curpos = console.getxy();
	var msgIndex = 0;
		var endIndex = pTopIndex - pMaxLines + 1; // The index of the last message to display
		for (msgIndex = pTopIndex; (msgIndex >= 0) && (msgIndex >= endIndex); --msgIndex)
		{
			// The following line which sets console.line_counter to 0 is a
			// kludge to disable Synchronet's automatic pausing after a
			// screenful of text, so that this script can have more control
			// over screen pausing.
			console.line_counter = 0;
			// Get the message header (it will be a MsgHeader object) and
			// display it.
			msgHeader = this.GetMsgHdrByIdx(msgIndex);
			if (msgHeader == null)
				continue;

			// Display the message info
			this.PrintMessageInfo(msgHeader, false, msgIndex+1);
			if (console.term_supports(USER_ANSI))
			{
				++curpos.y;
				console.gotoxy(curpos);
			}
			else
				console.crlf();
		var endIndex = pTopIndex + pMaxLines; // One past the last message index to display
		for (msgIndex = pTopIndex; (msgIndex < this.NumMessages()) && (msgIndex < endIndex); ++msgIndex)
		{
			// The following line which sets console.line_counter to 0 is a
			// kludge to disable Synchronet's automatic pausing after a
			// screenful of text, so that this script can have more control
			// over screen pausing.
			console.line_counter = 0;
			// Get the message header (it will be a MsgHeader object) and
			// display it.
			msgHeader = this.GetMsgHdrByIdx(msgIndex);
			if (msgHeader == null)
				continue;

			// Display the message info
			this.PrintMessageInfo(msgHeader, false, msgIndex+1);
			if (console.term_supports(USER_ANSI))
			{
				++curpos.y;
				console.gotoxy(curpos);
			}
			else
				console.crlf();
		atLastPage = (msgIndex == this.NumMessages());
	}
// For the DigDistMsgReader Class: Displays the help screen for the message list.
//  pChgSubBoardAllowed: Whether or not changing to another sub-board is allowed
//  pPauseAtEnd: Boolean, whether or not to pause at the end.
function DigDistMsgReader_DisplayMsgListHelp(pChgSubBoardAllowed, pPauseAtEnd)
{
	DisplayProgramInfo();

	// Display help specific to which interface is being used.
	if (this.msgListUseLightbarListInterface)
		this.DisplayLightbarMsgListHelp(false, pChgSubBoardAllowed);
		this.DisplayTraditionalMsgListHelp(false, pChgSubBoardAllowed);

	// If pPauseAtEnd is true, then output a newline and
	// prompt the user whether or not to continue.
	if (pPauseAtEnd)
		console.pause();
}
// For the DigDistMsgReader Class: Displays help for the traditional-interface
// message list
//
// Parameters:
//  pDisplayHeader: Whether or not to display a help header at the beginning
//  pChgSubBoardAllowed: Whether or not changing to another sub-board is allowed
//  pPauseAtEnd: Boolean, whether or not to pause at the end.
function DigDistMsgReader_DisplayTraditionalMsgListHelp(pDisplayHeader, pChgSubBoardAllowed, pPauseAtEnd)
{
	// If pDisplayHeader is true, then display the program information.
	if (pDisplayHeader)
		DisplayProgramInfo();

	// Display information about the current sub-board and search results.
	console.print("\1n\1cCurrently reading \1g" + subBoardGrpAndName(this.subBoardCode));
	console.crlf();
	// If the user isn't reading personal messages (i.e., is reading a sub-board),
	// then output the total number of messages in the sub-board.  We probably
	// shouldn't output the total number of messages in the "mail" area, because
	// that includes more than the current user's email.
	if (this.subBoardCode != "mail")
	{
		console.print("\1n\1cThere are a total of \1g" + this.msgbase.total_msgs + " \1cmessages in the current area.");
		console.crlf();
	}
	// If there is currently a search (which also includes personal messages),
	// then output the number of search results/personal messages.
	if (this.SearchingAndResultObjsDefinedForCurSub())
	{
		var numSearchResults = this.NumMessages();
		var resultsWord = (numSearchResults > 1 ? "results" : "result");
		console.print("\1n\1c");
		if (this.readingPersonalEmail)
			console.print("You have \1g" + numSearchResults + " \1c" + (numSearchResults == 1 ? "message" : "messages") + ".");
		else
		{
			if (numSearchResults == 1)
				console.print("There is \1g1 \1csearch result.");
			else
				console.print("There are \1g" + numSearchResults + " \1csearch results.");
		}
		console.crlf();
	}
	console.crlf();

	console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"]);
	displayTextWithLineBelow("Page navigation and message selection", false,
	                         this.colors["tradInterfaceHelpScreenColor"], "\1k\1h");
	console.print(this.colors["tradInterfaceHelpScreenColor"]);
	console.print("The message lister will display a page of message header information.  At\r\n");
	console.print("the end of each page, a prompt is displayed, allowing you to navigate to\r\n");
	console.print("the next page, previous page, first page, or the last page.  If you would\r\n");
	console.print("like to read a message, you may type the message number, followed by\r\n");
	console.print("the enter key if the message number is short.  To quit the listing, press\r\n");
	console.print("the Q key.\r\n\r\n");
	this.DisplayMessageListNotesHelp();
	console.crlf();
	console.crlf();
	displayTextWithLineBelow("Summary of the keyboard commands:", false,
	                         this.colors["tradInterfaceHelpScreenColor"], "\1k\1h");
	console.print(this.colors["tradInterfaceHelpScreenColor"]);
	console.print("\1n\1h\1cN" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the next page\r\n");
	console.print("\1n\1h\1cP" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the previous page\r\n");
	console.print("\1n\1h\1cF" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the first page\r\n");
	console.print("\1n\1h\1cL" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the last page\r\n");
	console.print("\1n\1h\1cG" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to a specific message by number (the message will appear at the top\r\n" +
	              "   of the list)\r\n");
	console.print("\1n\1h\1cNumber" + this.colors["tradInterfaceHelpScreenColor"] + ": Read the message corresponding with that number\r\n");
	//console.print("The following commands are available only if you have permission to do so:\r\n");
	if (this.CanDelete() || this.CanDeleteLastMsg())
		console.print("\1n\1h\1cD" + this.colors["tradInterfaceHelpScreenColor"] + ": Mark a message for deletion\r\n");
	if (this.CanEdit())
		console.print("\1n\1h\1cE" + this.colors["tradInterfaceHelpScreenColor"] + ": Edit an existing message\r\n");
	if (pChgSubBoardAllowed)
		console.print("\1n\1h\1cC" + this.colors["tradInterfaceHelpScreenColor"] + ": Change to another message sub-board\r\n");
	console.print("\1n\1h\1cS" + this.colors["tradInterfaceHelpScreenColor"] + ": Select messages (for batch delete, etc.)\r\n");
	console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + "  A message number or multiple numbers can be entered separated by commas or\r\n");
	console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + "  spaces.  Additionally, a range of numbers (separated by a dash) can be used.\r\n");
	console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + "  Examples:\r\n");
	console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + "  125\r\n");
	console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + "  1,2,3\r\n");
	console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + "  1 2 3\r\n");
	console.print("\1n" + this.colors["tradInterfaceHelpScreenColor"] + "  1,2,10-20\r\n");
	console.print("\1n\1h\1cCTRL-D" + this.colors["tradInterfaceHelpScreenColor"] + ": Batch delete selected messages\r\n");
	console.print("\1n\1h\1cQ" + this.colors["tradInterfaceHelpScreenColor"] + ": Quit\r\n");
	console.print("\1n\1h\1c?" + this.colors["tradInterfaceHelpScreenColor"] + ": Show this help screen\r\n\r\n");

	// If pPauseAtEnd is true, then output a newline and
	// prompt the user whether or not to continue.
	if (pPauseAtEnd)
		console.pause();
}
// For the DigDistMsgReader Class: Displays help for the lightbar message list
//
// Parameters:
//  pDisplayHeader: Whether or not to display a help header at the beginning
//  pChgSubBoardAllowed: Whether or not changing to another sub-board is allowed
//  pPauseAtEnd: Boolean, whether or not to pause at the end.
function DigDistMsgReader_DisplayLightbarMsgListHelp(pDisplayHeader, pChgSubBoardAllowed, pPauseAtEnd)
{
	// If pDisplayHeader is true, then display the program information.
	if (pDisplayHeader)
		DisplayProgramInfo();

	// Display information about the current sub-board and search results.
	console.print("\1n\1cCurrently reading \1g" + subBoardGrpAndName(this.subBoardCode));
	console.crlf();
	// If the user isn't reading personal messages (i.e., is reading a sub-board),
	// then output the total number of messages in the sub-board.  We probably
	// shouldn't output the total number of messages in the "mail" area, because
	// that includes more than the current user's email.
	if (this.subBoardCode != "mail")
	{
		console.print("\1n\1cThere are a total of \1g" + this.msgbase.total_msgs + " \1cmessages in the current area.");
		console.crlf();
	}
	// If there is currently a search (which also includes personal messages),
	// then output the number of search results/personal messages.
	if (this.SearchingAndResultObjsDefinedForCurSub())
	{
		var numSearchResults = this.NumMessages();
		var resultsWord = (numSearchResults > 1 ? "results" : "result");
		console.print("\1n\1c");
		if (this.readingPersonalEmail)
			console.print("You have \1g" + numSearchResults + " \1c" + (numSearchResults == 1 ? "message" : "messages") + ".");
		else
		{
			if (numSearchResults == 1)
				console.print("There is \1g1 \1csearch result.");
			else
				console.print("There are \1g" + numSearchResults + " \1csearch results.");
		}
		console.crlf();
	}
	console.crlf();

	displayTextWithLineBelow("Lightbar interface: Page navigation and message selection",
	                         false, this.colors["tradInterfaceHelpScreenColor"], "\1k\1h");
	console.print(this.colors["tradInterfaceHelpScreenColor"]);
	console.print("The message lister will display a page of message header information.  You\r\n");
	console.print("may use the up and down arrows to navigate the list of messages.  The\r\n");
	console.print("currently-selected message will be highlighted as you navigate through\r\n");
	console.print("the list.  To read a message, navigate to the desired message and press\r\n");
	console.print("the enter key.  You can also read a message by typing its message number.\r\n");
	console.print("To quit out of the message list, press the Q key.\r\n\r\n");
	this.DisplayMessageListNotesHelp();
	console.crlf();
	console.crlf();
	displayTextWithLineBelow("Summary of the keyboard commands:", false, this.colors["tradInterfaceHelpScreenColor"], "\1k\1h");
	console.print(this.colors["tradInterfaceHelpScreenColor"]);
	console.print("\1n\1h\1cDown arrow" + this.colors["tradInterfaceHelpScreenColor"] + ": Move the cursor down/select the next message\r\n");
	console.print("\1n\1h\1cUp arrow" + this.colors["tradInterfaceHelpScreenColor"] + ": Move the cursor up/select the previous message\r\n");
	console.print("\1n\1h\1cN" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the next page\r\n");
	console.print("\1n\1h\1cP" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the previous page\r\n");
	console.print("\1n\1h\1cF" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the first page\r\n");
	console.print("\1n\1h\1cL" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to the last page\r\n");
	console.print("\1n\1h\1cG" + this.colors["tradInterfaceHelpScreenColor"] + ": Go to a specific message by number (the message will be highlighted and\r\n" +
	              "   may appear at the top of the list)\r\n");
	console.print("\1n\1h\1cENTER" + this.colors["tradInterfaceHelpScreenColor"] + ": Read the selected message\r\n");
	console.print("\1n\1h\1cNumber" + this.colors["tradInterfaceHelpScreenColor"] + ": Read the message corresponding with that number\r\n");
	if (this.CanDelete() || this.CanDeleteLastMsg())
		console.print("\1n\1h\1cDEL" + this.colors["tradInterfaceHelpScreenColor"] + ": Mark the selected message for deletion\r\n");
	if (this.CanEdit())
		console.print("\1n\1h\1cE" + this.colors["tradInterfaceHelpScreenColor"] + ": Edit the selected message\r\n");
	if (pChgSubBoardAllowed)
		console.print("\1n\1h\1cC" + this.colors["tradInterfaceHelpScreenColor"] + ": Change to another message sub-board\r\n");
	console.print("\1n\1h\1cSpacebar" + this.colors["tradInterfaceHelpScreenColor"] + ": Select message (for batch delete, etc.)\r\n");
	console.print("\1n\1h\1cCTRL-A" + this.colors["tradInterfaceHelpScreenColor"] + ": Select/de-select all messages\r\n");
	console.print("\1n\1h\1cCTRL-D" + this.colors["tradInterfaceHelpScreenColor"] + ": Batch delete selected messages\r\n");
	console.print("\1n\1h\1cQ" + this.colors["tradInterfaceHelpScreenColor"] + ": Quit\r\n");
	console.print("\1n\1h\1c?" + this.colors["tradInterfaceHelpScreenColor"] + ": Show this help screen\r\n");

	// If pPauseAtEnd is true, then pause.
	if (pPauseAtEnd)
		console.pause();
}
// For the DigDistMsgReader class: Displays the message list notes for the
// help screens.
function DigDistMsgReader_DisplayMessageListNotesHelp()
{
	displayTextWithLineBelow("Notes about the message list:", false,
	                         this.colors["tradInterfaceHelpScreenColor"], "\1n\1k\1h")
	console.print(this.colors["tradInterfaceHelpScreenColor"]);
	console.print("If a message has been marked for deletion, it will appear with a blinking\r\n");
	console.print("red asterisk (\1n\1h\1r\1i*" + "\1n" + this.colors["tradInterfaceHelpScreenColor"] + ") in");
	console.print(" after the message number in the message list.");
}
// For the DigDistMsgReader Class: Sets the traditional UI pause prompt text
// strings, sLightbarModeHelpLine, the text string for the lightbar help line,
// for the message lister interface.  This checks with this.msgbase to determine
// if the user is allowed to delete or edit messages, and if so, adds the
// appropriate keys to the prompt & help text.
function DigDistMsgReader_SetMsgListPauseTextAndLightbarHelpLine()
{
	/*
	var helpLineHotkeyColor = "\1r";
	var helpLineNormalColor = "\1b";
	var helpLineParenColor = "\1m";
	*/
	/*
	this.colors.lightbarMsgListHelpLineGeneralColor
	this.colors.lightbarMsgListHelpLineHotkeyColor
	this.colors.lightbarMsgListHelpLineParenColor
	*/

	if ((this.msgbase != null) && (this.msgbase.is_open))
	{
		// Set the traditional UI pause prompt text.
		// If the user can delete messages, then append D as a valid key.
		// If the user can edit messages, then append E as a valid key.
		this.sStartContinuePrompt = "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "N\1n\1c)"
		                          + this.colors["tradInterfaceContPromptMainColor"]
		                          + "ext, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "L\1n\1c)"
		                          + this.colors["tradInterfaceContPromptMainColor"]
		                          + "ast, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "G\1n\1c)"
		                          + this.colors["tradInterfaceContPromptMainColor"] + "o, ";
		if (this.CanDelete() || this.CanDeleteLastMsg())
		{
			this.sStartContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"]
			                          + "D\1n\1c)" + this.colors["tradInterfaceContPromptMainColor"] + "el, ";
		}
		if (this.CanEdit())
		{
			this.sStartContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"]
			                          + "E\1n\1c)" + this.colors["tradInterfaceContPromptMainColor"] + "dit, ";
		}
		this.sStartContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "S\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "el, ";
		this.sStartContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "Q\1n\1c)"
		                          + this.colors["tradInterfaceContPromptMainColor"]
		                          + "uit, msg" + this.colors["tradInterfaceContPromptHotkeyColor"] + "#" +
		                          this.colors["tradInterfaceContPromptMainColor"] + ", " + this.colors["tradInterfaceContPromptHotkeyColor"]
		                          + "?" + this.colors["tradInterfaceContPromptMainColor"] + ": "
		                          		+ this.colors["tradInterfaceContPromptUserInputColor"];

		this.sContinuePrompt = "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "N\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "ext, \1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "P\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "rev, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "F\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "irst, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "L\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "ast, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "G\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"] + "o, ";
		if (this.CanDelete() || this.CanDeleteLastMsg())
		{
			this.sContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"]
			                     + "D\1n\1c)" + this.colors["tradInterfaceContPromptMainColor"] + "el, ";
		}
		if (this.CanEdit())
		{
			this.sContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"]
			                     + "E\1n\1c)" + this.colors["tradInterfaceContPromptMainColor"] + "dit, ";
		}
		this.sContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "S\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "el, ";
		this.sContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "Q\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "uit, msg" + this.colors["tradInterfaceContPromptHotkeyColor"] + "#"
		                     + this.colors["tradInterfaceContPromptMainColor"] + ", " + this.colors["tradInterfaceContPromptHotkeyColor"]
		                     + "?" + this.colors["tradInterfaceContPromptMainColor"] + ": "
		                     + this.colors["tradInterfaceContPromptUserInputColor"];

		this.sEndContinuePrompt = "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "P\1n\1c)"
		                        + this.colors["tradInterfaceContPromptMainColor"]
		                        + "rev, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "F\1n\1c)"
		                        + this.colors["tradInterfaceContPromptMainColor"]
		                        + "irst, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "G\1n\1c)"
		                        + this.colors["tradInterfaceContPromptMainColor"] + "o, ";
		if (this.CanDelete() || this.CanDeleteLastMsg())
		{
			this.sEndContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"]
			                        + "D\1n\1c)" + this.colors["tradInterfaceContPromptMainColor"] + "el, ";
		}
		if (this.CanEdit())
		{
			this.sEndContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"]
			                        + "E\1n\1c)" + this.colors["tradInterfaceContPromptMainColor"] + "dit, ";
		}
		this.sEndContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "S\1n\1c)"
		                        + this.colors["tradInterfaceContPromptMainColor"]
		                        + "el, ";
		this.sEndContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "Q\1n\1c)"
		                        + this.colors["tradInterfaceContPromptMainColor"]
		                        + "uit, msg" + this.colors["tradInterfaceContPromptHotkeyColor"] + "#"
		                        + this.colors["tradInterfaceContPromptMainColor"] + ", " + this.colors["tradInterfaceContPromptHotkeyColor"]
		                        + "?" + this.colors["tradInterfaceContPromptMainColor"] + ": "
		                        + this.colors["tradInterfaceContPromptUserInputColor"];

		this.msgListOnlyOnePageContinuePrompt = "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "G\1n\1c)"
		                                + this.colors["tradInterfaceContPromptMainColor"] + "o, ";
		if (this.CanDelete() || this.CanDeleteLastMsg())
		{
			this.msgListOnlyOnePageContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"]
			                                + "D\1n\1c)" + this.colors["tradInterfaceContPromptMainColor"] + "el, ";
		}
		if (this.CanEdit())
		{
			this.msgListOnlyOnePageContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"]
			                                + "E\1n\1c)" + this.colors["tradInterfaceContPromptMainColor"] + "dit, ";
		}
		this.msgListOnlyOnePageContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "S\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "el, ";
		this.msgListOnlyOnePageContinuePrompt += "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "Q\1n\1c)"
		                                + this.colors["tradInterfaceContPromptMainColor"]
		                                + "uit, msg" + this.colors["tradInterfaceContPromptHotkeyColor"] + "#"
6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958
		                                + this.colors["tradInterfaceContPromptMainColor"] + ", " + this.colors["tradInterfaceContPromptHotkeyColor"]
		                                + "?" + this.colors["tradInterfaceContPromptMainColor"] + ": "
		                                + this.colors["tradInterfaceContPromptUserInputColor"];

		// Set the lightbar help text for message listing
		var extraCommas = true; // Whether there's room for commas between the last options
		this.msgListLightbarModeHelpLine = this.colors.lightbarMsgListHelpLineHotkeyColor + UP_ARROW
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
								   + this.colors.lightbarMsgListHelpLineHotkeyColor + DOWN_ARROW
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
								   + this.colors.lightbarMsgListHelpLineHotkeyColor + "PgUp"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + "/"
								   + this.colors.lightbarMsgListHelpLineHotkeyColor + "Dn"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
								   + this.colors.lightbarMsgListHelpLineHotkeyColor + "ENTER"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
								   + this.colors.lightbarMsgListHelpLineHotkeyColor + "HOME"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
								   + this.colors.lightbarMsgListHelpLineHotkeyColor + "END";
		// If the user can delete messages, then append DEL as a valid key.
		if (this.CanDelete() || this.CanDeleteLastMsg())
		{
			this.msgListLightbarModeHelpLine += this.colors.lightbarMsgListHelpLineGeneralColor + ", "
			                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "DEL";
			extraCommas = false;
		}
		this.msgListLightbarModeHelpLine += this.colors.lightbarMsgListHelpLineGeneralColor
		                                 + ", " + this.colors.lightbarMsgListHelpLineHotkeyColor
		                                 + "#" + this.colors.lightbarMsgListHelpLineGeneralColor + ", ";
		// If the user can edit messages, then append E as a valid key.
		if (this.CanEdit())
		{
			this.msgListLightbarModeHelpLine += this.colors.lightbarMsgListHelpLineHotkeyColor
			                           + "E" + this.colors.lightbarMsgListHelpLineParenColor
									   + ")" + this.colors.lightbarMsgListHelpLineGeneralColor
									   + "dit ";
		}
		this.msgListLightbarModeHelpLine += this.colors.lightbarMsgListHelpLineHotkeyColor + "F"
		                           + this.colors.lightbarMsgListHelpLineParenColor + ")"
								   + this.colors.lightbarMsgListHelpLineGeneralColor + (extraCommas ? "irst pg, " : "irst pg ")
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "L"
		                           + this.colors.lightbarMsgListHelpLineParenColor + ")"
								   + this.colors.lightbarMsgListHelpLineGeneralColor
		                           + (extraCommas ? "ast pg, " : "ast pg ")
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "G"
								   + this.colors.lightbarMsgListHelpLineParenColor + ")"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + (extraCommas ? "o, " : "o ")
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "Q"
								   + this.colors.lightbarMsgListHelpLineParenColor + ")"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + (extraCommas ? "uit, " : "uit ")
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "?  ";
	}
	else
	{
		// this.msgbase is null, so construct the default pause & help text (without
		// the delete & edit keys).

		// Set the traditional UI pause prompt text
		this.sStartContinuePrompt = "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "N\1n\1c)"
		                          + this.colors["tradInterfaceContPromptMainColor"]
		                          + "ext, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "L\1n\1c)"
		                          + this.colors["tradInterfaceContPromptMainColor"]
		                          + "ast, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "Q\1n\1c)"
		                          + this.colors["tradInterfaceContPromptMainColor"]
		                          + "uit, msg " + this.colors["tradInterfaceContPromptHotkeyColor"] + "#"
		                          + this.colors["tradInterfaceContPromptMainColor"] + ", " + this.colors["tradInterfaceContPromptHotkeyColor"]
		                          + "?" + this.colors["tradInterfaceContPromptMainColor"] + ": "
		                          + this.colors["tradInterfaceContPromptUserInputColor"];
		this.sContinuePrompt = "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "N\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "ext, \1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "P\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "rev, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "F\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "irst, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "L\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "ast, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "Q\1n\1c)"
		                     + this.colors["tradInterfaceContPromptMainColor"]
		                     + "uit, msg " + this.colors["tradInterfaceContPromptHotkeyColor"] + "#"
		                     + this.colors["tradInterfaceContPromptMainColor"] + ", " + this.colors["tradInterfaceContPromptHotkeyColor"]
		                     + "?" + this.colors["tradInterfaceContPromptMainColor"] + ": "
		                     + this.colors["tradInterfaceContPromptUserInputColor"];
		this.sEndContinuePrompt = "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "P\1n\1c)"
		                        + this.colors["tradInterfaceContPromptMainColor"]
		                        + "rev, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "F\1n\1c)"
		                        + this.colors["tradInterfaceContPromptMainColor"]
		                        + "irst, \1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "Q\1n\1c)"
		                        + this.colors["tradInterfaceContPromptMainColor"]
		                        + "uit, msg " + this.colors["tradInterfaceContPromptHotkeyColor"] + "#"
		                        + this.colors["tradInterfaceContPromptMainColor"] + ", " + this.colors["tradInterfaceContPromptHotkeyColor"]
		                        + "?" + this.colors["tradInterfaceContPromptMainColor"] + ": "
		                        + this.colors["tradInterfaceContPromptUserInputColor"];
		this.msgListOnlyOnePageContinuePrompt = "\1n\1c(" + this.colors["tradInterfaceContPromptHotkeyColor"] + "Q\1n\1c)"
		                                + this.colors["tradInterfaceContPromptMainColor"]
		                                + "uit, msg " + this.colors["tradInterfaceContPromptHotkeyColor"] + "#"
		                                + this.colors["tradInterfaceContPromptMainColor"] + ", " + this.colors["tradInterfaceContPromptHotkeyColor"]
		                                + "?" + this.colors["tradInterfaceContPromptMainColor"] + ": "
		                                + this.colors["tradInterfaceContPromptUserInputColor"];

		// Set the lightbar help line
		this.msgListLightbarModeHelpLine = this.colors.lightbarMsgListHelpLineHotkeyColor + UP_ARROW
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + DOWN_ARROW
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "PgUp"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + "/"
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "Dn"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "ENTER"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "HOME"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "END"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + ", "
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "F"
		                           + this.colors.lightbarMsgListHelpLineParenColor + ")"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + "irst, "
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "L"
		                           + this.colors.lightbarMsgListHelpLineParenColor + ")"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + "ast, "
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "Q"
		                           + this.colors.lightbarMsgListHelpLineParenColor + ")"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + "uit, "
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "#"
		                           + this.colors.lightbarMsgListHelpLineGeneralColor + " or "
		                           + this.colors.lightbarMsgListHelpLineHotkeyColor + "?";
	}
	// Add spaces to the end of sLightbarModeHelpLine up until one char
	// less than the width of the screen.
	var lbHelpLineLen = console.strlen(this.msgListLightbarModeHelpLine);
	var numChars = console.screen_columns - lbHelpLineLen - 3;
	if (numChars > 0)
	{
		// Gradient block characters: °±²Û
		// Add characters on the left and right of the line so that the
		// text is centered.
		var numLeft = Math.floor(numChars / 2);
		var numRight = numChars - numLeft;
		for (var i = 0; i < numLeft; ++i)
			this.msgListLightbarModeHelpLine = "Û" + this.msgListLightbarModeHelpLine;
		this.msgListLightbarModeHelpLine = "\1n"
		                             + this.colors.lightbarMsgListHelpLineBkgColor
		                             + this.msgListLightbarModeHelpLine;
		this.msgListLightbarModeHelpLine += "\1n" + this.colors.lightbarMsgListHelpLineBkgColor;
		for (var i = 0; i < numRight; ++i)
			this.msgListLightbarModeHelpLine += "Û";
	}
}
// For the DigDistMsgReader Class: Sets the hotkey help line for the enhanced
// reader mode
function DigDistMsgReader_SetEnhancedReaderHelpLine()
{
	// Generate it differently depending on whether the message base is open or
	// not, because some options will have to be checked in the message base
	// to determine whether deleting & editing messages is allowed.
	if ((this.msgbase != null) && (this.msgbase.is_open))
	{
		this.enhReadHelpLine = this.colors.enhReaderHelpLineHotkeyColor + UP_ARROW
		                     + this.colors.enhReaderHelpLineGeneralColor + ", "
		                     + this.colors.enhReaderHelpLineHotkeyColor + DOWN_ARROW
		                     + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor + LEFT_ARROW
							 + this.colors.enhReaderHelpLineGeneralColor +", "
							 + this.colors.enhReaderHelpLineHotkeyColor + RIGHT_ARROW
							 + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor + "PgUp"
							 + this.colors.enhReaderHelpLineGeneralColor + "/"
		                     + this.colors.enhReaderHelpLineHotkeyColor + "Dn"
							 + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor + "HOME"
							 + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor + "END"
							 + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor;
		if (this.CanDelete() || this.CanDeleteLastMsg())
			this.enhReadHelpLine += "DEL" + this.colors.enhReaderHelpLineGeneralColor + ", " + this.colors.enhReaderHelpLineHotkeyColor;
		if (this.CanEdit() && (console.screen_columns > 87))
			this.enhReadHelpLine += "E" + this.colors.enhReaderHelpLineParenColor + ")" + this.colors.enhReaderHelpLineGeneralColor + "dit, " + this.colors.enhReaderHelpLineHotkeyColor;
		this.enhReadHelpLine += "F" + this.colors.enhReaderHelpLineParenColor + ")"
		                     + this.colors.enhReaderHelpLineGeneralColor + "irst, "
		                     + this.colors.enhReaderHelpLineHotkeyColor + "L"
							 + this.colors.enhReaderHelpLineParenColor + ")"
		                     + this.colors.enhReaderHelpLineGeneralColor + "ast, "
							 + this.colors.enhReaderHelpLineHotkeyColor + "R"
							 + this.colors.enhReaderHelpLineParenColor + ")"
							 + this.colors.enhReaderHelpLineGeneralColor + "eply, "
		                     + this.colors.enhReaderHelpLineHotkeyColor + "C"
							 + this.colors.enhReaderHelpLineParenColor + ")"
							 + this.colors.enhReaderHelpLineGeneralColor + "hg area, "
							 + this.colors.enhReaderHelpLineHotkeyColor + "Q"
							 + this.colors.enhReaderHelpLineParenColor + ")"
							 + this.colors.enhReaderHelpLineGeneralColor + "uit, "
							 + this.colors.enhReaderHelpLineHotkeyColor + "?";
		// Center the help text based on the console width
		var numCharsRemaining = console.screen_columns - console.strlen(this.enhReadHelpLine) - 1;
		var numCharsOnEachSide = Math.floor(numCharsRemaining/2);
		// Left side
		for (var i = 0; i < numCharsOnEachSide; ++i)
			this.enhReadHelpLine = " " + this.enhReadHelpLine;
		this.enhReadHelpLine = "\1n" + this.colors.enhReaderHelpLineBkgColor + this.enhReadHelpLine;
		// Right side
		for (var i = 0; i < numCharsOnEachSide; ++i)
			this.enhReadHelpLine += " ";
		//numCharsRemaining = console.screen_columns - console.strlen(this.enhReadHelpLine) - 5;
		numCharsRemaining = console.screen_columns - 1 - console.strlen(this.enhReadHelpLine);
		if (numCharsRemaining > 0)
		{
			for (var i = 0; i < numCharsRemaining; ++i)
			this.enhReadHelpLine += " ";
		}

		// Create a version without the change area option
		this.enhReadHelpLineWithoutChgArea = this.colors.enhReaderHelpLineHotkeyColor + UP_ARROW
		                                   + this.colors.enhReaderHelpLineGeneralColor + ", "
		                                   + this.colors.enhReaderHelpLineHotkeyColor + DOWN_ARROW
		                                   + this.colors.enhReaderHelpLineGeneralColor + ", "
										   + this.colors.enhReaderHelpLineHotkeyColor + LEFT_ARROW
										   + this.colors.enhReaderHelpLineGeneralColor + ", "
										   + this.colors.enhReaderHelpLineHotkeyColor + RIGHT_ARROW
										   + this.colors.enhReaderHelpLineGeneralColor + ", "
										   + this.colors.enhReaderHelpLineHotkeyColor + "PgUp"
										   + this.colors.enhReaderHelpLineGeneralColor + "/"
		                                   + this.colors.enhReaderHelpLineHotkeyColor + "Dn"
										   + this.colors.enhReaderHelpLineGeneralColor + ", "
										   + this.colors.enhReaderHelpLineHotkeyColor + "HOME"
										   + this.colors.enhReaderHelpLineGeneralColor + ", "
										   + this.colors.enhReaderHelpLineHotkeyColor + "END"
										   + this.colors.enhReaderHelpLineGeneralColor + ", "
										   + this.colors.enhReaderHelpLineHotkeyColor;
		if (this.CanDelete() || this.CanDeleteLastMsg())
			this.enhReadHelpLineWithoutChgArea += "DEL" + this.colors.enhReaderHelpLineGeneralColor + ", " + this.colors.enhReaderHelpLineHotkeyColor;
		if (this.CanEdit())
			this.enhReadHelpLineWithoutChgArea += "E" + this.colors.enhReaderHelpLineParenColor + ")" + this.colors.enhReaderHelpLineGeneralColor + "dit, " + this.colors.enhReaderHelpLineHotkeyColor;
		this.enhReadHelpLineWithoutChgArea += "F" + this.colors.enhReaderHelpLineParenColor + ")"
		                                   + this.colors.enhReaderHelpLineGeneralColor + "irst, "
										   + this.colors.enhReaderHelpLineHotkeyColor + "L"
										   + this.colors.enhReaderHelpLineParenColor + ")"
										   + this.colors.enhReaderHelpLineGeneralColor + "ast, "
										   + this.colors.enhReaderHelpLineHotkeyColor + "R"
										   + this.colors.enhReaderHelpLineParenColor + ")"
										   + this.colors.enhReaderHelpLineGeneralColor + "eply, "
		                                   + this.colors.enhReaderHelpLineHotkeyColor + "Q"
										   + this.colors.enhReaderHelpLineParenColor + ")"
										   + this.colors.enhReaderHelpLineGeneralColor + "uit, "
										   + this.colors.enhReaderHelpLineHotkeyColor + "?";
		// Center the help text based on the console width
		numCharsRemaining = console.screen_columns - console.strlen(this.enhReadHelpLineWithoutChgArea) - 2;
		numCharsOnEachSide = Math.floor(numCharsRemaining/2);
		// Left side
		for (var i = 0; i < numCharsOnEachSide; ++i)
			this.enhReadHelpLineWithoutChgArea = " " + this.enhReadHelpLineWithoutChgArea;
		this.enhReadHelpLineWithoutChgArea = "\1n" + this.colors.enhReaderHelpLineBkgColor + this.enhReadHelpLineWithoutChgArea;
		// Right side
		for (var i = 0; i < numCharsOnEachSide; ++i)
			this.enhReadHelpLineWithoutChgArea += " ";
		numCharsRemaining = console.screen_columns - console.strlen(this.enhReadHelpLineWithoutChgArea) - 1;
		if (numCharsRemaining > 0)
		{
			for (var i = 0; i < numCharsRemaining; ++i)
			this.enhReadHelpLineWithoutChgArea += " ";
		}
	}
	else
	{
		this.enhReadHelpLine = this.colors.enhReaderHelpLineHotkeyColor + UP_ARROW
		                     + this.colors.enhReaderHelpLineGeneralColor + ", "
		                     + this.colors.enhReaderHelpLineHotkeyColor + DOWN_ARROW
		                     + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor + LEFT_ARROW
							 + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor + RIGHT_ARROW
							 + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor + "PgUp"
							 + this.colors.enhReaderHelpLineGeneralColor + "/"
		                     + this.colors.enhReaderHelpLineHotkeyColor + "Dn"
							 + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor + "HOME"
							 + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor + "END"
							 + this.colors.enhReaderHelpLineGeneralColor + ", "
							 + this.colors.enhReaderHelpLineHotkeyColor + "F"
							 + this.colors.enhReaderHelpLineParenColor + ")"
							 + this.colors.enhReaderHelpLineGeneralColor + "irst, "
							 + this.colors.enhReaderHelpLineHotkeyColor + "L"
							 + this.colors.enhReaderHelpLineParenColor + ")"
							 + this.colors.enhReaderHelpLineGeneralColor + "ast, "
		                     + this.colors.enhReaderHelpLineHotkeyColor + "R"
							 + this.colors.enhReaderHelpLineParenColor + ")"
							 + this.colors.enhReaderHelpLineGeneralColor + "eply, "
							 + this.colors.enhReaderHelpLineHotkeyColor + "C"
							 + this.colors.enhReaderHelpLineParenColor + ")"
							 + this.colors.enhReaderHelpLineGeneralColor + "hg area, "
							 + this.colors.enhReaderHelpLineHotkeyColor + "Q"
							 + this.colors.enhReaderHelpLineParenColor + ")"
							 + this.colors.enhReaderHelpLineGeneralColor + "uit, "
							 + this.colors.enhReaderHelpLineHotkeyColor + "?";
		// Center the help text based on the console width
		var numCharsRemaining = console.screen_columns - console.strlen(this.enhReadHelpLine) - 2;
		var numCharsOnEachSide = Math.floor(numCharsRemaining/2);
		// Left side
		for (var i = 0; i < numCharsOnEachSide; ++i)
			this.enhReadHelpLine = " " + this.enhReadHelpLine;
		this.enhReadHelpLine = "\1n" + this.colors.enhReaderHelpLineBkgColor + this.enhReadHelpLine;
		// Right side
		for (var i = 0; i < numCharsOnEachSide; ++i)
			this.enhReadHelpLine += " ";
		numCharsRemaining = console.screen_columns - console.strlen(this.enhReadHelpLine) - 1;
		if (numCharsRemaining > 0)
		{
			for (var i = 0; i < numCharsRemaining; ++i)
			this.enhReadHelpLine += " ";
		}

		// Create a version without the change area option
		this.enhReadHelpLineWithoutChgArea = this.colors.enhReaderHelpLineHotkeyColor + UP_ARROW
		                                   + this.colors.enhReaderHelpLineGeneralColor + ", "
		                                   + this.colors.enhReaderHelpLineHotkeyColor + DOWN_ARROW
		                                   + this.colors.enhReaderHelpLineGeneralColor + ", "
										   + this.colors.enhReaderHelpLineHotkeyColor + LEFT_ARROW
										   + this.colors.enhReaderHelpLineGeneralColor
										   + ", " + this.colors.enhReaderHelpLineHotkeyColor + RIGHT_ARROW
										   + this.colors.enhReaderHelpLineGeneralColor + ", "
										   + this.colors.enhReaderHelpLineHotkeyColor + "PgUp"
										   + this.colors.enhReaderHelpLineGeneralColor + "/"
		                                   + this.colors.enhReaderHelpLineHotkeyColor + "Dn"
										   + this.colors.enhReaderHelpLineGeneralColor
										   + ", " + this.colors.enhReaderHelpLineHotkeyColor + "HOME"
										   + this.colors.enhReaderHelpLineGeneralColor
										   + ", " + this.colors.enhReaderHelpLineHotkeyColor + "END"
										   + this.colors.enhReaderHelpLineGeneralColor
										   + ", " + this.colors.enhReaderHelpLineHotkeyColor + "F"
										   + this.colors.enhReaderHelpLineParenColor + ")"
										   + this.colors.enhReaderHelpLineGeneralColor
										   + "irst, " + this.colors.enhReaderHelpLineHotkeyColor
										   + "L" + this.colors.enhReaderHelpLineParenColor + ")"
										   + this.colors.enhReaderHelpLineGeneralColor + "ast, "
		                                   + this.colors.enhReaderHelpLineHotkeyColor + "R"
										   + this.colors.enhReaderHelpLineParenColor + ")"
										   + this.colors.enhReaderHelpLineGeneralColor
										   + "eply, " + this.colors.enhReaderHelpLineHotkeyColor
										   + "Q" + this.colors.enhReaderHelpLineParenColor + ")"
										   + this.colors.enhReaderHelpLineGeneralColor + "uit, "
										   + this.colors.enhReaderHelpLineHotkeyColor + "?";
		// Center the help text based on the console width
		numCharsRemaining = console.screen_columns - console.strlen(this.enhReadHelpLineWithoutChgArea) - 2;
		numCharsOnEachSide = Math.floor(numCharsRemaining/2);
		// Left side
		for (var i = 0; i < numCharsOnEachSide; ++i)
			this.enhReadHelpLineWithoutChgArea = " " + this.enhReadHelpLineWithoutChgArea;
		this.enhReadHelpLineWithoutChgArea = "\1n" + this.colors.enhReaderHelpLineBkgColor + this.enhReadHelpLineWithoutChgArea;
		// Right side
		for (var i = 0; i < numCharsOnEachSide; ++i)
			this.enhReadHelpLineWithoutChgArea += " ";
		numCharsRemaining = console.screen_columns - 1 - console.strlen(this.enhReadHelpLineWithoutChgArea);
		if (numCharsRemaining > 0)
		{
			for (var i = 0; i < numCharsRemaining; ++i)
			this.enhReadHelpLineWithoutChgArea += " ";
		}
	}
}
// For the DigDistMsgReader class: Reads the configuration file (by default,
// DDMsgReader.cfg) and sets the object properties
// accordingly.
function DigDistMsgReader_ReadConfigFile()
{
	this.cfgFileSuccessfullyRead = false;

	var themeFilename = ""; // In case a theme filename is specified

	// Open the main configuration file.  First look for it in the sbbs/mods
	// directory, then sbbs/ctrl, then in the same directory as this script.
	var cfgFilename = system.mods_dir + this.cfgFilename;
	if (!file_exists(cfgFilename))
		cfgFilename = system.ctrl_dir + this.cfgFilename;
	if (!file_exists(cfgFilename))
		cfgFilename = gStartupPath + this.cfgFilename;
	var cfgFile = new File(cfgFilename);
	if (cfgFile.open("r"))
	{
		this.cfgFileSuccessfullyRead = true;

		var fileLine = null;     // A line read from the file
		var equalsPos = 0;       // Position of a = in the line
		var commentPos = 0;      // Position of the start of a comment
		var setting = null;      // A setting name (string)
		var settingUpper = null; // Upper-case setting name
		var value = null;        // To store a value for a setting (string)
		var valueUpper = null;   // Upper-cased value for a setting (string)
		while (!cfgFile.eof)
		{
			// Read the next line from the config file.
			fileLine = cfgFile.readln(2048);

			// fileLine should be a string, but I've seen some cases
			// where it isn't, so check its type.
			if (typeof(fileLine) != "string")
				continue;

			// If the line starts with with a semicolon (the comment
			// character) or is blank, then skip it.
			if ((fileLine.substr(0, 1) == ";") || (fileLine.length == 0))
				continue;

			// If the line has a semicolon anywhere in it, then remove
			// everything from the semicolon onward.
			commentPos = fileLine.indexOf(";");
			if (commentPos > -1)
				fileLine = fileLine.substr(0, commentPos);

			// Look for an equals sign, and if found, separate the line
			// into the setting name (before the =) and the value (after the