#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;		// 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();
	}
}
