#include	<math.h>
#include	"misc.h"
#include	"slug.h"
#include	"range.h"

void sprange::reheight(int *cv, int *mv)
{
	if (*cv != *mv)
		ERROR "slug %d: an imbedded SP, line %d\n",
			first->serialno(), first->lineno() WARNING;
	*cv += dv;
	*mv = max(*mv, *cv);
}

void sprange::rerawht(int *cv, int *mv)
{
	*cv += rawht();
	*mv = max(*mv, *cv);
}

void nestrange::restore()
{
	subrange->restoreall();
}

void stream::freeall()	// not a destructor;  called explicitly
{
	strblk *p, *q;
	for (p = first; p; p = q) {
		q = p->next;
		delete p;
	}
	first = last = curr = 0;
}

void stream::dump()
{
	for (stream s = *this; s.more(); s.advance())
		s.current()->dump();
}

void stream::rdump()
{
	for (stream s = *this; s.more(); s.advance())
		s.current()->rdump();
}

int stream::restoreall()
{
	for (stream s = *this; s.more(); s.advance())
		s.current()->restore();
	return measure(this);
}

range *stream::append(range *r)
{
	if (last == 0)
		curr = first = last = new strblk;
	else {
		last->next = new strblk;
		last = last->next;
		if (curr == 0)
			curr = last;
	}
	last->next = 0;
	return last->rp = r;
}

void stream::split()	// duplicate current() range
{
	strblk *s2 = new strblk;
	range *r2 = curr->rp->clone();
	s2->rp = r2;
	s2->next = curr->next;
	if (last == curr)
		last = s2;
	curr->next = s2;
	curr->rp->killkids();		// children only in the 2nd one
	// r2->crosslink(r1);
}

int stream::height()
{
	int h;
	stream s = *this;
	for (h = 0; s.more(); s.advance())
		h += s.current()->height();
	return h;
}

int stream::rawht()
{
	int h;
	stream s = *this;
	for (h = 0; s.more(); s.advance())
		h += s.current()->rawht();
	return h;
}

int measure(stream *sp)		// record high-water mark of stream
{				// sets nested stream heights
	stream s = *sp;
	int curv, maxv;
	for (maxv = curv = 0; s.more(); s.advance())
		s.current()->reheight(&curv, &maxv);
	return maxv;
}

int rawmeasure(stream *sp)
{
	stream s = *sp;
	int curv, maxv;
	for (maxv = curv = 0; s.more(); s.advance())
		s.current()->rerawht(&curv, &maxv);
	return maxv;
}

void nestrange::rdump()
{
	dump();
	if (subrange)
		subrange->rdump();
}

void nestrange::killkids()
{
	subrange = new stream;
}

int nestrange::print(int curv, int col)
{
	int ocurv = curv;
	first->slugout(col);
	for (stream s = *subrange; s.more(); s.advance())
		curv = s.current()->print(curv, col);
	return ocurv + height();
}

#define macroclone(rangetype) range *rangetype::clone() {\
	rangetype *t = new rangetype;\
	*t = *this;\
	return t; }

macroclone(usrange);
macroclone(ufrange);
macroclone(bfrange);

#undef macroclone

#define macropickgoal(rangetype) void rangetype::pickgoal(int acv, double scale) {\
	if (scale > 1) {\
		goalV = (int)(scale*goalV);\
		goal2 = (int)(scale*goal2);\
	}\
	if (abs(acv - goalV) > abs(acv-goal2))\
		goalV = goal2; }

macropickgoal(ufrange)
macropickgoal(bfrange)

#undef macropickgoal

range *generator::next()
{
	range *r;
	if (child) {
		if ((r = child->next()) != 0)
			return r;
		delete child;
		child = 0;
	}
	if (!s.more())
		return 0;
	r = s.current();
	if (r->isnested())
		child = new generator(r->children());
	s.advance();
	return r;
}

range *queue::enqueue(range *r)
{
	if (dbg & 8)
		printf("#entering queue::enqueue()\n");
	check("queue::enqueue");
	if (!last || last->rp->serialno() < r->serialno())	// common case
		return append(r);
	if (dbg & 8)
		printf("#queue::enqueue() pushing back\n");
	newguy = new strblk;
	newguy->rp = r;
	if (r->serialno() < first->rp->serialno()) {
		newguy->next = first;
		curr = first = newguy;
		return newguy->rp;
	}
	if (dbg & 8)
		printf("#queue::enqueue() searching down queue\n");
	for (curr = first;
		next() && next()->serialno() < r->serialno();
		curr = curr->next)
		;
	newguy->next = curr->next;
	curr->next = newguy;
	curr = first;			// restore important queue condition
	return newguy->rp;
}

range *queue::dequeue()
{
	if (dbg & 8)
		printf("#entering queue::dequeue()\n");
	check("queue::dequeue");
	curr = first->next;
	range *retval = first->rp;
	delete first;
	first = curr;
	if (!curr)
		last = 0;
	return retval;
}

// ================================================================================

//	functions that munge the troff output stored in slugs[]

// ================================================================================

static void doprefix(FILE *fp) // copy 1st "x" commands to output
{
	int c;

	while ((c = getc(fp)) != EOF) {
		if (c != 'x') {
			ungetc(c, fp);
			break;
		}
		putchar(c);
		do {
			putchar(c = getc(fp));
		} while (c != '\n');
		linenum++;
	}
//	printf("x font 1 R\n");	// horrible kludge: ensure a font for first f1 command 
}

#define	DELTASLUGS	15000

static slug	*slugs = 0;
static int	nslugs = 0;	// slugs has nslugs slots
static slug	*slugp = 0;	// next free slug in slugs

static void readslugs(FILE *fp)
{
	if ((slugs = (slug *) malloc((nslugs = DELTASLUGS)*sizeof(slug))) == NULL)
		ERROR "no room for %d-slug array\n", nslugs FATAL;
	slugp = slugs;
	for (slugp = slugs; ; slugp++) {
		if (slugp >= slugs+nslugs-2) {
			int where = slugp - slugs;
			if ((slugs = (slug *) realloc((char *) slugs, (nslugs += DELTASLUGS)*sizeof(slug))) == NULL)
				ERROR "no room for %d slugs\n", nslugs FATAL;
			ERROR "now slug array can hold %d slugs\n", nslugs WARNING;
			slugp = slugs + where;
		}
		*slugp = getslug(fp);
		if (slugp->type == EOF)
			break;
	}
	*++slugp = eofslug();
	printf("# %d slugs\n", slugp-slugs);
}

static slug *findend(slug *sp)
{
	slug *p;
	for (p = sp; p->type == sp->type; p++)	// skip runs
		;				// espec UF UF UF 
	for ( ; p < slugp; p++)
		switch (p->type) {
		case US:
		case UF:
		case BF:
		case PT:
		case BT:
			p = findend(p);
			break;
		case END:
			return p;
		}
	ERROR "walked past EOF in findend looking for %d (%s), line %d\n",
		sp->type, sp->typename(), sp->lineno() FATAL;
	return sp;
}

static int markp(int i, int n, int parm)
{	// should VBOX i of n be marked to brevent breaking after it?
	if (i >= n-1)
		return 0;
	return i <= parm-2 || i >= n-parm;
}

static void markbreak(slug *p)
{
	// Mark impermissible breakpoints in BS's.
	// The parm field of a VBOX is >0 if we shouldn't break after it.
	int parm = 0;		// how many lines must stay on page
	int goahead = 1;	// true until we see the next BS
	int nowmark = 0;	// true when we should be marking
	int n = 0;
	while (p->type == BS)
		parm = p++->parm;	// latest BS parm applies
	slug *op = p;
	while (goahead) {
		switch (p->type) {
		case VBOX:		// count VBOXes so second pass knows
			if (p->dv > 0)	// knows how far to end of BS
				n++;
			break;
		case US:		// mark around EQ/EN, etc.
			nowmark = 1;
			p = findend(p);
			break;
		case UF:		// but not around floats, PTs, and BTs
		case BF:
		case PT:
		case BT:
			p = findend(p);
			break;
		case SP:		// naked SP:  probable macro botch
			nowmark = 1;	// mark around it anyhow
			break;
		case BS:		// beginning of next paragraph
		case END:		// probable macro botch
		case EOF:
			goahead = 0;	// stop work after marking
			nowmark = 1;
		default:
			break;
		}
		p++;
		if (nowmark) {
			int i = 0;	// VBOX counter for second pass
			while (op < p) {
				switch (op->type) {
				case VBOX:
					if (op->dv > 0)
						op->parm = markp(i, n, parm);
					i++;
					break;
				case US:	// caused second pass to begin
				case SP:
				case BS:
				case END:
				case EOF:
					op = p;
					break;
				case UF:	// skip on this pass too
				case BF:
				case PT:
				case BT:
					op = findend(op);
					break;
				default:
					break;
				}
			op++;
			}
			if (i != n)
				ERROR "markbreak failed : i %d n %d\n",
					i, n WARNING;
			op = p;
			nowmark = n = 0;
		}
	}
}

static void fixslugs()		// adjust bases and dv's, set parameters, etc.
{
	slug *p, *prevV = 0;
	for (p = slugs; p < slugp; p++) {
		if (p->type == VBOX) {
			prevV = p;
			continue;
		}
		if (p->base != 0) {
			ERROR "%s slug (type %d) has base = %d, line %d\n",
				p->typename(), p->type, p->base, p->lineno() WARNING;
		}
		if ((p->type == SP) || (p->type == NE))
			continue;
		if (p->type == PAGE)
			prevV = 0;
		if (p->dv != 0)
			if (prevV) {
				prevV->base = max(prevV->base, p->dv);
				p->dv = 0;
			} else {
				ERROR "%s slug (type %d) has dv = %d, line %d\n",
					p->typename(), p->type, p->dv, p->lineno() WARNING;
			}
	}
	prevV = 0;
	int firstNP = 0, firstFO = 0, firstPL = 0;
	for (p = slugs; p < slugp; p++) {
		switch (p->type) {
		// adjust the dv in a sequence of VBOXes
		// by subtracting from each the base of the preceding VBOX
		case VBOX:
			if (prevV)
				p->dv -= prevV->base;
			prevV = p;
			break;
		case SP:
			p->dv = max(p->dv, 0);
			break;
		case PAGE:
			p->neutralize();
			prevV = 0;
			break;
		// record only first "declarations" of Page Top and bottom (FO);
		case PARM:
			switch (p->parm) {
			case NP:
				if (firstNP++ == 0)
					pagetop = p->parm2;
				p->neutralize();
				break;
			case FO:
				if (firstFO++ == 0)
					pagebot = p->parm2;
				p->neutralize();
				break;
			case PL:
				if (firstPL++ == 0)
					physbot = p->parm2;
				p->neutralize();
				break;
			}
			break;
		// things that begin groups; not US, which should nest properly
		case UF:
		case BF:
			while ((p+1)->type == p->type) {
							// join adjacent identical
				(p+1)->parm2 = p->parm;	// parm is latest
							// parm2 is previous
				p->neutralize();	// so it's not seen later
				p++;
			}
			break;
		// none of the above
		case US:
		case PT:
		case BT:
		case BS:
		case END:
		case TM:
		case COORD:
		case NE:
		case MC:
		case CMD:
		case EOF:
			break;
		default:
			ERROR "Unknown slug type %d in fixslugs, line %d\n",
				p->type, p->lineno() WARNING;
			break;
		}
	}
	int pagesize = pagebot - pagetop;
	if (pagesize == 0)
		ERROR "Page dimensions not declared\n" FATAL;
	if (physbot == 0)
		physbot = pagebot + pagetop;
	printf("# page top %d bot %d size %d physbot %d\n",
		pagetop, pagebot, pagesize, physbot);
	for (p = slugs; p < slugp; p++) {
		switch (p->type) {
		// normalize float parameters
		case BF:
		case UF:
					// primary goal
			p->parm = max(min(p->parm-pagetop, pagesize), 0);
					// secondary goal
			p->parm2 = max(min(p->parm2-pagetop, pagesize), 0);
			break;
		// normalize need parameters
		case NE:
			p->dv = max( min(p->dv, pagesize), 0);
			break;
		// mark permissible breaks
		case BS:
			markbreak(p);
			break;
		}
		if (dbg & 1)
			p->dump();
	}
}

void checkout()
{
	for (slug *p = slugs; p < slugp; p++)
		switch (p->type) {
		case PT:
		case BT:
			p = findend(p);
			break;
		case SP:
		case VBOX:
			if (p->seen != 1)
				ERROR "%s slug %d seen %d times\n",
					p->typename(), p->serialno(),
					p->seen WARNING;
			break;
		}
}

eofrange *lastrange;
stream	ptlist, btlist;

static slug *makeranges(slug *p, stream *s, int level)
{
	stream *t;

	for ( ; p < slugp; p++)
		switch (p->type) {
		case VBOX:
			s->append(new vboxrange(p));
			break;
		case SP:
			s->append(new sprange(p));
			break;
		case BS:
			s->append(new bsrange(p));
			break;
		case US:
			s->append(new usrange(p, t = new stream));
			p = makeranges(p+1, t, level+1);
			break;
		case BF:
			s->append(new bfrange(p, t = new stream));
			p = makeranges(p+1, t, level+1);
			break;
		case UF:
			s->append(new ufrange(p, t = new stream));
			p = makeranges(p+1, t, level+1);
			break;
		case PT:
			ptlist.append(new ptrange(p, t = new stream));
			p = makeranges(p+1, t, level+1);
			break;
		case BT:
			btlist.append(new btrange(p, t = new stream));
			p = makeranges(p+1, t, level+1);
			break;
		case END:
			s->append(new endrange(p));
			return p;
		case TM:
			s->append(new tmrange(p));
			break;
		case COORD:
			s->append(new coordrange(p));
			break;
		case NE:
			if (level) {
				ERROR "Nested NE commands are ignored, line %d\n",
					p->lineno() WARNING;
				p->dv = 0;
			}
			s->append(new nerange(p));
			break;
		case MC:
			s->append(new mcrange(p));
			break;
		case CMD:
			if (level)
				ERROR "Nested command ignored, line %d\n",
					p->lineno() WARNING;
			s->append(new cmdrange(p));
			break;
		case PARM:
			if (level)
				ERROR "Nested parameter ignored, line %d\n",
					p->lineno() WARNING;
			s->append(new parmrange(p));
			break;
		case EOF:
			lastrange = new eofrange(p);
			return 0;
		}
	return p;
}

static queue text;			// unexamined input ranges; the real data

void startup(FILE *fp)
{
	doprefix(fp);			// peel off 'x' commands
	readslugs(fp);			// read everything into slugs[]
	fixslugs();			// measure parameters and clean up
	makeranges(slugs, &text, 0);	// add range superstructure
	measure(&text);		// heights of nested things
	rawmeasure(&text);
	while (text.more()) {
		range *r = text.dequeue();
		if (dbg & 2)
			r->dump();
		r->enqueue();
	}
}
