#include "post_mus.h"

extern char *splines;

setmax (i, j) int  *i;		/* set i to max of i, j */
{
    if (*i < j) {
	*i = j;
    }
}

puttie (stave, staff) {		/* put ties within this staff */
    struct staves  *stavep = stavev + stave;
    int     s_first_bar = stavep -> s_first_bar,
            s_last_bar = stavep -> s_last_bar;
    struct bars *barp = barv + s_first_bar;
    int     b_first_note = barp -> b_first_note;
    int     b_last_note = barv[stavev[stave].s_last_bar - 1].b_last_note;
    struct notes   *notep = notev + b_first_note;
    int     startnote[10],
            startbar[10],
            height[10],
            startsequ[10];
    int     depth = 0,
            maxht = 0,
            bar,
            note = b_first_note;
    int     i,
            j;

    for (bar = s_first_bar; bar < s_last_bar; bar++, barp++) {
	b_first_note = barp -> b_first_note;
	b_last_note = barp -> b_last_note;
	for (note = b_first_note, notep = notev + b_first_note;
		note < b_last_note;
		note++, notep++) {
	    if (notep -> n_staff != staff)
		continue;
/* some ties end here */
	    if (put_monitor && notep -> n_tie_end)
		fprintf (stderr, "Tieends b %d n %d %d\n",
			bar, note - barp -> b_first_note + 1, notep -> n_tie_end);
	    for (i = 0; i < notep -> n_tie_end; i++) {
		if (depth > 0) {/* full tie */
		    depth--;
		    for (j = depth - 1; j >= 0; j--)
			setmax (height + j, height[j + 1] + TIEHT);
		    put1tie (startnote[depth], startbar[depth],
			    note, bar, height[depth], startsequ[depth], i, 0);
		}
		else {		/* tie from previous stave */
		    maxht++;
		    put1tie (-1, -1, note, bar, maxht, 0, i, -1);
		}
	    }			/* end for all ties ending here */
/* check for hight notes */
	    if (depth)
		setmax (height + depth - 1, notep -> n_maxy);
/* note start of ties */
	    if (put_monitor && notep -> n_tie_start)
		fprintf (stderr, "Tiestarts b %d n %d %d\n",
			bar, note - barp -> b_note_start + 1, notep -> n_tie_start);
	    for (i = 0; i < notep -> n_tie_start; i++) {
		startnote[depth] = note;
		startbar[depth] = bar;
		startsequ[depth] = i;
		height[depth] = HALFSTAVE + TIEHT;
		setmax (height + depth, notep -> n_maxy);
		for (j = depth - 1; j >= 0; j--)
		    setmax (height + j, height[j + 1] + TIEHT);
		setmax (&maxht, height[0]);
		depth++;
	    }			/* end for all ties starting here */
	}			/* end for all notes in bar */
    }				/* for all bars on stave */
 /* some unfinished ties */
    for (i = 0; i < depth; i++) {
	put1tie (startnote[i], startbar[i],
		-1, -1, maxht - i, startsequ[i], i, 1);
    }
}

put1tie (fromnote, frombar, tonote, tobar, ht, sn, fn, type) {
/* full tie if type == 0, r.h. end if type == -1, l.h. start if +1 */
/* sn = start number, fn = finish number */
/* [fromx,fromy] = start co-ords, [tox,toy] = end co-ords */
    struct bars *fbar = barv + frombar, /* fbar = "from bar" */
               *tbar = barv + tobar;
    struct notes   *fnote = notev + fromnote, /* fnote = "from note" */
                   *tnote = notev + tonote;
    int     fromx =
            frombar >= 0 ?
            fbar -> b_x_wrt_staff +
            fnote -> n_width - fnote -> n_dots * atom[DOT].a_width +
            fnote -> n_x_wrt_bar + 2 * sn + 1 :
            barv[stavev[stave].s_first_bar].b_note_start;
    int     tox =
            tobar >= 0 ?
            tbar -> b_x_wrt_staff + tnote -> n_head_x + tnote -> n_x_wrt_bar - 2 * fn - 1 :
            width_now;
    int	    close = tonote - fromnote < 3;
    int	    tieup = 1; /*fromnote >= 0 && tonote >= 0 ?
		    (fnote -> stickup + tnote -> stickup) <= 0 :
		fromnote >= 0 ? fnote -> stickup <= 0 :
		    tnote -> stickup <= 0; */
    int     yoff = stavev[stave].s_y_wrt_page + staffv[stave][staff].s_y_wrt_stave;
    int	    yodd = tieup ?
		5 :
		-5;
    int     full = tieup ? FULLSTAVE : -FULLSTAVE;
    int	    fromy = yoff +
	      (frombar >= 0 ?
		fnote -> n_y_wrt_staff +
		( fnote->stickup>0?atom[STICK].height:yodd) :
		full );
    int	    toy = yoff +
	      (tobar >= 0 ?
		tnote -> n_y_wrt_staff +
		( tnote->stickup>0?atom[STICK].height:yodd) :
		full );
    int     maxy = toy > fromy ? toy : fromy;
    int     miny = toy < fromy ? toy : fromy;
    int     h = tieup ? maxy + 6 : miny - 6;
    int     h1 = h + (tieup ? -3 : 3);
    int     fromh = tieup ? h - fromy : fromy - h;
    int     toh = tieup ? h - toy : toy - h;
    int     toth = fromh + toh;
    int     x1,
            x2;
    int     dx;

    if (type) {
	fprintf (stderr, "Non standard tie type %d bar %d note %d ignored\n",
		type, bar, beat - fbar -> b_first_note + 1);
	return;
    }

    if (fnote -> stickup > 0 && tnote -> stickup < 0)
	fprintf (stderr, "Bar %d note %d tie problem\n", bar, beat);
    if (tox - fromx < 12) {
	dx = (12 - tox + fromx) / 2;
	fromx -= dx;
	tox += dx;
    }
    dx = tox - fromx;
    x1 = fromx + dx * fromh / (4 * toth);
    x2 = tox - dx * toh / (4 * toth);
    if (fromy > toy) {
	if (put_monitor == 9)
	    fprintf (stderr, "Adjust desc tie from (%d,%d) ",
		    fromy, toy);
	if (tieup)
	    toy += (fromy - toy) / 2;
	else
	    fromy -= (fromy - toy) / 2;
    }
    if (fromy < toy) {
	if (put_monitor == 9)
	    fprintf (stderr, "Adjust asc tie from (%d,%d) ",
		    fromy, toy);
	if (tieup)
	    fromy += (toy - fromy) / 2;
	else
	    toy -= (toy - fromy) / 2;
    }

    if (put_monitor == 9) {
	fprintf (stderr, "Tie [(b%d,n%d),(b%d,n%d)] [(x%d,y%d),(x%d,y%d)]type %d\n",
		frombar, fromnote - barv[frombar].b_first_note + 1,
		tobar, tonote - barv[tobar].b_first_note + 1,
		fromx, fromy, tox, toy,
		type);
    }

 /* ordinary tie */
    if (type == 0) {
	h *= 2;
	for (h1 = 0; h1 < 2; h1++) {
	    if (put_monitor == 9)
		fprintf (stderr,
			"%s from %d,%d then right %d up %3.1f \
		then right %d then right %d down %3.1f\n",
			splines,/* Chelgraph won't take splines */
			fromx, fromy,/* start point */
			x1 - fromx, (h - 2 * fromy) / 2.0,
				/* diagonal right to start */
			x2 - x1,/* horizontal right */
			tox - x2, (h - 2 * toy) / 2.0);
				/* diagonal right to end */
	    fprintf (stdout,
		    "%s from %d,%d then right %d up %3.1f \
then right %d then right %d down %3.1f\n",
		    splines,	/* Chelgraph won't take splines */
		    fromx, fromy,/* start point */
		    x1 - fromx, (h - 2 * fromy) / 2.0,
				/* diagonal right to start */
		    x2 - x1,	/* horizontal right */
		    tox - x2, (h - 2 * toy) / 2.0);
				/* diagonal right to end */
	    h += tieup ? -1 : 1;
	    fprintf (stdout,
		    "%s from %d,%d then left %d up %3.1f \
then left %d then left %d down %3.1f;\n",
		    splines,
		    tox, toy,	/* start point */
		    tox - x2, (h - 2 * toy) / 2.0,
				/* diagonal right to start */
		    x2 - x1,	/* horizontal right */
		    x1 - fromx, (h - 2 * fromy) / 2.0);
				/* diagonal right to end */
	    h += tieup ? -1 : 1;
	}
    }
    else
	if (type < 0) {		/* end of tie from start of stave */
	    dx = (fromy - toy) / 2;
	    fprintf (stdout,
		    "%s from %d,%d then right %d then right %d down %d\n",
		    splines,
		    fromx, fromy,/* start at left edge */
		    tox - fromx - dx,/* right */
		    fromy - toy, fromy - toy);
	    fprintf (stderr,
		    "%s from %d,%d then right %d then right %d down %d\n",
		    splines,
		    fromx, fromy,/* start at left edge */
		    tox - fromx - dx,/* right */
		    dx, fromy - toy);
	}
	else {			/* start of tie to end of stave */
	    dx = (toy - fromy) / 2;
	    fprintf (stdout,
		    "%s from %d,%d then right %d up %d then right %d\n",
		    splines,
		    fromx, fromy,
		    dx, toy - fromy,/* right */
		    tox - fromx - dx);/* to right edge */
	    fprintf (stderr,
		    "%s from %d,%d then right %d up %d then right %d\n",
		    splines,
		    fromx, fromy,
		    dx, toy - fromy,/* right */
		    tox - fromx - dx);/* to right edge */
	}
}
