#include "pre_mus.h"

mod (modi) {			/*    remainder mod 12    */
    return (modi + 120) % 12;
}

note_to_int (ch1, ch2) char ch1,
                            ch2;
/* convert 2 char note to int, look it up in scale */
{
    int     i,
            start;
    start = accid_mode == EXPLACCID ? 8 :
	accid_mode == SEMIACCID ? root_now :
	accid_mode == AUTOACCID ? root_now :
	root_now;
    for (
	    i = start - 1;	/* start at e.g. F below C */
	    i < start + 6 && scale[i % 7][0] != ch1;
	    i++
	);
    if (i >= start + 6) {	/* not found */
	ioerror ("Error in note_to_int \"%c%c\"\n", ch1, ch2);
	return - 1;
    }
 /* explicit n_accids */
    if (accid_mode == EXPLACCID) {
/*	  if ( ch2 == ' ' ) return i; */
	if (ch2 == '+' || ch2 == '-') {
	    i = addaccid (i, ch2);
	}
	if (ch2 == '=') {
	    setaccid (i, ' ');
	}
	return i;
/*	  ioerror( "note to int %c %c", ch1, ch2 ); */
    }
 /* usual, assume sharps & flats of current key */
 /* no n_accid specified */
    if (ch2 == ' ') {
	i = addaccid (i, baraccid[i % 7]);
    }
    else
	if (ch2 == SAMESYM) {	/* natural */
	    if (i >= 14) {	/* normally a sharp */
		setaccid (i, '-');
		i -= 7;
	    }
	    else
		if (i < 7) {	/* normally a flat */
		    setaccid (i, '+');
		    i += 7;
		}
		else {
		    if (verbose && getaccid (i) == ' ')
			iowarn ("Natural on natural note", 0, 0);
		    setaccid (i, ' ');
		}
	}
	else
	    if (ch2 == '+') {	/* sharp specified */
		setaccid (i, '+');
		i += 7;
	    }
	    else
		if (ch2 == '-') {/* flat specified */
		    setaccid (i, '-');
		    i -= 7;
		}
    if (i < 0)
	i += 12;
    if (i >= 21)
	i -= 12;
    return i;
}

puttext (s) char   *s;
{
    int     over = 0,
            under = 0;
    putchar (' ');
    while (*s) {
	if (*s == UTEXTSYM)
	    under = 1 - under;
	if (*s == OTEXTSYM)
	    over = 1 - over;
	if ((textover || (!over && *s != OTEXTSYM))
		&& (textunder || (!under && *s != UTEXTSYM))) {
	    putchar (*s);
	}
	s++;
    }
}

putnote (note) {		/* put given note */
    struct notes   *notep = notev + note;
    int     i;
    for (i = notep -> n_tie_start; i > 0; i--)
	printf ("%c", TIESTART);
    if (notep -> n_beam > 0)
	printf ("%c", BEAMSTART);
    if (notep -> n_group > 0)
	printf ("%c", GROUPSTART);
    printf (" %c%c%3d", notep -> n_pitch, notep -> n_octv, notep -> n_length);
    if (notep -> stickup > 0)
	printf ("%c", 'u');
    if (notep -> stickup < 0)
	printf ("%c", 'd');
    if (notep -> n_tnote)
	puttext (notep -> n_tnote);
    if (notep -> n_group == 0 && notev[note - 1].n_group)
	printf ("%c", GROUPEND);
    if (notep -> n_beam < 0)
	printf ("%c", BEAMEND);
    for (i = notep -> n_tie_end; i > 0; i--)
	printf ("%c", TIEEND);
    printf (";");
}

putbar (b) {			/* put given bar */
    int     beat,
            part,
            stff;
    struct bars *barp = barv + b;
    if (verbose == 10) {
	barprint( b );
	return;
    }
    if ( verbose == 11 ) {
	for ( part = 0; part < n_parts; part++ ) {
	    for (beat = bar_first_note[b][part];
		beat < bar_last_note[b][part];
		beat++) {
		noteprint (beat);
	    }
	}
    }

    if (bar_first_note[b][0] == bar_last_note[b][n_parts - 1]) {
	if (b == 0)
		printf ("|\n");
	return;
    }

 /* put out any change of output clefs */
    for (stff = 0; stff < n_staffs; stff++) {
	if (barp -> b_clef[stff])
		printf ("\n\\c %d %c ", stff, barp -> b_clef[stff]);
    }
 /* put out any change of output key */
    if (barp -> b_root) {
	    printf ("\n\\k %c ", barp -> b_root + 'a');
    }
 /* put out any change of time tsig */
    if (barp -> b_n_tsig) {
	tsig_n_now = barp -> b_n_tsig;
	tsig_d_now = barp -> b_d_tsig;
	    printf ("\n\\t %d %d ", tsig_n_now, tsig_d_now);
    }
 /* change to bps */
    if (barp -> b_bps && verbose <= 1)
	printf ("\n\\n %d ", barp -> b_bps);
 /* change to width */
    if (barp -> b_s_width && verbose <= 1)
	printf ("\n\\w %d ", barp -> b_s_width);
 /* print the notes */
    for (part = 0; part < n_parts; part++)
	if ( bar_first_note[b][part] < bar_last_note[b][part]
		&& partnos[part] >= 0) {
	    if (part != part_now) {
		printf ("\n\\p %d ", part);
		part_now = part;
	    }
	    if (barp -> b_tover[partv[part].pt_end_stave])
		puttext (barp -> b_tover[partv[part].pt_end_stave]);
	    for (beat = bar_first_note[b][part]; beat < bar_last_note[b][part]; beat++) {
		putnote (beat);
	    }			/* end there are notes in this part */
	}			/* end for all parts */
 /* print barline and type */
	printf (" %c", barp -> b_new_stave ? NBARSYM : BARSYM);
	if (barp -> b_end_type)
	    printf (" %c", barp -> b_end_type);
	printf ("\n");
}

putpiece () {
    int     b;
    if (nerrs () || n_staves == 0)
	return;
    if (reset <= 0)
	return;
    if (firstexec)
	printf (".sp -0.15i\n");
    printf (".MS\n");
    puthead ();
    for (b = 0; b < bar; b++) {
	putbar (b);
    }
	printf (".ME\n");
    firstexec++;
}

puthead () {
    int     i;
    if (verbose <= 1) {
	printf ("\"%s\" # ltitle\n",
		piecev.left_title ? piecev.left_title : "");
	printf ("\"%s\" # ctitle\n",
		piecev.centre_title ? piecev.centre_title : "");
	printf ("\"%s\" # rtitle\n",
		piecev.right_title ? piecev.right_title : "");
    /* n_staves */
	printf ("%d # nstaffs\n", n_staffs);
    /* per stave; clefs, keyoffset, octv, join_down */
	for (i = 0; i < n_staffs; i++) {
	    printf ("%c %d %d \"%s\" %d\n",
		    staffv[0][i].s_clef, staffv[0][i].s_key_offset,
		    staffv[0][i].s_octv,
		    staffv[0][i].s_instrument ? staffv[0][i].s_instrument : "",
		    staffv[0][i].s_join_down);
	}
    /* n_parts */
	printf ("%d # n_parts\n", n_parts - parts_ignored);
    /* per part; stave, pt_updown */
	for (i = 0; i < n_parts; i++)
	    if (partnos[i] >= 0)
		printf ("%d %d\n",
			partv[i].pt_end_stave, partv[i].pt_updown);
    /* this piece */
	printf ("%c # root\n", piecev.p_root + 'a');
	printf ("%d; %d %d # nbars tsig\n",
		piecev.p_bars, piecev.p_tsig_n, piecev.p_tsigd);
	printf ("%d %d # ist gaps\n",
		i_stave_gap, i_staff_gap);
	printf ("%d; %d; %d # monitors\n",
		get_monitor, set_monitor, put_monitor);
	printf ("%d; %d; %d # hgap height width\n",
		hgap, height, width);
	printf ("%d; %d; %d # chordtransp updown bps\n",
		chordtransp, up_down_border, piecev.p_bps);
	printf ("%d, %d, %d, %d # clef key time lead sigs\n",
		clefsig, keysig, timesig, leadsig);
	printf ("%d, %d, %d, %d # natmode testing slopeform tieform\n",
		nat_mode, testing, beamslope, tieform);
    }
}

getaccid (p) {			/* get currently set n_accid for pitch */
    return baraccid[p % 7];
}

setaccid (p, a) char    a;	/* set current bar accid for p to a */
{
    if (verbose && baraccid[p % 7] == a)
	iowarn ("n_accid already set", 0, 0);
    baraccid[p % 7] = a;
}

addaccid (p, c) {		/* add n_accid 'c' to pitch 'p' */
    int     i;
    if (c == ' ')
	i = p;
    else
	if (c == '+')
	    i = p + 7;
	else
	    if (c == '-')
		i = p - 7;
	    else {
		ioerror ("Invalid n_accid \"%c\" (ASCII %o)", c, c);
		return - 1;
	    }
    if (i < 0)
	i += 12;
    if (i >= 21)
	i -= 12;
    return i;
}

clearaccid () {			/* clear currently set n_accids */
    int     i;
    for (i = 0; i < 7; i++)
	baraccid[i] = ' ';
}

#ifdef junk
getclef () {
    char    c = nextvischar ();
    int     stff = partv[part].pt_end_stave;
    fprintf (stderr, "setclef bar %d staff %d clef \"%c\"\n", bar, stff, c);
    clef_now = clefs_now[stff] = barv[bar].b_clef[stff] = c;
    return;
}
#endif

gettimesig () {
    tsig_n_now = barv[bar].b_n_tsig = readint ();
    tsig_d_now = barv[bar].b_d_tsig = readint ();
    piecev.p_beat_length = SBL / tsig_d_now;
    piecev.p_bar_length = piecev.p_beat_length * tsig_n_now;
    if (SBL % tsig_d_now)
	ioerror ("Can't divide bar-length by %d", tsig_d_now, 0);
}

getbarno () {			/* get number for repeated bars */
    int     m,
            n,
            r,
            pt;
    char    c = nextvischar ();
    char    s[20];
    char   *p = s;
    if (c >= '0' && c <= '9') {	/* straight integer */
	backup ();
	n = readint ();
    }
    else
	if (c == '-') {		/* relative to current bar */
	    n = bar - readint ();
	}
	else
	    if (c == OTEXTSYM || c == UTEXTSYM || c == NTEXTSYM) {
		*p++ = c;
		while ((*p = nextchar ()) != c)
		    p++;
		*p++ = c;
		*p = 0;
		n = -1;
		for (pt = 0; pt < n_parts; pt++)
		    for (m = bar - 1; m >= 0 && n < 0; m--) {
			for (r = bar_first_note[m][pt]; r < bar_last_note[m][pt]; r++) {
			    if (strncmp (s, notev[r].n_tnote, strlen (s)) == 0)
				n = m;
			}
		    }
		if (n == -1) {
		    ioerror ("Can't find bar containing %s", s, 0);
		    n = 0;
		}
		c = nextvischar ();
		if (c == '+')
		    n += readint ();
		else
		    if (c == '-')
			n -= readint ();
		    else
			backup ();
	    }
	    else {		/* else not UTEXTSYM or OTEXTSYM error */
		ioerror ("Can't find bar number", 0, 0);
		n = 0;
	    }
    return n;
}

checklength () {
    if (hdsq && hdsq != piecev.p_bar_length/* length musically */
	    && reset && reset != piecev.p_bars
				/* exclude first and last bars */
	    && barv[bar].b_end_type == 0 && barv[bar - 1].b_end_type == 0
				/* and special bars */
	    && within_ms) {
	ioerror ("Incorrect bar length hdsq %d (should be %d)",
		hdsq, piecev.p_bar_length);
    }
    hdsq = 0;
}
