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

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

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

/* This is the header file that contains definitions of the structures used for
holding musical data, and various flags and enumerations. */


/* Offset for overlay string levels */

#define olay_offset 64

/* Tie flags - an 8-bit field; the "savedash" bit is not saved in ties
themselves and could be greater than 128 in fact. It is passed into the
ps_line() function when drawing several lines with the same dash settings. */

#define tief_default     1
#define tief_slur        2
#define tief_gliss       4
#define tief_editorial   8
#define tief_dashed     16
#define tief_dotted     32
#define tief_savedash   64

/* Slur flags - a 16-bit field */

#define sflag_w       0x0001u   /* wiggly */
#define sflag_b       0x0002u   /* below */
#define sflag_l       0x0004u   /* line */
#define sflag_h       0x0008u   /* horizontal */
#define sflag_ol      0x0010u   /* line open on left */
#define sflag_or      0x0020u   /* line open on right */
#define sflag_i       0x0040u   /* intermittent (dashed) */
#define sflag_e       0x0080u   /* editorial */
#define sflag_x       0x0100u   /* crossing */
#define sflag_abs     0x0200u   /* absolutely positioned */
#define sflag_lay     0x0400u   /* at {und,ov}erlay level */
#define sflag_idot    0x0800u   /* intermittent (dotted) */
#define sflag_cx      0x1000u   /* interpret end 'c' options as in MusicXML */

/* Plet flags */

#define plet_a        1
#define plet_b        2
#define plet_lx       4
#define plet_rx       8
#define plet_x       16
#define plet_bn      32
#define plet_by      64
#define plet_abs    128

/* Hairpin flags */

#define hp_below      1
#define hp_middle     2
#define hp_halfway    4
#define hp_abs        8
#define hp_bar       16

/* Control flags on a note. */

#define nf_hidden      0x00000001u  /* Invisible note */
#define nf_coupleU     0x00000002u  /* Up coupled note (to control ledgers) */
#define nf_coupleD     0x00000004u  /* Down coupled note */
#define nf_centre      0x00000008u  /* Centre this (rest) in bar */
#define nf_stemup      0x00000010u  /* Stem direction */
#define nf_plus        0x00000020u  /* Augmentation plus */
#define nf_dot         0x00000040u  /* One augmentation dot */
#define nf_dot2        0x00000080u  /* Two augmentation dots */
#define nf_lowdot      0x00000100u  /* Print dots/plus below line */
#define nf_dotright    0x00000200u  /* Dot/plus moved right because of invert */
#define nf_appogg      0x00000400u  /* Print slash through stem */
#define nf_accrbra     0x00000800u  /* Round bracket for accidental */
#define nf_accsbra     0x00001000u  /* Square bracket for accidental */
#define nf_invert      0x00002000u  /* Print this note on other side of stem */
#define nf_fuq         0x00004000u  /* This note is a free upstemmed quaver */
#define nf_cuesize     0x00008000u  /* Note must print at cue size */
#define nf_cuedotalign 0x00010000u  /* Align cue dots with normal dots */
#define nf_accleft     0x00020000u  /* Explicit accidental move was given */
#define nf_chord       0x00040000u  /* This note is part of a chord */
#define nf_stem        0x00080000u  /* This note has a stem */
#define nf_highdot     0x00100000u  /* Move space dot up to next space */
#define nf_shortened   0x00200000u  /* This note's stem has been automatically shortened */
#define nf_noplay      0x00400000u  /* Do not play - note tied */
#define nf_smallhead   0x00800000u  /* Small notehead */
#define nf_halfacc     0x01000000u  /* Half accidental */
#define nf_tripletize  0x02000000u  /* Check note for tripletizing */
#define nf_headbra     0x04000000u  /* Round bracket around notehead */
#define nf_nhharmonic  0x08000000u  /* Harmonic (diamond) notehead */
#define nf_nhcross     0x10000000u  /* Cross notehead */
#define nf_restrep     0x20000000u  /* Rest displayed as repetition sign */

#define nf_couple      (nf_coupleU+nf_coupleD)
#define nf_dotted      (nf_dot+nf_dot2+nf_plus)
#define nf_notrests    (nf_stemup|nf_smallhead|nf_headbra)

/* Flags for accents on a note. Ornaments are held separately, as individual
numbers less than 256. The table of strings relies on accent bit values being
greater than 255; in other words, don't use the bottom eight bits here without
reworking things. */

#define af_opposite    0x80000000u    /* Print accents on opposite side */
#define af_staccato    0x40000000u    /* Staccato */
#define af_bar         0x20000000u    /* Bar accent */
#define af_gt          0x10000000u    /* Greater Than (>) */
#define af_wedge       0x08000000u    /* Vertical wedge */
#define af_tp          0x04000000u    /* Teepee (large circumflex) */
#define af_vline       0x02000000u    /* Short vertical line */
#define af_down        0x01000000u    /* Violin down bow */
#define af_up          0x00800000u    /* Violin up bow */
#define af_ring        0x00400000u    /* Ring */
#define af_staccatiss  0x00200000u    /* Staccatissimo (teardrop) */

#define af_dynamics   (af_staccato | af_bar | af_gt | af_wedge | \
                       af_tp | af_down | af_up | af_ring | af_vline | \
                       af_staccatiss)

#define af_dyninside  (af_staccato | af_staccatiss | af_bar | af_ring)

#define af_dynoutside (af_gt | af_wedge | af_tp | af_down | af_up | af_vline)

/* Dynamics identification for movement blocks. These are one less
than the user-visible accent numbers. */

enum { dyn_staccato, dyn_bar, dyn_gt, dyn_wedge, dyn_tp,
  dyn_down, dyn_up, dyn_ring, dyn_vline, dyn_staccatiss, dyn_max };

/* Lengths for notes */

#define len_breve      (1152*5*7*11*13)
#define len_semibreve  (len_breve/2)
#define len_minim      (len_breve/4)
#define len_crotchet   (len_breve/8)
#define len_quaver     (len_breve/16)
#define len_squaver    (len_breve/32)
#define len_dsquaver   (len_breve/64)
#define len_hdsquaver  (len_breve/128)

#define TUPLET_ROUND   10  /* Rounding tolerance for tuplets */

/* Note types */

enum { breve, semibreve, minim, crotchet, quaver, squaver, dsquaver, hdsquaver };

/* Ornament types. These are for rarer things that can be moved.
Accidentals above/below notes are handled as ornaments. */

enum {
  or_ferm,        /* Fermata */
  or_tr,          /* Trill */
  or_trsh,        /* Trill + sharp */
  or_trfl,        /* Trill + flat */
  or_trnat,       /* Trill + natural */
  or_trem1,       /* One tremolo line */
  or_trem2,       /* Two tremolo lines */
  or_trem3,       /* Three tremolo lines */
  or_mord,        /* Mordent */
  or_dmord,       /* Double mordent */
  or_imord,       /* Inverted mordent */
  or_dimord,      /* Double inverted mordent */
  or_turn,        /* Turn */
  or_iturn,       /* Inverted Turn */
  or_arp,         /* Arpeggio */
  or_arpu,        /* Arpeggio + up arrow */
  or_arpd,        /* Arpeggio + down arrow */
  or_spread,      /* Spread */

  /* These triples must be in the standard accidental ordering,
  and must be last in this enumeration. */

  or_dsharp, or_dsharprb, or_dsharpsb, /* Double sharp */
  or_flat,   or_flatrb,   or_flatsb,   /* Flat */
  or_dflat,  or_dflatrb,  or_dflatsb,  /* Double flat */
  or_nat,    or_natrb,    or_natsb,    /* Natural */
  or_sharp,  or_sharprb,  or_sharpsb,  /* Sharp, plain & with brackets */
  or_hflat,  or_hflatrb,  or_hflatsb,  /* Half flat */
  or_hsharp, or_hsharprb, or_hsharpsb, /* Half sharp */

  or_accbelow    /* The above are repeated from here, but don't need */
                 /* individual names. */
};

/* Flags for indicating brackets on dynamics and ornaments. */

#define DO_RBRA   0x01
#define DO_RKET   0x02
#define DO_SBRA   0x04
#define DO_SKET   0x08

/* Accidental types. The ordering is by vertical height, which turns out to be
useful. */

enum { ac_none, ac_dsharp, ac_flat, ac_dflat, ac_natural, ac_sharp };

/* Type values that identify each structure in a bar's data. This list of types
must be kept in step with the table of structure lengths called length_table in
src/tables.c. */

enum {
  b_End,      /* End of bar */
  b_Jump,     /* Connection to another block of store */

  b_all, b_barnum, b_beamacc, b_beambreak, b_beambreak2, b_beamrit, b_bowing,
  b_breakbarline, b_caesura, b_chord, b_clef, b_comma, b_dbar, b_dotbar,
  b_dotright, b_draw, b_dynmove, b_ebar, b_endplet, b_endslur, b_ens, b_ensure,
  b_footnote, b_hairpin, b_ibar, b_justify, b_key, b_linegap, b_lrepeat,
  b_masq, b_move, b_name, b_nbar, b_newline, b_newpage, b_nopack, b_note,
  b_noteheads, b_notes, b_ns, b_nsm, b_offset, b_olevel, b_olhere, b_ornament,
  b_page, b_pagebots, b_pagetops, b_playchange, b_plet, b_prevbar, b_reset,
  b_resume, b_rrepeat, b_setclef, b_setkey, b_settime, b_sgabove, b_sghere,
  b_sgnext, b_slope, b_slur, b_slurgap, b_slurmod, b_space, b_ssabove,
  b_sshere, b_ssnext, b_suspend, b_text, b_textX, b_tick, b_tie, b_time,
  b_tremolo, b_tripsw, b_ulevel, b_ulhere, b_unbreakbarline, b_zcopy,

  b_baditem   /* For detecting bad values */
};

/* This is the "generic" structure - the only relevant field
is the type field, which is common to all structures. */

typedef struct {
  uschar type;
} bstr;

/* b_End marks the end of a bar */

typedef struct {
  uschar type;
  uschar overbeam;
  uschar barlinestyle;
} b_Endstr;

/* b_Jump marks a discontinuity in the storage; the next field points to
the next block of storage, minus the length of a b_Jumpstr so that the usual
code for "move on to next" works. */

typedef struct b_Jumpstr {
  uschar type;
  bstr  *next;
} b_Jumpstr;

/* Standard struct for items with one byte arg */

typedef struct {
  uschar type;
  uschar value;
} b_charvaluestr;

/* Standard struct for items with single dimension arg */

typedef struct {
  uschar type;
  int value;
} b_intvaluestr;

/* The remainder of the structures are actual musical items. Each has its own
structure. Some are the same as others, but by giving each its own name it will
be easier to alter them if necessary. */

typedef bstr b_allstr;

typedef struct {
  uschar type;
  uschar flag;
  int x;
  int y;
} b_barnumstr;

typedef b_charvaluestr b_beamaccstr;
typedef bstr           b_beambreakstr;
typedef b_charvaluestr b_beambreak2str;
typedef b_charvaluestr b_beamritstr;
typedef b_charvaluestr b_bowingstr;
typedef bstr           b_breakbarlinestr;
typedef bstr           b_caesurastr;

typedef struct {
  uschar type;
  uschar notetype;
  uschar acc;
  uschar spitch;
  uschar truepitch;
  uschar orig;
  short int accleft;
  usint flags;
  usint acflags;
  int length;
  int yextra;
} b_chordstr;

typedef struct {
  uschar type;
  uschar trueclef;
  uschar suppress;
} b_clefstr;

typedef bstr b_commastr;
typedef bstr b_dbarstr;
typedef bstr b_dotbarstr;
typedef bstr b_ebarstr;

typedef b_intvaluestr b_dotrightstr;

typedef struct {
  uschar type;
  uschar overflag;
  tree_node *item;
  drawitem *args;
} b_drawstr;

typedef struct {
  uschar type;
  uschar dynamic;
  uschar bflags;
  int x;
  int y;
} b_dynmovestr;

typedef bstr b_endpletstr;

typedef struct {
  uschar type;
  uschar id;
} b_endslurstr;

typedef bstr b_ensstr;
typedef b_intvaluestr b_ensurestr;

typedef struct {
  uschar type;
  headstr h;
} b_footnotestr;

typedef struct {
  uschar type;
  uschar opt;
  uschar flags;
  int x;
  int y;
  int offset;    /* "Offset" fraction */
  int su;        /* Split end up/down */
  int h;         /* "Halfway" fraction */
  int width;     /* Width of open end */
} b_hairpinstr;

typedef bstr b_ibarstr;

typedef struct {
  uschar type;
  uschar opt;
  uschar side;
} b_justifystr;

typedef struct {
  uschar type;
  uschar key;
  uschar suppress;
  uschar warn;
} b_keystr;

typedef struct {
  uschar type;
  uschar id;
  int hfraction;
  int xadjust;
  int width;
  tree_node *draw;
  drawitem *args;      /* for drawing */
  gaptextstr *gaptext;
} b_linegapstr;

typedef bstr           b_lrepeatstr;
typedef b_charvaluestr b_masqstr;

typedef struct {
  uschar type;
  uschar relative;
  int x;
  int y;
} b_movestr;

typedef struct {
  uschar type;
  uschar n;
} b_namestr;

typedef struct {
  uschar type;
  uschar n;
  uschar ssize;
  uschar *s;
  int x;
  int y;
} b_nbarstr;

typedef bstr           b_newlinestr;
typedef bstr           b_newpagestr;
typedef bstr           b_nopackstr;
typedef b_chordstr     b_notestr;       /* sic (an actual note) */
typedef b_charvaluestr b_noteheadsstr;
typedef b_charvaluestr b_notesstr;      /* sic (notes on/off) */

typedef struct {
  uschar type;
  int ns[8];
} b_nsstr;

typedef b_intvaluestr  b_nsmstr;
typedef b_intvaluestr  b_offsetstr;

typedef struct {
  uschar type;
  uschar opt;
  int value;
} b_olevelstr;

typedef b_intvaluestr  b_olherestr;

typedef struct {
  uschar type;
  uschar ornament;
  uschar bflags;
  int x;
  int y;
} b_ornamentstr;

typedef struct {
  uschar type;
  uschar relative;
  int value;
} b_pagestr;

typedef b_intvaluestr  b_pagebotsstr;
typedef b_intvaluestr  b_pagetopsstr;

typedef struct b_playchangestr {
  uschar type;
  uschar stave;
  short int barno;
  struct b_playchangestr *next;
  short int transpose;
  uschar channel;
  uschar voice;
  uschar note;
  uschar volume;
} b_playchangestr;

typedef struct {
  uschar type;
  uschar pletlen;
  uschar flags;
  int x;
  int yleft;
  int yright;
} b_pletstr;

typedef struct {
  uschar type;
  uschar dbar;
  uschar ibar;
  uschar style;
} b_prevbarstr;

typedef bstr           b_resetstr;
typedef bstr           b_resumestr;
typedef bstr           b_rrepeatstr;

typedef b_charvaluestr b_setclefstr;
typedef b_charvaluestr b_setkeystr;
typedef b_intvaluestr  b_settimestr;

typedef struct {
  uschar type;
  uschar opt;
  int value;
} b_sgstr;

typedef b_intvaluestr  b_slopestr;

/* Structure for holding a set of slur modifications, which might repeat
for different parts of a split slur. */

typedef struct b_slurmodstr {
  uschar type;
  short int sequence;
  struct b_slurmodstr *next;
  int lxoffset;
  int lx;
  int ly;
  int rxoffset;
  int rx;
  int ry;
  int c;
  int clx;
  int cly;
  int crx;
  int cry;
} b_slurmodstr;

/* The basic slur structure */

typedef struct {
  uschar type;
  uschar id;
  short int flags;
  int ally;
  b_slurmodstr *mods;
} b_slurstr;

typedef struct {
  uschar type;
  uschar relative;
  int value;
} b_spacestr;

typedef struct {
  uschar type;
  uschar opt;
  uschar stave;
  int value;
} b_ssstr;

typedef bstr b_suspendstr;

typedef struct {
  uschar type;
  uschar font;
  uschar size;
  uschar htype;
  uschar ulevel;
  uschar ulen;
  short int flags;
  uschar *string;
  int x;
  int y;
} b_textstr;

typedef struct {
  uschar type;
  int rotate;
  int halfway;      /* "Halfway" fraction */
  int offset;       /* "Offset fraction */
} b_textXstr;

typedef bstr b_tickstr;

typedef struct {
  uschar type;
  uschar flags;
  uschar abovecount;
  uschar belowcount;
  b_notestr *note;
} b_tiestr;

typedef struct {
  uschar type;
  uschar warn;
  uschar suppress;
  int time;
} b_timestr;

typedef struct {
  uschar type;
  uschar count;
  uschar join;
} b_tremolostr;

typedef b_charvaluestr  b_tripswstr;

typedef struct {
  uschar type;
  uschar opt;
  int value;
} b_ulevelstr;

typedef b_intvaluestr b_ulherestr;
typedef bstr          b_unbreakbarlinestr;
typedef b_intvaluestr b_zcopystr;

/* End of barhdr.h */
