/*
    See license.txt in the root of this project.
*/

# ifndef LMT_PRINTING_H
# define LMT_PRINTING_H

/*tex

    Printing in \TEX\ is hybrid: in the enumeration below you see the targets. Traditionally \TEX\
    is rather character based, probably because collecting string was costly and because flushing
    to a modem (termimal) can make a printer follow. Anyway, because in \LUAMETATEX, we have much
    more (detailed) logging, the overhead of logging and serializing becomes noticeable. Not all
    low down comes from \TEX: there can be huge differences between consoles, tracing in editors,
    etc.

    It is for this reason that the printing mechanism evolved over years. Sometimes the gains are
    huge, for instance when we're tacing linebreaks or math, so begin August 2026 I decided to
    make it a bit more efficient: we let the formatter collect more and for critital prints also
    pass the length (because in the end \TEX\ meeds it anyway). We only use direct serializers when
    we need extreme performance.

    It's not always pretty but at least we try to be consistent. Occasionally I spend some time on
    making it nicer, so we might see more formatters.

*/

typedef enum selector_settings {
    no_print_selector_code,             /*tex |selector| setting that makes data disappear */
    terminal_selector_code,             /*tex printing is destined for the terminal only */
    logfile_selector_code,              /*tex printing is destined for the transcript file only */
    terminal_and_logfile_selector_code, /*tex normal |selector| setting */
    pseudo_selector_code,               /*tex special |selector| setting for |show_context| */
    new_string_selector_code,           /*tex printing is deflected to the string pool */
    luabuffer_selector_code,
} selector_settings;

typedef struct print_state_info {
    FILE          *logfile;
    char          *loggable_info;
    int            selector;
    int            terminal_offset;
    int            logfile_offset;
    int            new_string_line;
    int            tally;
    unsigned char  trick_buffer[max_error_line + 1]; /* padded */
    int            trick_count;
    int            first_count;
    int            saved_selector;
    int            font_in_short_display; /*tex an internal font number */
    FILE          *saved_logfile;
    int            saved_logfile_offset;
} print_state_info;

extern print_state_info lmt_print_state;

typedef enum spec_units {
    no_unit,
    pt_unit,
    mu_unit,
 // fi_unit,    /* todo */
 // fil_unit,
 // fill_unit,
 // filll_unit,
 // filll_unit,
} spec_units;

/*tex
    Some of these can go away because we stepwise implement usage of |tex_print_format| instead of
    a multitude of specific calls. It's one of these thing I do when I'm bored.

    todo : check tex_print_ln
    todo : check tex_print_nl
    todo : check tex_print_str_nl

*/

extern void        tex_print_ln               (void);   /* always forces a newline */
extern void        tex_print_char             (int s);
extern void        tex_print_tex_str          (int s);
//     void        tex_print_tex_str_esc      (strnumber s);
extern void        tex_print_nlp              (void);   /* flushes a line if we're doing one */
extern void        tex_print_banner           (void);
extern void        tex_print_log_banner       (void);
extern void        tex_print_version_banner   (void);
extern void        tex_print_int              (int n);
extern void        tex_print_hex              (long long n);
//     void        tex_print_uhex             (long long n);
//     void        tex_print_qhex             (long long n);
extern void        tex_print_roman_int        (int n, int numerical);
extern void        tex_print_cs_checked       (halfword p);                       /*tex Also does the |IMPOSSIBLE| etc. */
extern void        tex_print_cs               (halfword p);                       /*tex Only does the undefined case. */
extern void        tex_print_cs_name          (halfword p);                       /*tex Only prints known ones. */
extern void        tex_print_str              (const char *s);
extern void        tex_print_str_len          (const char *s, int len);
//     void        tex_print_str_esc          (const char *s);
extern void        tex_print_posit            (halfword d); 
extern void        tex_print_posit_5          (halfword d); 
extern void        tex_print_dimension        (scaled d, int unit);               /*tex prints a dimension with pt */
extern void        tex_print_sparse_dimension (scaled d, int unit);               /*tex prints a dimension with pt */
extern void        tex_print_unit             (int unit);                         /*tex prints a glue component */
extern void        tex_print_glue             (scaled d, int order, int unit);    /*tex prints a glue component */
extern void        tex_print_glue_set         (halfword p);
extern void        tex_print_spec             (int p, int unit);                  /*tex prints a glue specification */
extern void        tex_print_fontspec         (int p);
extern void        tex_print_mathspec         (int p);
extern void        tex_print_font_identifier  (halfword f);
extern void        tex_print_font_specifier   (halfword e);                       /*tex this is an eq table entry */
extern void        tex_print_font             (halfword f);
extern void        tex_print_char_identifier  (halfword c);
extern void        tex_print_token_list       (const char *s, halfword p);        /*tex prints token list data in braces */
//     void        tex_print_rule_dimension   (scaled d);                         /*tex prints dimension in rule node */
//     void        tex_print_group            (int e);
//     void        tex_print_group_count      (int n);
extern void        tex_print_format           (const char *format, ...);          /*tex similar to the one we use for errors */
extern const char *tex_print_format_args      (const char *format, va_list args); /*tex only for error message */
extern void        tex_begin_diagnostic       (void);
extern void        tex_print_levels           (void);
extern void        tex_end_diagnostic         (void);
extern void        tex_show_box               (halfword p);
extern void        tex_short_display          (halfword p);                       /*tex prints highlights of list |p| */
extern void        tex_print_message          (const char *s);

# endif
