#ifndef SCRIPT_H
#define SCRIPT_H

#include "resizeable_buf.h"
#include "colors.h"

/* a script is a series of lines of text, that don't necessarily coorespond to what is dispalyed on the screen
 * by playing back a script, you can fully recreate a view of the screen.
 *
 * the script always looks like this
 *
 * ------------
 * | protected|
 * |          |
 * |----------|  - display starts here
 * | virtual  |
 * |          |
 * |----------|
 * | pending  |
 * |          |
 * |----------|
 * | dirty    |
 * |          |
 * |----------|  - ends here
 *
 * pending are lines on the screen, when they scroll off the top, they become protected.
 * they can be dirtied.
 *
 * virtual lines turn into protected ones if they scroll off the top, but are
 * copied if dirtied. (with one copy becoming protected, the other being
 * dirtied)
 *
 * dirty lines must be reread from the pane if needed. this is done lazily.
 *
 * virtual and dirty are often empty, virtual ones come about by resizing a
 * window to be larger or saving the state of a full screen program in the
 * scrollback. dirty ones come about by editing a line.
 *
 * new lines are always added in the pending state at the botom. this can
 * cause the dirty lines to need to be refreshed to bring them back into the
 * pending state.
 *
 *
 * the script data structure itself consists of a stream of normalized utf8
 * text, with embedded control sequences of forms described below. the control
 * sequences are not related to ascii control sequences and are only used
 * internally by the script engine. The utf8 text is not arbitrary, but of a
 * special normalized form.
 *
 */



typedef struct script_line script_line_t;



/* control characters
 *
 * '\0' - unused.
 * '\n' - reserved for separating script lines.
 * '\r' - reserved for specifying soft breaks.
 * '\t' <n:byte> - skip n characters, created by a tab.
 * ' '           - a space
 * 0x01 <attr:struct char_attr> - set attributes. absolute. idempotent
 * 0x02 <fg:struct color *> - set foreground color
 * 0x03 <bg:struct color *> - set background color
 *
 */


struct char_attr {
        bool double_width : 1;
        bool italic : 1;
        bool bold : 1;
        bool underline : 1;
        bool overstrike : 1;
        bool blink : 1;
        bool inverse :1;
        bool subscript : 1;
        bool superscript : 1;
        bool rapidblink :1;
        bool dim : 1;
};


struct script_line {
        short ref;
        bool is_deleted : 1;
        bool is_protected : 1;  // cannot change, in scrollback
        bool is_virtual   : 1;  // virtual, copy on dirty
        bool noflow : 1;        // inhibit reflowing if line is too long
        bool dirty : 1;         // dirty, must be read back in.
        rb_t chars;
        script_line_t *next;
        script_line_t *prev;
};

typedef struct script_consumer sc_t;

void script_text(sc_t *sc, const char *text, int length);
void script_tab(sc_t *sc, int n);
void script_setattr(sc_t *sc, struct char_attr);
void script_setfgcolor(sc_t *sc, struct color *fg);
void script_setbgcolor(sc_t *sc, struct color *bg);
script_line_t *script_newline(sc_t *sc);


// dirty up a line, along with passing it an object to replay the line information into.
void script_dirty(sc_t *sc, script_line_t *l, void *data);

struct pane;
sc_t *script_new(void);
struct pane *script_getpane(sc_t *sc);

// split a line at character n, returning the new line or null if the line was too short.
script_line_t *script_split(sc_t *sc, script_line_t *l, int n);
script_line_t *script_insert_after(sc_t *sc, script_line_t *l);

// cause a line and all preceding lines to be protected, must not discard any
// information needed to read in dirtied lines until this returns so they can
// be read back in by the script as needed when they become protected.
void script_protect(sc_t *sc, script_line_t *l);

#ifdef lines
#undef lines
#endif

struct script_consumer {
        enum { sc_pane, sc_line, sc_record } type;
        struct pane *pane;
        script_line_t lines;
};


#endif

