/*************************************************
*    The PMW Music Typesetter - 3rd incarnation  *
*************************************************/

/* Copyright (c) Philip Hazel, 1991 - 2019 */

/* Written by Philip Hazel, starting November 1991 */
/* This file last modified: November 2020 */

/* This is the header file for the score reading routines;
imported by error.c in order to access the input buffers. */


#define read_footingsize      8000     /* These are fixed sizes; heading */
#define read_pageheadingsize 10000     /*   sizes are held in a table */
#define read_maxheadcount        3     /*     with four entries */

#define baraccs_len 108                /* Byte size of baraccs table */
#define stemstacksize          200     /* Byte size of stem stack */
#define beamstacksize          200     /* And beam stack */


/* Bits for remembering which headings/footings have been read, for
the purpose of throwing away old ones at movement starts. These are
also used for selecting default sizes. Additional bits are now used
for remembering which midi parameters have already been changed, for
getting new tables. */

enum {
  rh_footing =      0x001,
  rh_heading =      0x002,
  rh_lastfooting =  0x004,
  rh_pagefooting =  0x008,
  rh_pageheading =  0x010,
  rh_ps =           0x020,
  rh_footnote =     0x040,
  rh_midivoice =    0x080,
  rh_midichannel =  0x100,
  rh_midinote =     0x200,
  rh_midivolume=    0x400
};




/*************************************************
*          Character reading macros              *
*************************************************/


#define sigch() \
  while (read_ch == ' ' || read_ch == '\t' || read_ch == '\n') next_ch()

#define sigchNL() \
  while (read_ch == ' ' || read_ch == '\t') next_ch();

#define next_sigch() \
  while ((next_ch(), read_ch == ' ') || read_ch == '\t' || read_ch == '\n') {}



/*************************************************
*         Macros for trivial functions           *
*************************************************/


#define mac_setstackedstems(flag) \
  while (stave_stemstackptr > 0) \
    { (stave_stemstack[--stave_stemstackptr])->flags |= flag; \
      if (((stave_stemstack[stave_stemstackptr])->flags & nf_chord) != 0) \
        read_sortchord(stave_stemstack[stave_stemstackptr], flag); }


#define mac_setstemflag(noteptr, flag) \
  noteptr->flags |= flag; \
  if ((noteptr->flags & nf_chord) != 0) read_sortchord(noteptr, flag)





/*************************************************
*                  Structures                    *
*************************************************/


/* Structure for remembering stacked files during include */

typedef struct {
  FILE *file;
  uschar *filename;
  int   linenumber;
  int   okdepth;
} filestr;

/* Structure for tables of directives */

typedef struct {
  const char *name;
  void (*proc)(void);
  int  arg1;
  int  arg2;
} dirstr;

/* Structure for remembering data about tie accidentals */

typedef struct {
  uschar pitch;
  uschar acc;
  uschar acc_tp;
} tiedata;

/* Structure for remembering underlay strings */

typedef struct ulaypend {
  struct ulaypend *next;
  uschar *string;
  uschar level;
  uschar size;
  uschar font;
  uschar htype;
  short int flags;
  int  x;
  int  y;
  int  halfway;    /* "halfway" fraction */
  int  offset;     /* "offset" fraction */
} ulaypend;

/* Structure for list of accent/ornament codings */

typedef struct accent {
  uschar *string;
  usint flag;
} accent;


/*************************************************
*             Global variables                   *
*************************************************/

extern usint   accent_list[];        /* List of accent flags, in order */
extern accent  accent_chars[];       /* List of accents/ornaments & flags */

extern bstr  **barvector;           /* Points to bar index */

extern uschar *baraccs;             /* Record of accidentals in a bar */
extern uschar *baraccs_tp;          /* Ditto, transposed */

extern tree_node *define_tree;      /* Root of the tree of defines */

extern uschar  read_accpitch[];     /* Accidental pitch table */
extern int     read_barlinestyle;   /* Current bar's style */
extern uschar  read_basicpitch[];   /* Basic pitch table */
extern int     read_ch;             /* The current character */
extern uschar  *read_chptr;         /* Pointer to next character */
extern int     read_copied_fontsizestr; /* Flag for store managing */
extern dirstr *read_dir;            /* Pointer to found directive */
extern uschar  *read_endptr;        /* End of input line */
extern BOOL    read_endstave;       /* End stave flag */
extern BOOL    read_EOF;            /* EOF reached */
extern filestr *read_filestack;     /* For stacking files */
extern int     read_filestackptr;   /* Pointer for same */
extern int     read_headcount;      /* Count of heading strings */
extern int     read_headingsizes[];
extern int     read_headmap;        /* Map of headings/footings read */
extern b_ensurestr *read_lastensuredtie;      /* For if last is tied chord */
extern b_playchangestr **read_lastplaychange; /* For chaining them all */
extern int     read_linenumber;     /* Line number */
extern int     read_okdepth;        /* For if nesting */
extern int     read_prev_had_dbar;  /* For setting up previous bar block */
extern int     read_prev_had_ibar;
extern int     read_prev_barlinestyle;
extern int     read_skipdepth;      /* For if nesting */
extern BOOL    read_stavedir;       /* TRUE if next stave directive is read */
extern uschar *read_word;           /* Holds word read from input */

extern usint   stave_accentflags;   /* Default for next note */
extern int     stave_accritvalue;   /* holds 2 or 3 */
extern int     stave_barlength;     /* Current bar length */
extern int     stave_barlinestyle;  /* Current bar line style */
extern int     stave_barnumber;     /* Current bar number */
extern int     stave_barrepeatcount;/* Repeat count */
extern bstr   *stave_barrepeatptr;  /* From here */
extern int     stave_beamcount;     /* While reading a beam */
extern b_notestr *stave_beamfirstnote; /* Remembering beam start */
extern BOOL    stave_beaming;       /* TRUE in a beam */
extern b_notestr **stave_beamstack; /* Stack of pending beam */
extern int     stave_beamstackptr;  /* Pointer therein */
extern int     stave_beamstemforce; /* Stem force value in a beam */
extern BOOL    stave_checklength;   /* Check bar length */
extern int     stave_chordcount;    /* Count of notes in last chord */
extern int     stave_clef;          /* Current input clef */
extern int     stave_clef_octave;   /* Sounding octave adjustment */
extern BOOL    stave_copy_accs;     /* Copy accidentals for 'p' and 'x' notes */
extern int     stave_couplestate;   /* Current coupling */
extern int     stave_fbfont;        /* Default initial font */
extern int     stave_fbsize;        /* Default size */
extern BOOL    stave_firstinbar;    /* Flags first note */
extern b_notestr *stave_firstnoteptr; /* The start of the most recent note */
extern BOOL    stave_hadnocount;    /* To ignore 2nd nocount */
extern int     stave_hairpinbegun;  /* Remember state of hairpin */
extern int     stave_hairpinflags;  /* Current hairpin options */
extern int     stave_hairpinsru;    /* Remember sru value */
extern int     stave_hairpinwidth;  /* Current width */
extern int     stave_hairpiny;      /* Default y value */
extern int     stave_key;           /* Current key */
extern int     stave_key_tp;        /* Transposed key */
extern int     stave_lastgracestem; /* Stemforce value for previous grace */
extern b_notestr *stave_lastbasenoteptr; /* Points to start of previous original note */
extern b_notestr *stave_lastnoteptr; /* Points to start of previous note or rest */
extern BOOL    stave_laststemup;    /* Flag */
extern int     stave_lasttiepitch;  /* Pitch of single tied note */
extern BOOL    stave_lastwasdouble; /* Last bar had double bar line */
extern BOOL    stave_lastwastied;   /* Flag */
extern int     stave_matchnum;      /* Factor for triplet/duplet matching */
extern int     stave_matchden;
extern int     stave_maxaway;       /* "Depth" of a beam */
extern int     stave_maxbarlength;  /* High water mark length */
extern int     stave_maxpitch;      /* Max note on a stave */
extern int     stave_minpitch;      /* Min note on a stave */
extern int     stave_noteden;       /* Divides note length */
extern int     stave_noteflags;     /* Default flags */
extern int     stave_notenum;       /* Multiplies note length */
extern BOOL    stave_notes;         /* Notes on/off state */
extern int     stave_octave;        /* Octave number *12 */
extern int     stave_olfont;        /* Default font */
extern int     stave_olsize;        /* Default size */
extern int     stave_ornament;      /* Default ornament */
extern BOOL    stave_overbeam;      /* Continue over bar line */
extern ulaypend *stave_pendulay;    /* Pending underlay chain */
extern int     stave_pitchcount;    /* Count of notes on a stave */
extern int     stave_pitchtotal;    /* Total of pitches on a stave */
extern int     stave_pletflags;     /* Default plet flags */
extern int     stave_pletlen;       /* Current plet parameter */
extern int     stave_pletsupnum;    /* Plet parameters */
extern int     stave_pletsupden;
extern int     stave_plety;         /* Default y value */
extern int     stave_printpitch;    /* Forced printing pitch */
extern int     stave_requiredbarlength; /* As determined by key sig */
extern BOOL    stave_resetOK;       /* [reset] permitted */
extern int     stave_restlevel;     /* current rest level */
extern int     stave_slurcount;     /* Nesting depth */
extern int     stave_smove;         /* Space save after smove */
extern BOOL    stave_smove_relative;/* Relative flag for same */
extern int     stave_stemflag;      /* Default "not noteheads only" */
extern int     stave_stemforce;     /* Current stem option */
extern int     stave_stemlength;    /* Default stem length */
extern b_notestr **stave_stemstack; /* Stack of pending stems */
extern int     stave_stemstackptr;  /* Pointer therein */
extern int    *stave_stemswaplevel; /* Pointer to current table */
extern BOOL    stave_string_followOK; /* OK for a followon string */
extern BOOL    stave_suspended;     /* For automatic resume */
extern int     stave_textabsolute;  /* Default absolute position */
extern int     stave_textflags;     /* Default text flags */
extern int     stave_textfont;      /* Default initial font */
extern int     stave_textsize;      /* Default text size */
extern tiedata *stave_tiedata;      /* For saving tie info */
extern int     stave_ties;          /* Tie direction */
extern int     stave_totalnocount;  /* Count uncounted bars */
extern int     stave_transpose;     /* Current transposition */
extern BOOL    stave_transposedaccforce; /* Default acc forcing */
extern int     stave_transpose_letter; /* Current letter transposition */
extern BOOL    stave_transpose_letter_is_auto; /* Automatically set */
extern BOOL    stave_tripletize;    /* Tripletize dotted quaver pairs */
extern int     stave_ulfont;        /* Default initial font */
extern int     stave_ulsize;        /* Default size */

extern uschar *next_buffer;         /* For reading next line */
extern uschar *this_buffer;         /* The current line */
extern uschar *prev_buffer;         /* The previous line */



/*************************************************
*               Global procedures                *
*************************************************/

extern void next_ch(void);
extern void next_word(void);
extern void next_heading(void);

extern void pre_process(void);

extern BOOL read_bar(void);
extern void read_boolproc(void);
extern int  read_clef(void);
extern int  read_compute_barlength(int);
extern void read_draw(void);
extern drawtextstr *read_draw_text(void);
extern BOOL read_expect_integer(int *, int, int);
extern int  read_getmidinumber(uschar *, uschar *, uschar *);
extern void read_headfootingtext(headstr *, int);
extern void read_initbaraccs(uschar *, int);
extern int  read_integer(BOOL);
extern int  read_key(void);
extern int  read_movevalue(void);
extern void read_note(void);
extern BOOL read_plainstring(void);
extern void read_resetstemflag(b_notestr *, int);
extern int  read_scaletime(int);
extern void read_setbeamstems(void);
extern void read_setfontsfortime(int, int);
extern void read_sortchord(b_notestr *, int);
extern void read_stavedirective(void);
extern int  read_stavepitch(void);
extern int  read_time(void);

/* End of readhdr.h */
