#ifndef EMULATOR_H
#define EMULATOR_H

/* arch-tag: b7ea9e43-da17-4cfa-9831-3cd434d8ac8e */

#include <stdbool.h>
#include <stdio.h>

#include <X11/Xlib.h>

#include "pane.h"
#include "script.h"
#include "resizeable_buf.h"
#include "bitfield.h"

enum emulator_state {
        ground_state,
        csi_entry_state,
        csi_ignore_state,
        csi_intermediate_state,
        csi_param_state,
        escape_state,
        escape_intermediate_state,
        misc_string_state,
        osc_string_state,
        dcs_entry_state,
        dcs_intermediate_state,
        dcs_ignore_state,
        dcs_param_state,
        dcs_passthrough_state,
        vt52_1_state,
        vt52_2_state
};

struct emulate {
        enum emulator_state state;
        int cols, rows;
        rb_t v_param;
        rb_t v_chars;
        rb_t v_collect;
        int scroll_begin;
        int scroll_end;
        struct cell style;
        struct cell blank_style;
        //std::vector<wchar_t> v_chars, v_collect, v_reply;
        //std::vector<int> v_param;
        bool mode_irm : 1;
        bool mode_kam : 1;
        bool mode_srm : 1;
        bool mode_lnm : 1;
        bool mode_decckm : 1;
        bool mode_decanm : 1;
        bool mode_deckpam : 1;
        bool mode_dectcem : 1;
        struct cursor {
                int col, row;
                bool mode_decom : 1;
                bool mode_decawm : 1;
                int charset, charset_save;  // index into charset[4]
                //Style const * style;
                //Null<wchar_t const *> charset, charset_save;
                //Cursor(): style(new Style) { }
        } cursor, saved ;
        struct pty *pty;
        wchar_t const * charset[4];
        bitfield_t *tabs;
};

struct emulate * emulate_create(void);
void emulate_data(struct emulate *e, void const *text, int length, sc_t *output, bool latin1);
void emulate_set_size(struct emulate * e, int c, int r);
void print_emulator_state(FILE *f, struct emulate *e);

/*
class Emulator {
public:
    struct Style: public gc {
        Init<bool, false> is_bold, is_underline, is_blink, is_inverse;
    };

    class Output {
    public:
        virtual ~Output() { }
        virtual void set_text(
            int col, int row, int length,
            wchar_t const *, Emulator::Style const *) = 0;
        virtual void set_cursor(int col, int row) = 0;
        virtual void copy(
            int from_col, int from_row,
            int to_col, int to_row,
            int width, int height) = 0;
        virtual void clear(
            int col, int row,
            int width, int height, Emulator::Style const *) = 0;
        virtual void bell() = 0;
    };

    Emulator();
    void set_size(int cols, int rows);
    void set_cursor(int col, int row);
    void data(int length, wchar_t const *, Output *);
    void event(XKeyEvent const &, Output *);
    int get_reply(wchar_t * buffer, int length);

private:

    struct Cursor {
        Init<int, 0> col, row;
        Init<bool, false> mode_decom;
        Init<bool, true> mode_decawm;
        Style const * style;
        Null<wchar_t const *> charset, charset_save;
        Cursor(): style(new Style) { }
    };

    Init<int, 0> cols, rows;
    Init<int, 0> scroll_begin, scroll_end;
    Init<emulator_state, ground_state> state;
    std::vector<bool> tabs;
    Cursor cursor, saved;

    Init<bool, false> mode_kam;
    Init<bool, false> mode_irm;
    Init<bool, true> mode_srm;
    Init<bool, false> mode_lnm;
    Init<bool, false> mode_decckm;
    Init<bool, true> mode_decanm;
    Init<bool, false> mode_deckpam;
    wchar_t const * charset[4];

    std::vector<wchar_t> v_chars, v_collect, v_reply;
    std::vector<int> v_param;

    static wchar_t const * const charset_uk, * const charset_special;
    static Style const * const blank_style;

    bool is_printable(wchar_t ch);
    void scroll(int begin, int end, int num, Output *);
    void data(wchar_t, Output *);
    void dispatch_csi(wchar_t, Output *);
    void dispatch_esc(wchar_t, Output *);
    void stuff(wchar_t const *);
    void stuff(char const *);
}; */

#endif

