#pragma once

/*
	Terminal
	by John Ryland
	Copyright (c) 2023
*/

////////////////////////////////////////////////////////////////////////////////////
//	Terminal Emulator

#include "TerminalProcess.h"
#include <cstdint>

namespace Terminal {

class TerminalEmulator
{
public:
    TerminalEmulator();
    virtual ~TerminalEmulator();

    virtual void Initialize();
    virtual void Shutdown();
    virtual void Update();

    virtual void HandleInput();
    virtual void Display();
    virtual void DrawCursor();

    void UpdateSize(int availableX, int availableY);

// TODO: make private
public:
    static const int BUFFER_COUNT = 2;  // main and alt buffers
    static const int MAX_SCROLL_BACK_LINES = 100;
    static const int MAX_LINE_COLUMNS = 250;

    enum class CharAttrib : uint8_t;

    struct Char
    {
        char       ch;
        CharAttrib attrib;
        uint32_t   foregroundColor;
        uint32_t   backgroundColor;
    };

    void PushChar(char ch);
    void DecodeChar(char ch);
    void ReadChars();
    void SendChar(char ch);
    void ResetDecoder();
    void DecodeRawChar(char ch);
    void DecodeEscapeSequence(char ch);
    void DecodeControlSequence(char ch);
    void DecodeEscapeSpecial(char ch);
    void DecodeCommandSequence(char ch);
    void BuildColorLookupTable();
    void NewLine();
    void SetCursorPosition(int x, int y);

    int GetParam(int defaultVal=1, int param=0);
    Char* Line(int line);

    int      m_cursorX;
    int      m_cursorY;
    int      m_savedCursorX;
    int      m_savedCursorY;
    int      m_fontHeight;
    int      m_fontWidth;
    int      m_currentColumns;
    int      m_currentLines;
    int      m_viewWidth;
    int      m_viewHeight;
    int      m_decodeState1;
    int      m_decodeState2;
    int      m_paramCount;
    int      m_paramOffset;
    int      m_topMargin[2];
    int      m_bottomMargin[2];
    int      m_leftMargin = 0;
    int      m_rightMargin = 0;

    bool     m_needScrollToY = false;

    // Special commands
    bool     m_appArrowKeys    = false;    // ?1h     : Application cursor keys
    bool     m_wrap            = true;     // ?7h     : Line wrapping on
    bool     m_blinkCursor     = false;    // ?12h    : Blink the cursor
    bool     m_showCursor      = true;     // ?25h    : Show the cursor
    bool     m_saveScreen      = false;    // ?47h    : Save screen    ?47l    : Restore screen
    bool     m_reportFocus     = false;    // ?1004h  : Send ESC [I and ESC [O  for in/out focus
    bool     m_altScreenBuffer = false;    // ?1049h  : Use alternative screen buffer
    bool     m_bracketedPaste  = false;    // ?2004h  : Send pasted text surrounded by:  ESC [200~ and ESC [201~ 

    // OS command
    int      m_osc = 0;
    char     m_title[256];
    char     m_oscText[256];
    int      m_oscTextLen;

    // Debug - circular buffer
    uint8_t  m_charHistoryIdx = 0;
    char     m_charHistory[256]; 

    char     m_params[10][10]; 

    Char*    m_windowMemory = nullptr;
    Char**   m_textWindow;
    Char*    m_mainWindow[MAX_SCROLL_BACK_LINES];
    Char*    m_altWindow[MAX_SCROLL_BACK_LINES];
    Char     m_currentAttributes;
    uint32_t m_colorLookupTable[256];

    TerminalProcess m_process;
};

} // Terminal namespace
