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

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

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

/* This is the header file that contains definitions of the structures used for
holding musical data. */


/* 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       0x0001   /* wiggly */
#define sflag_b       0x0002   /* below */
#define sflag_l       0x0004   /* line */
#define sflag_h       0x0008   /* horizontal */
#define sflag_ol      0x0010   /* line open on left */
#define sflag_or      0x0020   /* line open on right */
#define sflag_i       0x0040   /* intermittent (dashed) */
#define sflag_e       0x0080   /* editorial */
#define sflag_x       0x0100   /* crossing */
#define sflag_abs     0x0200   /* absolutely positioned */
#define sflag_lay     0x0400   /* at {und,ov}erlay level */
#define sflag_idot    0x0800   /* intermittent (dotted) */

/* 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      0x00000001  /* Invisible note */
#define nf_coupleU     0x00000002  /* Up coupled note (to control ledgers) */
#define nf_coupleD     0x00000004  /* Down coupled note */
#define nf_centre      0x00000008  /* Centre this (rest) in bar */
#define nf_stemup      0x00000010  /* Stem direction */
#define nf_plus        0x00000020  /* Augmentation plus */
#define nf_dot         0x00000040  /* One augmentation dot */
#define nf_dot2        0x00000080  /* Two augmentation dots */
#define nf_lowdot      0x00000100  /* Print dots/plus below line */
#define nf_dotright    0x00000200  /* Dot/plus moved right because of invert */
#define nf_appogg      0x00000400  /* Print slash through stem */
#define nf_accrbra     0x00000800  /* Round bracket for accidental */
#define nf_accsbra     0x00001000  /* Square bracket for accidental */
#define nf_invert      0x00002000  /* Print this note on other side of stem */
#define nf_fuq         0x00004000  /* This note is a free upstemmed quaver */
#define nf_cuesize     0x00008000  /* Note must print at cue size */
#define nf_cuedotalign 0x00010000  /* Align cue dots with normal dots */
#define nf_accleft     0x00020000  /* Explicit accidental move was given */
#define nf_chord       0x00040000  /* This is the first note of a chord */
#define nf_stem        0x00080000  /* This note has a stem */
#define nf_highdot     0x00100000  /* Move space dot up to next space */
#define nf_shortened   0x00200000  /* This note's stem has been automatically shortened */
#define nf_noplay      0x00400000  /* Do not play - note tied */
#define nf_smallhead   0x00800000  /* Small notehead */
#define nf_halfacc     0x01000000  /* Half accidental */

#define nf_couple    (nf_coupleU+nf_coupleD)
#define nf_dotted    (nf_dot+nf_dot2+nf_plus)

/* 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    0x80000000    /* Print accents on opposite side */
#define af_staccato    0x40000000    /* Staccato */
#define af_bar         0x20000000    /* Bar accent */
#define af_gt          0x10000000    /* Greater Than (>) */
#define af_wedge       0x08000000    /* Vertical wedge */
#define af_tp          0x04000000    /* Teepee (large circumflex) */
#define af_vline       0x02000000    /* Short vertical line */
#define af_down        0x01000000    /* Violin down bow */
#define af_up          0x00800000    /* Violin up bow */
#define af_ring        0x00400000    /* Ring */
#define af_staccatiss  0x00200000    /* 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 */

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_sghere,    b_sgnext,       b_slope,     b_slur,
  b_slurgap,        b_slurmod,   b_space,        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;
  int flags;
  int 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 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 lx;
  int ly;
  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 */
} 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 */
