//! \~\file piterminal.h
//! \~\ingroup Console
//! \brief
//! \~english Virtual terminal
//! \~russian Виртуальный терминал
/*
    PIP - Platform Independent Primitives
    Virtual terminal
    Ivan Pelipenko peri4ko@yandex.ru

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

    This program 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 Lesser General Public License for more details.

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

#ifndef PITERMINAL_H
#define PITERMINAL_H

#include "pikbdlistener.h"
#include "pip_console_export.h"
#include "piscreentypes.h"


//! \~\ingroup Console
//! \~\brief
//! \~english Virtual terminal that runs a shell and mirrors its screen into a cell buffer.
//! \~russian Виртуальный терминал, который запускает оболочку и отражает ее экран в буфер ячеек.
//! \details
//! \~english Provides terminal emulation for reading console input and output. Supports ANSI escape sequences for cursor movement, colors,
//! and text formatting.
//! \~russian Обеспечивает эмуляцию терминала для чтения ввода и вывода консоли. Поддерживает ANSI escape-последовательности для перемещения
//! курсора, цветов и форматирования текста.
class PIP_CONSOLE_EXPORT PITerminal: public PIThread {
	PIOBJECT_SUBCLASS(PITerminal, PIThread);

public:
	//! \~english Constructs %PITerminal.
	//! \~russian Создает %PITerminal.
	PITerminal();

	//! \~english Destroys the terminal and releases backend resources.
	//! \~russian Уничтожает терминал и освобождает внутренние ресурсы.
	~PITerminal();

	//! \~english Returns terminal width in columns.
	//! \~russian Возвращает ширину терминала в столбцах.
	int columns() const { return size_x; }

	//! \~english Returns terminal height in rows.
	//! \~russian Возвращает высоту терминала в строках.
	int rows() const { return size_y; }

	//! \~english Resizes the terminal viewport and backing cell buffer.
	//! \~russian Изменяет размер области терминала и связанного буфера ячеек.
	bool resize(int cols, int rows);

	//! \~english Sends raw byte data to the terminal input.
	//! \~russian Отправляет необработанные байты во входной поток терминала.
	void write(const PIByteArray & d);

	//! \~english Sends a special key with modifiers to the terminal.
	//! \~russian Отправляет в терминал специальную клавишу с модификаторами.
	void write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers m);

	//! \~english Sends a keyboard event to the terminal.
	//! \~russian Отправляет событие клавиатуры в терминал.
	void write(PIKbdListener::KeyEvent ke);

	//! \~english Returns the current terminal screen snapshot, including cursor blink state.
	//! \~russian Возвращает текущий снимок экрана терминала с учетом состояния мигания курсора.
	PIVector<PIVector<PIScreenTypes::Cell>> content();

	//! \~english Returns whether key code `k` is handled as a special terminal key.
	//! \~russian Возвращает, обрабатывается ли код `k` как специальная клавиша терминала.
	static bool isSpecialKey(int k);

	//! \~english Initializes the terminal backend and starts the polling thread.
	//! \~russian Инициализирует внутренний терминал и запускает поток опроса.
	bool initialize();

	//! \~english Stops the terminal and destroys the internal terminal backend instance.
	//! \~russian Останавливает терминал и уничтожает внутреннюю реализацию терминала.
	void destroy();

private:
	void initPrivate();
	void readConsole();
	void getCursor(int & x, int & y);
	uchar invertColor(uchar c);
	void run() override;
#ifndef WINDOWS
	void parseInput(const PIString & s);
	bool isCompleteEscSeq(const PIString & es);
	void applyEscSeq(PIString es);
	void moveCursor(int dx, int dy);
	int termType(const PIString & t);
#endif

	PRIVATE_DECLARATION(PIP_CONSOLE_EXPORT)
	int dsize_x, dsize_y;
	int size_x, size_y, cursor_x, cursor_y;
	bool cursor_blink, cursor_visible;
	PITimeMeasurer cursor_tm;
	PIVector<PIVector<PIScreenTypes::Cell>> cells;
};


#endif // PITERMINAL_H
