/*
	Copyright 2016 _that/TeamWin
	This file is part of TWRP/TeamWin Recovery Project.

	TWRP is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	TWRP is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with TWRP.  If not, see <http://www.gnu.org/licenses/>.
*/

// terminal.cpp - GUITerminal object

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <termio.h>

#include <string>
#include <cctype>
#include <linux/input.h>

extern "C" {
#include "../twcommon.h"
#include "../minuitwrp/minui.h"
}

#include "rapidxml.hpp"
#include "objects.hpp"

#if 0
#define debug_printf printf
#else
#define debug_printf(...)
#endif

extern int g_pty_fd; // in gui.cpp where the select is

/*
Pseudoterminal handler.
*/
class Pseudoterminal
{
public:
	Pseudoterminal() : fdMaster(0), pid(0)
	{
	}

	bool started() const { return pid > 0; }

	bool start()
	{
		fdMaster = getpt();
		if (fdMaster < 0) {
			LOGERR("Error %d on getpt()\n", errno);
			return false;
		}

		if (unlockpt(fdMaster) != 0) {
			LOGERR("Error %d on unlockpt()\n", errno);
			return false;
		}

		pid = fork();
		if (pid < 0) {
			LOGERR("fork failed for pty, error %d\n", errno);
			close(fdMaster);
			pid = 0;
			return false;
		}
		else if (pid) {
			// child started, now someone needs to periodically read from fdMaster
			// and write it to the terminal
			// this currently works through gui.cpp calling terminal_pty_read below
			g_pty_fd = fdMaster;
			return true;
		}
		else {
			int fdSlave = open(ptsname(fdMaster), O_RDWR);
			close(fdMaster);
			runSlave(fdSlave);
		}
		// we can't get here
		LOGERR("impossible error in pty\n");
		return false;
	}

	void runSlave(int fdSlave)
	{
		dup2(fdSlave, 0); // PTY becomes standard input (0)
		dup2(fdSlave, 1); // PTY becomes standard output (1)
		dup2(fdSlave, 2); // PTY becomes standard error (2)

		// Now the original file descriptor is useless
		close(fdSlave);

		// Make the current process a new session leader
		if (setsid() == (pid_t)-1)
			LOGERR("setsid failed: %d\n", errno);

		// As the child is a session leader, set the controlling terminal to be the slave side of the PTY
		// (Mandatory for programs like the shell to make them manage correctly their outputs)
		ioctl(0, TIOCSCTTY, 1);

		execl("/sbin/sh", "sh", NULL);
		_exit(127);
	}

	int read(char* buffer, size_t size)
	{
		if (!started()) {
			LOGERR("someone tried to read from pty, but it was not started\n");
			return -1;
		}
		int rc = ::read(fdMaster, buffer, size);
		debug_printf("pty read: %d bytes\n", rc);
		if (rc < 0) {
			LOGINFO("pty read failed: %d\n", errno);
			// assume child has died
			close(fdMaster);
			g_pty_fd = fdMaster = -1;
			pid = 0;
		}
		return rc;
	}

	int write(const char* buffer, size_t size)
	{
		if (!started()) {
			LOGERR("someone tried to write to pty, but it was not started\n");
			return -1;
		}
		int rc = ::write(fdMaster, buffer, size);
		debug_printf("pty write: %d bytes -> %d\n", size, rc);
		if (rc < 0) {
			LOGINFO("pty write failed: %d\n", errno);
			// assume child has died
			close(fdMaster);
			g_pty_fd = fdMaster = -1;
			pid = 0;
		}
		return rc;
	}

	template<size_t n>
	inline int write(const char (&literal)[n])
	{
		return write(literal, n-1);
	}

	void resize(int xChars, int yChars, int w, int h)
	{
		struct winsize ws;
		ws.ws_row = yChars;
		ws.ws_col = xChars;
		ws.ws_xpixel = w;
		ws.ws_ypixel = h;
		if (ioctl(fdMaster, TIOCSWINSZ, &ws) < 0)
			LOGERR("failed to set window size, error %d\n", errno);
	}

private:
	int fdMaster;
	int pid;
};

// UTF-8 decoder
// Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
// See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.

const uint32_t UTF8_ACCEPT = 0;
const uint32_t UTF8_REJECT = 1;

static const uint8_t utf8d[] = {
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f
	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f
	7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf
	8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df
	0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef
	0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff
	0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2
	1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4
	1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6
	1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8
};

uint32_t inline utf8decode(uint32_t* state, uint32_t* codep, uint32_t byte)
{
	uint32_t type = utf8d[byte];

	*codep = (*state != UTF8_ACCEPT) ?
		(byte & 0x3fu) | (*codep << 6) :
		(0xff >> type) & (byte);

	*state = utf8d[256 + *state*16 + type];
	return *state;
}
// end of UTF-8 decoder

// Append a UTF-8 codepoint to string s
size_t utf8add(std::string& s, uint32_t cp)
{
	if (cp < 0x7f) {
		s += cp;
		return 1;
	}
	else if (cp < 0x7ff) {
		s += (0xc0 | (cp >> 6));
		s += (0x80 | (cp & 0x3f));
		return 2;
	}
	else if (cp < 0xffff) {
		s += (0xe0 | (cp >> 12));
		s += (0x80 | ((cp >> 6) & 0x3f));
		s += (0x80 | (cp & 0x3f));
		return 3;
	}
	else if (cp < 0x1fffff) {
		s += (0xf0 | (cp >> 18));
		s += (0x80 | ((cp >> 12) & 0x3f));
		s += (0x80 | ((cp >> 6) & 0x3f));
		s += (0x80 | (cp & 0x3f));
		return 4;
	}
	return 0;
}

/*
TerminalEngine is the terminal back-end, dealing with the text buffer and attributes
and with communicating with the pty.
It does not care about visual things like rendering, fonts, windows etc.
The idea is that 0 to n GUITerminal instances (e.g. on different pages) can connect
to one TerminalEngine to interact with the terminal, and that the TerminalEngine
survives things like page changes or even theme reloads.
*/
class TerminalEngine
{
public:
#if 0 // later
	struct Attributes
	{
		COLOR fgcolor; // TODO: what about palette?
		COLOR bgcolor;
		// could add bold, underline, blink, etc.
	};

	struct AttributeRange
	{
		size_t start; // start position inside text (in bytes)
		Attributes a;
	};
#endif
	typedef uint32_t CodePoint; // Unicode code point

	// A line of text, optimized for rendering and storage in the buffer
	struct Line
	{
		std::string text; // in UTF-8 format
//		std::vector<AttributeRange> attrs;
		Line() {}
		size_t utf8forward(size_t start) const
		{
			if (start >= text.size())
				return start;
			uint32_t u8state = 0, u8cp = 0;
			size_t i = start;
			uint32_t rc;
			do {
				rc = utf8decode(&u8state, &u8cp, (unsigned char)text[i]);
				++i;
			} while (rc != UTF8_ACCEPT && rc != UTF8_REJECT && i < text.size());
			return i;
		}

		std::string substr(size_t start, size_t n) const
		{
			size_t i = 0;
			for (; start && i < text.size(); i = utf8forward(i))
				--start;
			size_t s = i;
			for (; n && i < text.size(); i = utf8forward(i))
				--n;
			return text.substr(s, i - s);
		}
		size_t length() const
		{
			size_t n = 0;
			for (size_t i = 0; i < text.size(); i = utf8forward(i))
				++n;
			return n;
		}
	};

	// A single character cell with a Unicode code point
	struct Cell
	{
		Cell() : cp(' ') {}
		Cell(CodePoint cp) : cp(cp) {}
		CodePoint cp;
//		Attributes a;
	};

	// A line of text, optimized for editing single characters
	struct UnpackedLine
	{
		std::vector<Cell> cells;
		void eraseFrom(size_t x)
		{
			if (cells.size() > x)
				cells.erase(cells.begin() + x, cells.end());
		}

		void eraseTo(size_t x)
		{
			if (x > 0)
				cells.erase(cells.begin(), cells.begin() + x);
		}
	};

	TerminalEngine()
	{
		// the default size will be overwritten by the GUI window when the size is known
		width = 40;
		height = 10;

		clear();
		updateCounter = 0;
		state = kStateGround;
		utf8state = utf8codepoint = 0;
	}

	void setSize(int xChars, int yChars, int w, int h)
	{
		width = xChars;
		height = yChars;
		if (pty.started())
			pty.resize(width, height, w, h);
		debug_printf("setSize: %d*%d chars, %d*%d pixels\n", xChars, yChars, w, h);
	}

	void initPty()
	{
		if (!pty.started())
		{
			pty.start();
			pty.resize(width, height, 0, 0);
		}
	}

	void readPty()
	{
		char buffer[1024];
		int rc = pty.read(buffer, sizeof(buffer));
		debug_printf("readPty: %d bytes\n", rc);
		if (rc < 0)
			output("\r\nChild process exited.\r\n");	// TODO: maybe exit terminal here
		else
			for (int i = 0; i < rc; ++i)
				output(buffer[i]);
	}

	void clear()
	{
		cursorX = cursorY = 0;
		lines.clear();
		setY(0);
		unpackLine(0);
		++updateCounter;
	}

	void output(const char *buf)
	{
		for (const char* p = buf; *p; ++p)
			output(*p);
	}

	void output(const char ch)
	{
		char debug[2]; debug[0] = ch; debug[1] = 0;
		debug_printf("output: %d %s\n", (int)ch, (ch >= ' ' && ch < 127) ? debug : ch == 27 ? "esc" : "");
		if (ch < 32) {
			// always process control chars, even after incomplete UTF-8 fragments
			processC0(ch);
			if (utf8state != UTF8_ACCEPT)
			{
				debug_printf("Terminal: incomplete UTF-8 fragment before control char ignored, codepoint=%u ch=%d\n", utf8codepoint, (int)ch);
				utf8state = UTF8_ACCEPT;
			}
			return;
		}
		uint32_t rc = utf8decode(&utf8state, &utf8codepoint, (unsigned char)ch);
		if (rc == UTF8_ACCEPT)
			processCodePoint(utf8codepoint);
		else if (rc == UTF8_REJECT) {
			debug_printf("Terminal: invalid UTF-8 sequence ignored, codepoint=%u ch=%d\n", utf8codepoint, (int)ch);
			utf8state = UTF8_ACCEPT;
		}
		// else we need to read more bytes to assemble a codepoint
	}

	bool inputChar(int ch)
	{
		debug_printf("inputChar: %d\n", ch);
		if (ch == 13)
			ch = 10;
		initPty();	// reinit just in case it died before
		// encode the char as UTF-8 and send it to the pty
		std::string c;
		utf8add(c, (uint32_t)ch);
		pty.write(c.c_str(), c.size());
		return true;
	}

	bool inputKey(int key)
	{
		debug_printf("inputKey: %d\n", key);
		switch (key)
		{
			case KEY_UP: pty.write("\e[A"); break;
			case KEY_DOWN: pty.write("\e[B"); break;
			case KEY_RIGHT: pty.write("\e[C"); break;
			case KEY_LEFT: pty.write("\e[D"); break;
			case KEY_HOME: pty.write("\eOH"); break;
			case KEY_END: pty.write("\eOF"); break;
			case KEY_INSERT: pty.write("\e[2~"); break;
			case KEY_DELETE: pty.write("\e[3~"); break;
			case KEY_PAGEUP: pty.write("\e[5~"); break;
			case KEY_PAGEDOWN: pty.write("\e[6~"); break;
			// TODO: other keys
			default:
				return false;
		}
		return true;
	}

	size_t getLinesCount() const { return lines.size(); }
	const Line& getLine(size_t n) { if (unpackedY == n) packLine(); return lines[n]; }
	int getCursorX() const { return cursorX; }
	int getCursorY() const { return cursorY; }
	int getUpdateCounter() const { return updateCounter; }

	void setX(int x)
	{
		x = min(width, max(x, 0));
		cursorX = x;
		++updateCounter;
	}

	void setY(int y)
	{
		//y = min(height, max(y, 0));
		y = max(y, 0);
		cursorY = y;
		while (lines.size() <= (size_t) y)
			lines.push_back(Line());
		++updateCounter;
	}

	void up(int n = 1) { setY(cursorY - n); }
	void down(int n = 1) { setY(cursorY + n); }
	void left(int n = 1) { setX(cursorX - n); }
	void right(int n = 1) { setX(cursorX + n); }

private:
	void packLine()
	{
		std::string& s = lines[unpackedY].text;
		s.clear();
		for (size_t i = 0; i < unpackedLine.cells.size(); ++i) {
			Cell& c = unpackedLine.cells[i];
			utf8add(s, c.cp);
			// later: if attributes changed, add attributes
		}
	}

	void unpackLine(size_t y)
	{
		uint32_t u8state = 0, u8cp = 0;
		std::string& s = lines[y].text;
		unpackedLine.cells.clear();
		for(size_t i = 0; i < s.size(); ++i) {
			uint32_t rc = utf8decode(&u8state, &u8cp, (unsigned char)s[i]);
			if (rc == UTF8_ACCEPT)
				unpackedLine.cells.push_back(Cell(u8cp));
		}
		if (unpackedLine.cells.size() < (size_t)width)
			unpackedLine.cells.resize(width);
		unpackedY = y;
	}

	void ensureUnpacked(size_t y)
	{
		if (unpackedY != y)
		{
			packLine();
			unpackLine(y);
		}
	}

	void processC0(char ch)
	{
		switch (ch)
		{
			case 7: // BEL
				DataManager::Vibrate("tw_button_vibrate");
				break;
			case 8: // BS
				left();
				break;
			case 9: // HT
				// TODO: this might be totally wrong
				right();
				while (cursorX % 8 != 0 && cursorX < width)
					right();
				break;
			case 10: // LF
			case 11: // VT
			case 12: // FF
				down();
				break;
			case 13: // CR
				setX(0);
				break;
			case 24: // CAN
			case 26: // SUB
				state = kStateGround;
				ctlseq.clear();
				break;
			case 27: // ESC
				state = kStateEsc;
				ctlseq.clear();
				break;
		}
	}

	void processCodePoint(CodePoint cp)
	{
		++updateCounter;
		debug_printf("codepoint: %u\n", cp);
		if (cp == 0x9b) // CSI
		{
			state = kStateCsi;
			ctlseq.clear();
			return;
		}
		switch (state)
		{
			case kStateGround:
				processChar(cp);
				break;
			case kStateEsc:
				processEsc(cp);
				break;
			case kStateCsi:
				processControlSequence(cp);
				break;
		}
	}

	void processChar(CodePoint cp)
	{
		ensureUnpacked(cursorY);
		// extend unpackedLine if needed, write ch into cell
		if (unpackedLine.cells.size() <= (size_t)cursorX)
			unpackedLine.cells.resize(cursorX+1);
		unpackedLine.cells[cursorX].cp = cp;

		right();
		if (cursorX >= width)
		{
			// TODO: configurable line wrapping
			// TODO: don't go down immediately but only on next char?
			down();
			setX(0);
		}
		// TODO: update all GUI objects that display this terminal engine
	}

	void processEsc(CodePoint cp)
	{
		switch (cp) {
			case 'c': // TODO: Reset
				break;
			case 'D': // Line feed
				down();
				break;
			case 'E': // Newline
				setX(0);
				down();
				break;
			case '[': // CSI
				state = kStateCsi;
				ctlseq.clear();
				break;
			case ']': // TODO: OSC state
			default:
				state = kStateGround;
		}
	}

	void processControlSequence(CodePoint cp)
	{
		if (cp >= 0x40 && cp <= 0x7e) {
			ctlseq += cp;
			execControlSequence(ctlseq);
			ctlseq.clear();
			state = kStateGround;
			return;
		}
		if (isdigit(cp) || cp == ';' /* || (ch >= 0x3c && ch <= 0x3f) */) {
			ctlseq += cp;
			// state = kStateCsiParam;
			return;
		}
	}

	static int parseArg(std::string& s, int defaultvalue)
	{
		if (s.empty() || !isdigit(s[0]))
			return defaultvalue;
		int value = atoi(s.c_str());
		size_t pos = s.find(';');
		s.erase(0, pos != std::string::npos ? pos+1 : std::string::npos);
		return value;
	}

	void execControlSequence(std::string ctlseq)
	{
		// assert(!ctlseq.empty());
		if (ctlseq == "6n") {
			// CPR - cursor position report
			char answer[20];
			sprintf(answer, "\e[%d;%dR", cursorY, cursorX);
			pty.write(answer, strlen(answer));
			return;
		}
		char f = *ctlseq.rbegin();
		// if (f == '?') ... private mode
		switch (f)
		{
			// case '@': // ICH - insert character
			case 'A': // CUU - cursor up
				up(parseArg(ctlseq, 1));
				break;
			case 'B': // CUD - cursor down
			case 'e': // VPR - line position forward
				down(parseArg(ctlseq, 1));
				break;
			case 'C': // CUF - cursor right
			case 'a': // HPR - character position forward
				right(parseArg(ctlseq, 1));
				break;
			case 'D': // CUB - cursor left
				left(parseArg(ctlseq, 1));
				break;
			case 'E': // CNL - cursor next line
				down(parseArg(ctlseq, 1));
				setX(0);
				break;
			case 'F': // CPL - cursor preceding line
				up(parseArg(ctlseq, 1));
				setX(0);
				break;
			case 'G': // CHA - cursor character absolute
				setX(parseArg(ctlseq, 1)-1);
				break;
			case 'H': // CUP - cursor position
				// TODO: consider scrollback area
				setY(parseArg(ctlseq, 1)-1);
				setX(parseArg(ctlseq, 1)-1);
				break;
			case 'J': // ED - erase in page
				{
					int param = parseArg(ctlseq, 0);
					ensureUnpacked(cursorY);
					switch (param) {
						default:
						case 0:
							unpackedLine.eraseFrom(cursorX);
							if (lines.size() > (size_t)cursorY+1)
								lines.erase(lines.begin() + cursorY+1, lines.end());
							break;
						case 1:
							unpackedLine.eraseTo(cursorX);
							if (cursorY > 0) {
								lines.erase(lines.begin(), lines.begin() + cursorY-1);
								cursorY = 0;
							}
							break;
						case 2: // clear
						case 3:	// clear incl scrollback
							clear();
							break;
					}
				}
				break;
			case 'K': // EL - erase in line
				{
					int param = parseArg(ctlseq, 0);
					ensureUnpacked(cursorY);
					switch (param) {
						default:
						case 0:
							unpackedLine.eraseFrom(cursorX);
							break;
						case 1:
							unpackedLine.eraseTo(cursorX);
							break;
						case 2:
							unpackedLine.cells.clear();
							break;
					}
				}
				break;
			// case 'L': // IL - insert line

			default:
				debug_printf("unknown ctlseq: '%s'\n", ctlseq.c_str());
				break;
		}
	}

private:
	int cursorX, cursorY; // 0-based, char based. TODO: decide how to handle scrollback
	int width, height; // window size in chars
	std::vector<Line> lines; // the text buffer
	UnpackedLine unpackedLine; // current line for editing
	size_t unpackedY; // number of current line
	int updateCounter; // changes whenever terminal could require redraw

	Pseudoterminal pty;
	enum { kStateGround, kStateEsc, kStateCsi } state;

	// for accumulating a full UTF-8 character from individual bytes
	uint32_t utf8state;
	uint32_t utf8codepoint;

	// for accumulating a control sequence after receiving CSI
	std::string ctlseq;
};

// The one and only terminal engine for now
TerminalEngine gEngine;

void terminal_pty_read()
{
	gEngine.readPty();
}


GUITerminal::GUITerminal(xml_node<>* node) : GUIScrollList(node)
{
	allowSelection = false; // terminal doesn't support list item selections
	lastCondition = false;

	if (!node) {
		mRenderX = 0; mRenderY = 0; mRenderW = gr_fb_width(); mRenderH = gr_fb_height();
	}

	engine = &gEngine;
	updateCounter = 0;
}

int GUITerminal::Update(void)
{
	if(!isConditionTrue()) {
		lastCondition = false;
		return 0;
	}

	if (lastCondition == false) {
		lastCondition = true;
		// we're becoming visible, so we might need to resize the terminal content
		InitAndResize();
	}

	if (updateCounter != engine->getUpdateCounter()) {
		// try to keep the cursor in view
		SetVisibleListLocation(engine->getCursorY());
		updateCounter = engine->getUpdateCounter();
	}

	GUIScrollList::Update();

	if (mUpdate) {
		mUpdate = 0;
		if (Render() == 0)
			return 2;
	}
	return 0;
}

// NotifyTouch - Notify of a touch event
//  Return 0 on success, >0 to ignore remainder of touch, and <0 on error
int GUITerminal::NotifyTouch(TOUCH_STATE state, int x, int y)
{
	if(!isConditionTrue())
		return -1;

	// TODO: grab focus correctly
	// TODO: fix focus handling in PageManager and GUIInput
	SetInputFocus(1);
	debug_printf("Terminal: SetInputFocus\n");
	return GUIScrollList::NotifyTouch(state, x, y);
	// TODO later: allow cursor positioning by touch (simulate mouse click?)
	// http://stackoverflow.com/questions/5966903/how-to-get-mousemove-and-mouseclick-in-bash
	// will likely not work with Busybox anyway
}

int GUITerminal::NotifyKey(int key, bool down)
{
	if (down)
		if (engine->inputKey(key))
			mUpdate = 1;
	return 0;
}

// character input
int GUITerminal::NotifyCharInput(int ch)
{
	if (engine->inputChar(ch))
		mUpdate = 1;
	return 0;
}

size_t GUITerminal::GetItemCount()
{
	return engine->getLinesCount();
}

void GUITerminal::RenderItem(size_t itemindex, int yPos, bool selected)
{
	const TerminalEngine::Line& line = engine->getLine(itemindex);

	gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha);
	// later: handle attributes here

	// render text
	const char* text = line.text.c_str();
	gr_textEx_scaleW(mRenderX, yPos, text, mFont->GetResource(), mRenderW, TOP_LEFT, 0);

	if (itemindex == (size_t) engine->getCursorY()) {
		// render cursor
		int cursorX = engine->getCursorX();
		std::string leftOfCursor = line.substr(0, cursorX);
		int x = gr_measureEx(leftOfCursor.c_str(), mFont->GetResource());
		// note that this single character can be a UTF-8 sequence
		std::string atCursor = (size_t)cursorX < line.length() ? line.substr(cursorX, 1) : " ";
		int w = gr_measureEx(atCursor.c_str(), mFont->GetResource());
		gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha);
		gr_fill(mRenderX + x, yPos, w, actualItemHeight);
		gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, mBackgroundColor.alpha);
		gr_textEx_scaleW(mRenderX + x, yPos, atCursor.c_str(), mFont->GetResource(), mRenderW, TOP_LEFT, 0);
	}
}

void GUITerminal::NotifySelect(size_t item_selected)
{
	// do nothing - terminal ignores selections
}

void GUITerminal::InitAndResize()
{
	// make sure the shell is started
	engine->initPty();
	// send window resize
	int charWidth = gr_measureEx("N", mFont->GetResource());
	engine->setSize(mRenderW / charWidth, GetDisplayItemCount(), mRenderW, mRenderH);
}

void GUITerminal::SetPageFocus(int inFocus)
{
	if (inFocus && isConditionTrue())
		InitAndResize();
}
