| Scripts/commslog_mfd.js | "use strict";
this.name = "CommsLogMFD";
this.author = "phkb";
this.copyright = "2016 phkb";
this.description = "Stores all communications received by the player and displays them in a multi-function display.";
this.licence = "CC BY-NC-SA 4.0";
this._debug = false;		    // change to false for less logging
this._scrollTimeout = 90;		// number of seconds it will take for a scrolled view to revert to viewing current message
this._clearOnLaunch = 0;	   	// 0 = message log kept indefinitely, 1 = messages clear on launch
this._logSize = 32000;			// maximum length of log (in bytes) when clear on launch is off. Should not be set over 32k which is the maximum string length
this._lineLength = 14.2;        // horizontal measure of the max width of a line in the MFD (15 is the width of an MFD, minus some margin)
this._commsMFD_maxlines = 9;	// maximum number of lines visible in the MFD (10 - 1 for the header line)
this._syslines = [];
this._msRows = 18;				// rows to display on the mission screen
this._msCols = 32;				// columns to display on the mission screen
this._menuColor = "orangeColor";
this._exitColor = "yellowColor";
//-------------------------------------------------------------------------------------------------------------
this.startUp = function () {
	this._scrollMethod = 1;			// 0 = by line, 1 = by message;
	this._commsMFD_lines = [];
	this._commsMFD_log = "";
	if (missionVariables.CommsLogMFD_logsize) this._logSize = missionVariables.CommsLogMFD_logsize;
	if (this._clearOnLaunch === 0) {
		if (missionVariables.CommsLogMFD_log == null) {
			missionVariables.CommsLogMFD_log = "";
			missionVariables.CommsLogMFD_maxscroll = 0;
		}
		if (missionVariables.CommsLogMFD_scrollmethod == null) missionVariables.CommsLogMFD_scrollmethod = 1;
		if (missionVariables.CommsLogMFD_data) {
			var dta = JSON.parse(missionVariables.CommsLogMFD_data);
			this.$reformatData(dta, this._commsMFD_lines, this._lineLength);
			dta = [];
		}
		if (missionVariables.CommsLogMFD_log) {
			this.$convertLogToArray(missionVariables.CommsLogMFD_log);		// storage string of messages
			delete missionVariables.CommsLogMFD_log;
			var dta = [];
			this.$reformatData(this._commsMFD_lines, dta, this._lineLength);
			this._commsMFD_lines = dta;
			dta = [];
		}
		// make sure we're only holding one set of data
		delete missionVariables.CommsLogMFD_data;
		delete missionVariables.CommsLogMFD_log;
		this._commsMFD_maxscroll = missionVariables.CommsLogMFD_maxscroll;	// storage of maximum scroll amount
		this._scrollMethod = missionVariables.CommsLogMFD_scrollmethod;
	} else {
		this._commsMFD_maxscroll = 0;	// storage of maximum scroll amount
	}
	this._commsMFD_scroll = 0;		// storage scroll amount
	this._scrollLaunch = 0;			// used to scroll to paricular launch record, 1 = most recent, 2 = second most recent, etc
	this.$commsMFD_updateview();
}
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function () {
	if (player.ship.docked) this.$initInterface(player.ship.dockedStation);
}
//=============================================================================================================
// ship interfaces
//-------------------------------------------------------------------------------------------------------------
this.shipDockedWithStation = function (station) {
	this.$initInterface(station);
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
	// only save if we aren't clearing every launch
	if (this._clearOnLaunch === 0) {
		missionVariables.CommsLogMFD_data = JSON.stringify(this._commsMFD_lines);
		missionVariables.CommsLogMFD_maxscroll = this._commsMFD_maxscroll;
		missionVariables.CommsLogMFD_scrollmethod = this._scrollMethod;
		missionVariables.CommsLogMFD_logsize = this._logSize;
		this._commsMFD_log = "";
	}
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillDockWithStation = function (station) {
	this.commsMessageReceived(expandDescription("[commslog_docked]", { time: clock.clockStringForTime(clock.adjustedSeconds) }), station);
	// force the log to be resized to prevent it becoming too large between save games
	this.$convertArrayToString();
	this.$convertLogToArray(this._commsMFD_log);
	this._commsMFD_log = "";
}
//-------------------------------------------------------------------------------------------------------------
this.shipWillLaunchFromStation = function () {
	if (missionVariables.CommsLogMFD_data) delete missionVariables.CommsLogMFD_data;
	// reset comms log settings
	if (this._clearOnLaunch === 1) {
		this._commsMFD_log = "";
		this._commsMFD_lines = [];
		this._commsMFD_maxscroll = 0;
	}
	this._commsMFD_scroll = 0;
}
//-------------------------------------------------------------------------------------------------------------
this.shipLaunchedFromStation = function (station) {
	// we're doing this here so that the "(adjusting)" text doesn't appear in the time stamp
	this._syslines = [];
	this.commsMessageReceived(expandDescription("[commslog_launched]", { time: clock.clockStringForTime(clock.adjustedSeconds) }), station);
	this.$commsMFD_updateview();
}
//-------------------------------------------------------------------------------------------------------------
this.shipLaunchedEscapePod = function (escapepod, passengers) {
	this.$addCommsMessage(expandDescription("[commslog_escapepod]", { time: clock.clockString.replace(expandDescription("[adjusting-word]"), "") }), expandDescription("[commslog_galcop_beacon]"));
}
//-------------------------------------------------------------------------------------------------------------
this.playerBoughtEquipment = function (equipment) {
	if (equipment === "EQ_COMMSLOGMFD_REMOVAL") {
		var p = player.ship;
		p.removeEquipment("EQ_COMMSLOGMFD");
		p.removeEquipment("EQ_COMMSLOGMFD_REMOVAL");
	}
	if (equipment === "EQ_COMMSLOGMFD_PASSIVE_REMOVAL") {
		var p = player.ship;
		p.removeEquipment("EQ_COMMSLOGMFD_PASSIVE");
		p.removeEquipment("EQ_COMMSLOGMFD_PASSIVE_REMOVAL");
	}
}
//-------------------------------------------------------------------------------------------------------------
this.missionScreenEnded = function () {
	if (player.ship.hudHidden == true) player.ship.hudHidden = false;
}
//-------------------------------------------------------------------------------------------------------------
this.$initInterface = function (station) {
	station.setInterface(this.name, {
		title: expandDescription("[commslog_interface_title]"),
		category: expandDescription("[interfaces-category-logs]"),
		summary: expandDescription("[commslog_interface_summary]"),
		callback: this.$showCommLog.bind(this)
	});
}
//=============================================================================================================
// General functions
//-------------------------------------------------------------------------------------------------------------
// converts a single string to an array
this.$convertLogToArray = function (commLog) {
	this._commsMFD_lines = commLog.split("\n");
}
//-------------------------------------------------------------------------------------------------------------
// converts the comm log array to a single string
this.$convertArrayToString = function () {
	var log = "";
	var nl = "";
	for (var i = this._commsMFD_lines.length - 1; i >= 0; i--) {
		// check for log file size limit
		if ((log + this._commsMFD_lines[i]).length > this._logSize) {
			// remove the top message
			// look for "\n[A-Z]" (which should indicate the start of the second message in the log
			var re = new RegExp("\\n[A-Z]", "i");
			var iSec = log.search(re);
			// cut out the first message
			log = log.substring(iSec + 1);
			break;
		}
		log = this._commsMFD_lines[i] + nl + log;
		nl = "\n";
	}
	this._commsMFD_log = log;
}
//-------------------------------------------------------------------------------------------------------------
// custom handler for special comms messages (that don't get raised through 'commsMessageReceived')
this.$addCommsMessage = function (message, altSender) {
	var msg = "";
	if (altSender && altSender != "") {
		msg = altSender + ": " + message;
	} else {
		msg = expandDescription("[commslog_unidentified]") + message;
	}
	this.$appendMessage(msg);
}
//-------------------------------------------------------------------------------------------------------------
// worldscript handler for comms messages
this.commsMessageReceived = function (message, sender) {
	var msg = "";
	if (sender) {
		msg = sender.displayName + ": " + message;
	} else {
		if (message.indexOf(":") > 0) {
			msg = message;
		} else {
			msg = expandDescription("[commslog_unidentified]") + message;
		}
	}
	this.$appendMessage(msg);
}
//-------------------------------------------------------------------------------------------------------------
// adds message to the comm log
this.$appendMessage = function (message) {
	if (this._debug === true) log(this.name, "comms::" + message);
	// add the message to the list
	this.$addMsgToArray(message, this._commsMFD_lines, this._lineLength);
	var p = player.ship;
	// only update MFD if the equipment is installed
	if (p.equipmentStatus("EQ_COMMSLOGMFD") === "EQUIPMENT_OK" || p.equipmentStatus("EQ_COMMSLOGMFD_PASSIVE") === "EQUIPMENT_OK") {
		this.$commsMFD_updateview();
	}
}
//-------------------------------------------------------------------------------------------------------------
this.$reformatData = function (srcArray, destArray, lineWidth) {
	//rebuild comms into wide screen format
	var msg = "";
	var output = "";
	for (var i = 0; i < srcArray.length; i++) {
		if (srcArray[i].substring(0, 1) != " " && msg != "") {
			// this is a new message, so output the current one and reset
			//output = output + "> " + msg + "\n";
			this.$addMsgToArray(msg, destArray, lineWidth);
			msg = "";
		}
		// add the message line to the current message
		// we'll trim off any leading and trailing spaces and add them back manually
		msg += srcArray[i].trim() + " ";
	}
	if (msg != "") {
		// output the remaining message
		//output = output + "> " + msg;
		this.$addMsgToArray(msg, destArray, lineWidth);
	}
}
//-------------------------------------------------------------------------------------------------------------
// displays a part of the comms log in the MFD
this.$commsMFD_updateview = function () {
	var p = player.ship;
	if (p.equipmentStatus("EQ_COMMSLOGMFD") === "EQUIPMENT_OK" || p.equipmentStatus("EQ_COMMSLOGMFD_PASSIVE") === "EQUIPMENT_OK") {
		var output = "";
		var iStart = 0;
		var iEnd = 0;
		var iCount = 0;
		var iLast = 0;
		// if we have lines, work out what to display, based on the current scroll position
		if ((this._commsMFD_lines != null) && (this._commsMFD_lines.length != 1 || this._commsMFD_lines[0] != "")) {
			// determine the maximum amount of scroll
			this._commsMFD_maxscroll = this._commsMFD_lines.length - this._commsMFD_maxlines;
			// if the max scroll is less than 0, reset to 0
			if (this._commsMFD_maxscroll < 0) this._commsMFD_maxscroll = 0;
			// work out the start and end points of the log to view
			// scroll line by line
			iEnd = this._commsMFD_lines.length;
			if (this._scrollMethod === 0) iEnd -= this._commsMFD_scroll;
			// scroll message by message
			if (this._scrollMethod === 1 && this._commsMFD_scroll > 0 && this._scrollLaunch === 0) {
				this._holdscrollLaunch = 0;
				// cycle back through the lines, from the bottom up
				for (var i = iEnd - 1; i >= 0; i--) {
					// look for a line that doesn't start with a space character
					if (this._commsMFD_lines[i].substring(0, 1) != " ") {
						// when found, increment our message counter
						iCount += 1;
						// and make a note of the position of this message start
						iLast = i;
						// if our counter equals our scroll value, we're done
						if (iCount === this._commsMFD_scroll) {
							// set the end point to be the point we are in the loop
							iEnd = i;
							// jump out of the loop
							break;
						}
					}
					// this check is to, essentially, stop the last page of messages from being scrolled.
					// check if we're inside the last 9 lines of the log
					//   AND the log length is greater than 9 lines
					//   AND the position of the last message we found is greater than 0 (that is, we found one)
					if (i < 9 && this._commsMFD_lines.length >= 9 && iLast > 0) {
						// don't scroll the last page of messages
						iEnd = 9;
						this._commsMFD_scroll = iCount;
						break;
					}
				}
			}
			// scroll launch by launch
			if (this._scrollLaunch != 0) {
				var newScroll = 0;
				var check = 0;
				// when the scroll method is by line and we're scrolling to the previous launch,
				// we need to pad out the current scroll amount otherwise we'll end up going to the same spot over and over
				var addln = 3;
				// however, going in the other direction we wont' need this
				if (this._scrollLaunch === -1) addln = 0;
				var launchWords = expandDescription("[commslog_launch_words]").split("|");
				for (var i = this._commsMFD_lines.length - 1; i >= 0; i--) {
					// look for a line that doesn't start with a space character
					if (this._commsMFD_lines[i].substring(0, 1) != " ") {
						// is this message a launch message?
						if ((this._commsMFD_lines[i].indexOf(": " + launchWords[0]) > 0) ||
							(this._commsMFD_lines[i].indexOf(": " + launchWords[1]) > 0 && this._commsMFD_lines[i + 1].indexOf(launchWords[2]) > 0) ||
							(this._commsMFD_lines[i].indexOf(":") > 0 && this._commsMFD_lines[i + 1].indexOf(launchWords[0]) > 0)) {
							// only used for line-by-line scrolling
							check = this._commsMFD_lines.length - i;
							// if we scrolling to the next launch, and we've passed the current scroll point, then we can break out of the loop
							// because we should now have the right values
							if (this._scrollLaunch === -1 && ((this._scrollMethod === 1 && iCount > this._commsMFD_scroll) || (this._scrollMethod === 0 && check > this._commsMFD_scroll + addln))) {
								break;
							}
							// look for a launch, that is, before or after the current scroll position (depanding on the scroll direction)
							if ((this._scrollLaunch === 1 && ((this._scrollMethod === 1 && iCount > this._commsMFD_scroll) || (this._scrollMethod === 0 && check > this._commsMFD_scroll + addln))) ||
								(this._scrollLaunch === -1 && ((this._scrollMethod === 1 && iCount < this._commsMFD_scroll) || (this._scrollMethod === 0 && check < this._commsMFD_scroll + addln)))) {
								// we've found it
								// we need to move forward 1 message so the full launch message is in the view
								iEnd = this._commsMFD_lines.length;
								for (var j = i + 1; j < this._commsMFD_lines.length - 1; j++) {
									if (this._commsMFD_lines[j].substring(0, 1) != " ") {
										// this is it
										iEnd = j;
										break;
									}
								}
								// set the new scroll value
								if (this._scrollMethod === 1) {
									newScroll = iCount;
								} else {
									newScroll = this._commsMFD_lines.length - iEnd;
								}
								// if we're scrolling to the previous launch we can break out now, because we have all the info we need
								if (this._scrollLaunch === 1) break;
							}
						}
						// when found, increment our message counter
						iCount += 1;
						// and make a note of the position of this message start
						iLast = i;
					}
					// this check is to, essentially, stop the last page of messages from being scrolled.
					// check if we're inside the last 9 lines of the log
					//   AND the log length is greater than 9 lines
					//   AND the position of the last message we found is greater than 0 (that is, we found one)
					if (this._scrollLaunch === 1 && i < 9 && this._commsMFD_lines.length >= 9 && iLast > 0) {
						// don't scroll the last page of messages
						iEnd = 9;
						newScroll = iCount - 1;
						// edge case, where the last message found is outside the 9 line limit, which would leave the first line of the message invisible
						if (iLast >= 9) {
							iEnd = 9;
							if (this._scrollMethod === 1) {
								newScroll = iCount;
							} else {
								newScroll = this._commsMFD_lines.length - 9;
							}
						}
						break;
					}
				}
				this._commsMFD_scroll = newScroll;
			}
			// the start position is always 9 lines less than the end point
			iStart = iEnd - this._commsMFD_maxlines;
			// this condition should never happen, but just in case...
			// make sure our end point is inside the bounds of the array of lines
			if (iEnd < 0) {
				iEnd = this._commsMFD_lines.length;
				this._commsMFD_scroll = 0;
			}
			// make sure our start point is inside the bounds of the array
			if (iStart < 0) {
				iStart = 0;
			}
			// build the header
			output = expandDescription("[commslog_mfd_header]");
			if (this._commsMFD_scroll != 0) {
				output = output + expandDescription("[commslog_scroll]", { lines: this._commsMFD_scroll.toString() });
			}
			output = output + "\n";
			// add the lines
			if (iEnd > 0) {
				for (var i = iStart; i < iEnd; i++) {
					output = output + this._commsMFD_lines[i] + "\n";
				}
			} else {
				output = output + expandDescription("[commslog_empty]");
			}
		} else {
			output = expandDescription("[commslog_mfd_header]") + "\n" + expandDescription("[commslog_empty]");
		}
		// send output to MFD
		p.setMultiFunctionText("CommsLogMFD", output, false);
	}
}
//-------------------------------------------------------------------------------------------------------------
// output the comms to the latest log
this.$dumpLog = function () {
	var msg = "";
	for (var i = 0; i < this._commsMFD_lines.length; i++) {
		if (this._commsMFD_lines[i].substring(0, 1) != " " && msg != "") {
			// this is a new message, so output the current one and reset
			log(this.name, msg);
			msg = "";
		}
		// add the message line to the current message
		// we'll trim off any leading and trailing spaces and add them back manually
		// we'll also replace any instances of "…" with "..."
		msg += this._commsMFD_lines[i].trim().replace("…", "...").replace("–", "-") + " ";
	}
	if (msg != "") {
		// output the remaining message
		log(this.name, msg);
	}
}
//-------------------------------------------------------------------------------------------------------------
this.$showCommLog = function $showCommLog() {
	this._syslines = [];
	this.$reformatData(this._commsMFD_lines, this._syslines, this._msCols);
	var p = player.ship;
	this._msRows = 18;
	// one less row if the comms log MFD is installed
	if (p.equipmentStatus("EQ_COMMSLOGMFD") === "EQUIPMENT_OK" || p.equipmentStatus("EQ_COMMSLOGMFD_PASSIVE") === "EQUIPMENT_OK") {
		this._msRows = 17;
	}
	this._maxpage = Math.ceil(this._syslines.length / this._msRows);
	this._curpage = 0;
	this.$showPage();
}
//-------------------------------------------------------------------------------------------------------------
// adds a message to an array, splitting the lines based on a line width
this.$addMsgToArray = function (msg, ary, linewidth) {
	var prt = "";
	if (defaultFont.measureString(msg) > linewidth) {
		var words = msg.split(" ");
		var iPoint = 0
		var nextWord = "";
		do {
			// add the space in (after the first word)
			if (prt != "") {
				prt += " ";
			}
			// add the word on
			prt = prt + words[iPoint];
			// get the next word in the array
			if (iPoint < words.length - 1) {
				nextWord = " " + words[iPoint + 1];
			} else {
				nextWord = ""
			}
			// check the width of the next with the nextword added on
			if (defaultFont.measureString(prt + nextWord) > linewidth) {
				// hit the max width - add the line and start again
				ary.push(prt);
				// subsequent lines of a message will be indented slightly
				prt = " ";
			}
			iPoint += 1;
			// check for the end of the array, and output remaining text
			if ((iPoint >= words.length) && (prt.trim() != "")) {
				ary.push(prt);
			}
		} while (iPoint < words.length);
		words = [];
	} else {
		ary.push(msg);
	}
}
//-------------------------------------------------------------------------------------------------------------
this.$commLogPage = function (cpage, lines) {
	var output = "";
	var iStart = 0;
	var iEnd = 0;
	var textCount = 0;
	// set out initial end point
	iEnd = iStart + lines;
	if (cpage != 0) {
		iStart = cpage * lines;
		iEnd = iStart + lines;
	}
	if (iEnd > this._syslines.length) iEnd = this._syslines.length;
	for (var i = iStart; i < iEnd; i++) {
		textCount += this._syslines[i].trim().length;
		output += this._syslines[i] + "\n";
	}
	if (cpage === 0 && iStart === 0 && iEnd === 0 && (this._syslines[0] == null || textCount == 0)) output = expandDescription("[commslog_empty]");
	return output;
}
//-------------------------------------------------------------------------------------------------------------
this.$showPage = function $showPage() {
	var p = player.ship;
	if (this.$isBigGuiActive() === false) p.hudHidden = true;
	this._msRows = 18;
	// one less row if the comms log MFD is installed
	if (p.equipmentStatus("EQ_COMMSLOGMFD") === "EQUIPMENT_OK" || p.equipmentStatus("EQ_COMMSLOGMFD_PASSIVE") === "EQUIPMENT_OK") this._msRows = 17;
	var text = this.$commLogPage(this._curpage, this._msRows);
	var opts;
	var curChoices = {};
	var def = "09_NEXT";
	if (this._maxpage <= 1) {
		def = "99_EXIT";
		curChoices["01_PREV"] = { text: "[commslog_prev_page]", color: "darkGrayColor", unselectable: true };
		curChoices["09_NEXT"] = { text: "[commslog_next_page]", color: "darkGrayColor", unselectable: true };
		curChoices["10_FIRST"] = { text: "[commslog_first_page]", color: "darkGrayColor", unselectable: true };
		curChoices["11_LAST"] = { text: "[commslog_last_page]", color: "darkGrayColor", unselectable: true };
	} else {
		if (this._curpage === 0) {
			curChoices["01_PREV"] = { text: "[commslog_prev_page]", color: "darkGrayColor", unselectable: true };
			curChoices["09_NEXT"] = { text: "[commslog_next_page]", color: this._menuColor };
			curChoices["10_FIRST"] = { text: "[commslog_first_page]", color: "darkGrayColor", unselectable: true };
			curChoices["11_LAST"] = { text: "[commslog_last_page]", color: "orangeColor" };
		} else {
			curChoices["01_PREV"] = { text: "[commslog_prev_page]", color: this._menuColor };
			if (this._curpage + 1 === this._maxpage) {
				def = "01_PREV";
				curChoices["09_NEXT"] = { text: "[commslog_next_page]", color: "darkGrayColor", unselectable: true };
				curChoices["10_FIRST"] = { text: "[commslog_first_page]", color: this._menuColor };
				curChoices["11_LAST"] = { text: "[commslog_last_page]", color: "darkGrayColor", unselectable: true };
			} else {
				curChoices["09_NEXT"] = { text: "[commslog_next_page]", color: this._menuColor };
				curChoices["10_FIRST"] = { text: "[commslog_first_page]", color: this._menuColor };
				curChoices["11_LAST"] = { text: "[commslog_last_page]", color: this._menuColor };
			}
		}
	}
	if (text != "(empty)") {
		curChoices["15_DUMPLOG"] = { text: "[commslog_write_log]", color: this._menuColor };
		curChoices["20_CLEARLOG"] = { text: "[commslog_clear_log]", color: this._menuColor };
	} else {
		curChoices["15_DUMPLOG"] = { text: "[commslog_write_log]", color: "darkGrayColor", unselectable: true };
		curChoices["20_CLEARLOG"] = { text: "[commslog_clear_log]", color: "darkGrayColor", unselectable: true };
	}
	curChoices["30_SETLOGSIZE"] = { text: "[commslog_set_log_size]", color: this._menuColor };
	if (p.equipmentStatus("EQ_COMMSLOGMFD") === "EQUIPMENT_OK") {
		curChoices["80_TYPE1"] = { text: "[commslog_mfd_active_mode]", color: this._menuColor };
	}
	if (p.equipmentStatus("EQ_COMMSLOGMFD_PASSIVE") === "EQUIPMENT_OK") {
		curChoices["80_TYPE2"] = { text: "[commslog_mfd_passive_mode]", color: this._menuColor };
	}
	curChoices["99_EXIT"] = { text: "[commslog_exit]", color: this._exitColor };
	var opts = {
		screenID: "oolite-communicationslog-main-map",
		title: expandDescription("[commslog_screen_title]", { page: (this._curpage + 1).toString(), max: (this._maxpage == 0 ? "1" : this._maxpage.toString()) }),
		allowInterrupt: true,
		choices: curChoices,
		exitScreen: "GUI_SCREEN_INTERFACES",
		overlay: { name: "commlog-radar.png", height: 546 },
		initialChoicesKey: this._lastchoice ? this._lastchoice : def,
		message: text
	};
	mission.runScreen(opts, this.$logHandler.bind(this));
}
//-------------------------------------------------------------------------------------------------------------
this.$logHandler = function $logHandler(choice) {
	delete this._lastchoice;
	var newChoice = null;
	if (!choice) {
		if (this._debug) log(this.name, "no choice");
		return; // launched while reading?
	} else if (choice === "01_PREV") {
		if (this._curpage > 0) this._curpage -= 1;
	} else if (choice === "09_NEXT") {
		if (this._curpage < this._maxpage - 1) this._curpage += 1;
	} else if (choice === "10_FIRST") {
		this._curpage = 0;
	} else if (choice === "11_LAST") {
		this._curpage = this._maxpage - 1;
	} else if (choice === "15_DUMPLOG") {
		this.$dumpLog();
	} else if (choice === "20_CLEARLOG") {
		this._scrollLaunch = 0;
		this._commsMFD_log = "";
		this._commsMFD_lines = [];
		this._syslines = [];
		this._maxpage = 1;
		this._curpage = 0;
	} else if (choice === "30_SETLOGSIZE") {
		this.$setLogSize();
	} else if (choice === "80_TYPE1") {
		this.$changeMFDType("TYPE2");
		newChoice = "80_TYPE2";
	} else if (choice === "80_TYPE2") {
		this.$changeMFDType("TYPE1");
		newChoice = "80_TYPE1";
	}
	this._lastchoice = choice;
	if (newChoice) this._lastchoice = newChoice;
	if (choice != "99_EXIT" && choice != "30_SETLOGSIZE") {
		this.$showPage();
	}
}
//-------------------------------------------------------------------------------------------------------------
this.$changeMFDType = function (mfdType) {
	var p = player.ship;
	switch (mfdType) {
		case "TYPE2":
			if (p.equipmentStatus("EQ_COMMSLOGMFD") != "EQUIPMENT_OK") return;
			if (p.equipmentStatus("EQ_COMMSLOGMFD_PASSIVE") === "EQUIPMENT_OK") return;
			p.removeEquipment("EQ_COMMSLOGMFD");
			p.awardEquipment("EQ_COMMSLOGMFD_PASSIVE");
			break;
		case "TYPE1":
			if (p.equipmentStatus("EQ_COMMSLOGMFD_PASSIVE") != "EQUIPMENT_OK") return;
			if (p.equipmentStatus("EQ_COMMSLOGMFD") === "EQUIPMENT_OK") return;
			p.removeEquipment("EQ_COMMSLOGMFD_PASSIVE");
			p.awardEquipment("EQ_COMMSLOGMFD");
			break;
	}
}
//-------------------------------------------------------------------------------------------------------------
// prompts the user for a new log file size
this.$setLogSize = function () {
	var text = expandDescription("[commslog_set_log_info]", { current: parseInt(this._logSize / 1000) });
	var opts = {
		screenID: "oolite-communicationslog-logsize-map",
		title: expandDescription("[commslog_log_size_title]"),
		allowInterrupt: false,
		exitScreen: "GUI_SCREEN_INTERFACES",
		overlay: { name: "commlog-radar.png", height: 546 },
		message: text,
		textEntry: true
	};
	mission.runScreen(opts, this.$getNewLogSize, this);
}
//-------------------------------------------------------------------------------------------------------------
// parses the input from the setLogSize screen
this.$getNewLogSize = function (param) {
	if (parseInt(param) >= 1 && parseInt(param) <= 32) {
		this._logSize = parseInt(param) * 1000;
		this.$convertArrayToString()
		this.$convertLogToArray(this._commsMFD_log);
	}
	this.$showPage();
}
//-------------------------------------------------------------------------------------------------------------
// returns true if a HUD with allowBigGUI is enabled, otherwise false
this.$isBigGuiActive = function () {
	if (oolite.compareVersion("1.83") <= 0) {
		return player.ship.hudAllowsBigGui;
	} else {
		var bigGuiHUD = ["XenonHUD.plist", "coluber_hud_ch01-dock.plist"]; 	// until there is a property we can check, I'll be listing HUD's that have the allow_big_gui property set here
		if (bigGuiHUD.indexOf(player.ship.hud) >= 0) {
			return true;
		} else {
			return false;
		}
	}
}
 |