/*
 *  This file is part of jcabc2ps,
 *  Copyright (C) 1996,1997,1998  Michael Methfessel
 *  See file jcabc2ps.c for details.
 */

#include "jcabc2ps.h"
#include "buffer.h"
#include "pssubs.h"
#include "subs.h"
#include "util.h"

/*  subroutines to handle output buffer  */

/* ----- a2b: appends string to output buffer ----- */
void a2b (t)
	char *t;
{
	int l,i;

	l=strlen(t);
	/*  fprintf(stderr,"Append %d <%s>\n", l, t); */

	if (nbuf+l>tunebuffsz) {
		fprintf(stderr,"+++ a2b: buffer full, tunebuffsz=%d\n", tunebuffsz);
		exit (1);
	}

	for (i=0;i<l;i++) tunebuf[nbuf+i]=t[i];
	nbuf += l;

}


/* ----- bskip(h): 
*   translate down by h points in output buffer 
* The extra file,line args are debug hooks because we've  had  some  problems
* with huge, random-looking values for h.  So we wrap this function in a call
* of Bskip(h), which appends the file name and line number to  the  arg  list
* and calls this routine.
*/
void bskip(float h, char *file, int line)
{	char *F = "bskip";
	if (h > 1000.0) {V2 "%s: ### h=%.2f [%s,%d]\n",F,h,file,line V; h=0.0;}
	if ((h*h)>0.0001) {
		PUT1("0 %.2f T\n", -h)
		V5 "%s: bposy=%.2f h=%.2f\n",F,bposy,h V;
		bposy -= h;
		V5 "%s: bposy=%.2f\n",F,bposy V;
		if (bposy < -1000.0) 
			V2 "%s: ### bposy=%.2f [%s,%d]\n",F,bposy,file,line V;
	}
}

/* ----- init_pdims: initialize page dimensions ----- */
void init_pdims ()
{
	if (in_page) return;
	posx=cfmt.leftmargin;
	posy=cfmt.pageheight-cfmt.topmargin;

}

/* ----- clear_buffer ------- */
void clear_buffer ()
{	char *F = "clear_buffer";
	nbuf   = 0;
	bposy  = 0.0;
	ln_num = 0;
	V5 "%s: nbuf=%d bposy=%.2f ln_num=%d.\n",F,nbuf,bposy,ln_num V;
}

/* ----- write_index_entry ------- */
void write_index_entry ()
{	char *F = "write_index_entry";
	char s[801];
	float w,dx1,dx2;

	if (!index_initialized) init_index_file ();


	V5 "%s: Write index entry: %5d  <%s>\n",F,pagenum, info.title V;

	/* spacing determined here */
	index_posy = index_posy-1.2*cfmt.indexfont.size;

	V2 "%s: index_posy=%.2f cfmt.indexfont.size=%.2f cfmt.botmargin=%.2f\n",F,
			index_posy,  cfmt.indexfont.size,  cfmt.botmargin V;
	if (index_posy - cfmt.indexfont.size < cfmt.botmargin) {
		V2 "%s: New page.\n",F V;
		close_index_page (findex);
		init_index_page (findex);
	}

	dx1 = 1.8*cfmt.indexfont.size;
	dx2 = dx1+cfmt.indexfont.size;


	tex_str (info.title,s,&w);
	if (strlen(s)==0) strcpy (s, "No title");
	fprintf(findex, "%.2f %.2f M (%d) lshow\n", index_posx+dx1, index_posy, pagenum);
	fprintf(findex, "%.2f %.2f M (%s) S\n", index_posx+dx2, index_posy, s);

	if (strlen(info.rhyth) || strlen(info.orig)) {
		fprintf (findex, "(  (");
		if (strlen(info.rhyth)) fprintf (findex, "%s", info.rhyth);
		if (strlen(info.rhyth) && strlen(info.orig))
			fprintf (findex, ", ");
		if (strlen(info.orig)) fprintf (findex, "%s", info.orig);
		fprintf (findex, ")) S\n");
	}


	if (strlen(info.comp[0])) fprintf (findex, "(   - %s) S\n", info.comp[0]);

}




/* ----- write_buffer: write buffer contents, break at full pages ---- */
void write_buffer (fp)
FILE *fp;
{	char *F = "write_buffer";
	int i,l,b1,b2,nb;
	float p1=0.0,dp=0.0;
//
	if (nbuf==0) return; 
	writenum++; 
	if ((writenum==1) && make_index) write_index_entry(); 
	nb=0;
	for (l=0;l<ln_num;l++) {
		b1=0;
		p1=0;
		if (l>0) {
			b1 = ln_buf[l-1];
			p1 = ln_pos[l-1];
			if (b1 < -1000.0 || p1 < -1000.0)
				V1 "%s: p1=ln_pos[%d]=%.2f b1=ln_buf[%d]=%i\n",F,l-1,p1,l-1,b1 V;
		}
		b2 = ln_buf[l];
		dp = ln_pos[l] - p1;
		if (b2 < -1000.0 || dp < -1000.0)
			V1 "%s: b2=ln_pos[%d]=%i dp=ln_buf[%d]-p1=%.2f\n",F,l,b2,l,dp V;
		if ((posy + dp < cfmt.botmargin) && (!epsf)) {
		//	if (vb < 2) {vb = 2;}
			V3 "%s: Call write_pagebreak because posy=%.2f + dp=%.2f < cfmt.botmargin=%.2f epsf=%d [b1=%d b2=%d]\n",F,
				posy,dp,cfmt.botmargin,epsf,b1,b2 V;
			write_pagebreak(fp);
			V3 "%s: write_pagebreak(fp) done.\n",F V;
		}
		for (i=b1;i<b2;i++) putc(tunebuf[i],fp);
		posy=posy+dp;
		nb=ln_buf[l];
	}
	if (nb<nbuf) {
		for (i=nb;i<nbuf;i++) putc(tunebuf[i],fp);
	}
	clear_buffer();
	return;
}

/* ----- buffer_eob: handle completed block in buffer ------- */
/* if the added stuff does not fit on current page, write it out
	 after page break and change buffer handling mode to pass though */
void buffer_eob (fp)
FILE *fp;
{	char *F = "buffer_eob";
	int do_break;

	if (ln_num >= BUFFLN)
		rx("max number off buffer lines exceeded"," -- check BUFFLN");

	ln_buf[ln_num] = nbuf ; if (nbuf  < -1000.0) V1 "%s: ln_buf[%d]=%i=nbuf \n",F,ln_num,ln_buf[ln_num] V;
	ln_pos[ln_num] = bposy; if (bposy < -1000.0) V1 "%s: ln_pos[%d]=%.2f=bposy\n",F,ln_num,ln_pos[ln_num] V;
	ln_num++;
	ln_pos[ln_num] = 0.0;
	V5 "%s: ln_pos[%d]=%.2f\n",F,ln_num,ln_pos[ln_num] V;

	if (!use_buffer) {
		write_buffer (fp);
		return;
	}

	do_break=0;
	if (posy+bposy<cfmt.botmargin) do_break=1;
	if (cfmt.oneperpage) do_break=1;

	if (do_break && (!epsf)) {
		if (tunenum != 1 ) {
			V3 "%s: Call write_pagebreak because tunenum=%d.\n",F,tunenum V;
			write_pagebreak(fp);
		}
		write_buffer (fp);
		use_buffer=0;
	}

	return;
}

/* ----- check_buffer: dump buffer if less than nb bytes avilable --- */
void check_buffer (fp, nb)
FILE *fp;
int nb;
{
	char mm[81];

	if (nbuf+nb>tunebuffsz) {
		sprintf (mm, "tunebuffsz=%d exceeded at line %d",tunebuffsz,ln_num);
		wng("possibly bad page breaks, ", mm);
		write_buffer (fp);
		use_buffer=0;
	}
}


