const int	NOGOAL = -1;

class stream;

enum primeflush { NO, YES, EXPECTED, UNEXPECTED };	// mergestream::prime()

// Ranges do two things.  They interpose a layer between slugs and the rest
// of the program; this is important because of the grossness of the slug
// data structure (made necessary by its origins in troff output).  Ranges also
// group together other ranges into meaningful chunks like unbreakable stream
// objects, floatable objects, and page headers and footers.
// Member function height() returns a range's height as of the latest composition.
// Member function rawht() returns the range's original height in the input.
class range {
  protected:
	slug	*first;		// earliest slug in range
	int	accumV;		// accumulated V to this point
  public:
	range()		{ first = 0; accumV = 0; }
	range(slug *p)	{ first = p; accumV = 0; }
	char	*headstr()		{
		return first ? first->headstr() : (char*)""; }
	char	*typename()		{ return first->typename(); }
	int	serialno()		{ return first->serialno(); }
	int	lineno()		{ return first->lineno(); }
	virtual void	dump()		{ first->dump(); }
	virtual void	rdump()		{ dump(); }
	virtual int	print(int cv, int col)	{
		first->slugout(col); return cv; }
	virtual int	floatable()	{ return 0; }
	virtual int	brkafter()	{ return 1; }
	virtual int	isnested()	{ return 0; }
	virtual int	issp()		{ return 0; }
	virtual int	isvbox()	{ return 0; }
	virtual int	isneed()	{ return 0; }
	virtual int	iscmd()		{ return 0; }
	virtual int	cmdtype()	{ return -1; }
	virtual int	isparm()	{ return 0; }
	virtual int	parmtype()	{ return -1; }
	virtual int	parm()		{ return -1; }
	virtual int	breakable()	{ return 0; }
	virtual int	forceflush()	{ return UNEXPECTED; }
	virtual int	pn()		{ return 0; }
	virtual stream	*children()	{ return 0; }	// see page::peeloff()
	virtual void	killkids()	{ }
	virtual void	enqueue(int = 0);
	virtual int	height()	{ return 0; }
	virtual int	rawht()		{ return 0; }
	virtual int	needht()	{ return 0; }
	virtual void	reheight(int *, int *)	{ }
	virtual void	rerawht(int *, int *)	{ }
	virtual void	setheight(int) { }
	virtual void	restore()	{ }		// goals of floatables
	virtual int	goal()		{ return NOGOAL; }
	int		accum()		{ return accumV; }
	void		setaccum(int n)	{ accumV = n; }
	virtual	void	setgoal(int)	{ }
	virtual void	pickgoal(int, double)	{ }
	virtual int	numcol()	{ return first->numcol(); }
	virtual int	issentinel()	{ return 0; }
	virtual range	*clone()	{ return 0; }
	virtual int	breaking()	{ return 0; }
	virtual void	setbreaking()	{ }
};

class vboxrange : public range {
	int	dv;		// inherited from slug
	int	base;		// inherited from slug
	int	brk;		// 0 => ok to break after, 1 => no break 
  public:
	vboxrange(slug *p) : range(p) { dv = p->dv; base = p->base; brk = p->parm; }
	void	dump() {
		printf("#### VBOX brk? %d dv %d ht %d\n", brk, dv, dv+base); }
	int	print(int cv, int col) {
		printf("V%d\n", cv += dv); first->slugout(col); return cv+base; }
	int	brkafter()		{ return !brk; }
	int	isvbox()		{ return 1; }
	int	forceflush()		{ return NO; }
	int	height()		{ return dv + base; }
	int	rawht()			{ return first->dv + first->base; }
	void	reheight(int *cv, int *mv) {
		*cv += dv+base; *mv = max(*mv, *cv); }
	void	rerawht(int *cv, int *mv) {
		*cv += rawht(); *mv = max(*mv, *cv); }
};

class sprange : public range {
	int dv;
  public:
	sprange(slug *p) : range(p) { dv = first->dv; }
	void	dump() {
		printf("#### SP dv %d (originally %d)\n", dv, first->dv); }
	int	print(int cv, int col)	{
		first->slugout(col); return cv + dv; }
	int	issp()			{ return 1; }
	int	forceflush()		{ return YES; }
	int	height()		{ return dv; }
	int	rawht()			{ return first->dv; }
	void	reheight(int *, int *);
	void	rerawht(int *, int *);
	void	setheight(int n)	{ dv = n; }
};

class tmrange : public range {
  public:
	tmrange(slug *p) : range(p)	{ }
	int	forceflush()		{ return NO; }
	int	print(int cv, int col)	{ first->slugout(col); return cv; }
};

class coordrange : public range {
  public:
	coordrange(slug *p) : range(p)	{ }
	int	forceflush()		{ return NO; }
	int	print(int cv, int col)
		{ first->slugout(col); printf(" Y %d\n", cv); return cv; }
};

class nerange : public range {
  public:
	nerange(slug *p) : range(p)	{ }
	int	isneed()		{ return 1; }
	int	forceflush()		{ return YES; }
	int	needht()		{ return first->dv; }
};

class mcrange : public range {
  public:
	mcrange(slug *p) : range(p)	{ }
	int	forceflush()		{ return YES; }
};

class cmdrange : public range {
  public:
	cmdrange(slug *p) : range(p)	{ }
	int	iscmd()			{ return 1; }
	int	forceflush()		{ return YES; }
	int	cmdtype()		{ return first->parm; }
};

class parmrange : public range {
  public:
	parmrange(slug *p) : range(p)	{ }
	int	isparm()		{ return 1; }
	int	forceflush()		{ return YES; }
	int	parmtype()		{ return first->parm; }
	int	parm()			{ return first->parm2; }
};

class bsrange : public range {
  public:
	bsrange(slug *p) : range(p)	{ }
	int	forceflush()		{ return NO; }
	int	print(int cv, int col)	{ first->slugout(col); return cv; }
};

class endrange : public range {
  public:
	endrange(slug *p) : range(p)	{ }
	int	forceflush()		{ return UNEXPECTED; }
};

class eofrange : public range {
  public:
	eofrange(slug *p) : range(p)	{ }
	int	forceflush()		{ return UNEXPECTED; }
};

extern eofrange *lastrange;	// the EOF block (trailer, etc.) goes here

int measure(stream *);
int rawmeasure(stream *);

// A nestrange packages together a sequence of ranges, its subrange.
// Other parts of the program reach in and alter the dimensions of
// some of these ranges, so when the height of a range is requested
// it is computed completely afresh.
// (Note:  the alternative, of keeping around many copies of ranges
// with different dimensions, was abandoned because of the difficulty
// of ensuring that exactly one copy of each original range would be
// output.)
class nestrange : public range {
  protected:
	stream	*subrange;
	int isbreaking;
	int rawdv;
  public:
	nestrange() : range()	{ subrange = 0; isbreaking = 0; rawdv = -1; }
	nestrange(slug *p, stream *s) : range(p)
				{ subrange = s; isbreaking = 0; rawdv = -1; }
	void	rdump();
	virtual void restore();
	stream	*children()	{ return subrange; }
	void	killkids();
	int	height()	{ return measure(subrange); }
	int	rawht()		{ if (rawdv < 0 || isbreaking) rawdv = rawmeasure(subrange);
					return rawdv; }
	void	reheight(int *cv, int *mv) {
			*mv += measure(subrange); *cv = max(*mv, *cv); }
	void	rerawht(int *cv, int *mv) {
			*mv += rawht(); *cv = max(*mv, *cv); }
	int	isnested()	{ return 1; }
	int	forceflush()	{ return EXPECTED; }
	int	print(int cv, int col);
	int	breaking()	{ return isbreaking; }
	void	setbreaking()	{ isbreaking++; }
};

class usrange : public nestrange {
  public:
	usrange()	{ }
	usrange(slug *p, stream *s) : nestrange(p, s) {}
	void dump() { printf("#### US	dv %d\n", height()); }
	range	*clone();
};

class ufrange : public nestrange {
	int	goalV, goal2;
  public:
	ufrange()	{ }
	ufrange(slug *p, stream *s) : nestrange(p, s) {
		goalV = p->parm; goal2 = p->parm2; }
	void 	dump() { printf("#### UF   dv %d goal %d goal2 %d\n",
		height(), goalV, goal2); }
	int	floatable()	{ return 1; }
	void	enqueue(int = 0);
	range	*clone();
	int	goal()		{ return goalV; }
	void	setgoal(int n)	{ goalV = goal2 = n; }
	void	pickgoal(int acv, double scale);
	void	restore()	{ goalV = first->parm; goal2 = first->ht; }
};

class bfrange : public nestrange {
	int	goalV, goal2;
  public:
	bfrange()	{ }
	bfrange(slug *p, stream *s) : nestrange(p, s) {
		goalV = p->parm; goal2 = p->parm2; }
	void 	dump() { printf("#### BF   dv %d goal %d goal2 %d\n",
		height(), goalV, goal2); }
	int	floatable()	{ return 1; }
	void	enqueue(int = 0);
	range	*clone();
	int	goal()		{ return goalV; }
	void	setgoal(int n)	{ goalV = goal2 = n; }
	void	pickgoal(int acv, double scale);
	void	restore()	{ goalV = first->parm; goal2 = first->parm2; }
	int	breakable()	{ return 1; }	// can be broken
};

class ptrange : public nestrange {
	int	pgno;
  public:
	int	pn()	{ return pgno; }
	ptrange(slug *p, stream *s) : nestrange(p, s) { pgno = p->parm; }
	void 	dump() { printf("#### PT   pgno %d dv %d\n", pgno, height()); }
};

class btrange : public nestrange {
	int	pgno;
  public:
	btrange(slug *p, stream *s) : nestrange(p, s) { pgno = p->parm; }
	void 	dump() { printf("#### BT   pgno %d dv %d\n", pgno, height()); }
};

// A stream is a sequence of ranges; we use this data structure a lot
// to traverse various sequences that crop up in page-making.
class stream {
  protected:
public:
	struct strblk {		// ranges are linked by these blocks
		strblk	*next;
		range	*rp;
	};
	strblk	*first;
	strblk	*last;
	strblk	*curr;
  public:
	stream()		{ curr = last = first = 0; }
	stream(range *r)	{ curr = last = first = new strblk;
					last->rp = r; last->next = 0; }
	void	freeall();	// note:  not a destructor
	void	dump();		// top level
	void	rdump();	// recursive
	int	restoreall();
	range	*current()	{ return curr->rp; }
	range	*next()		{ return curr && curr->next ? curr->next->rp : 0; }
	void	advance()	{ curr = curr->next; }
	range	*append(range *r);
	void	split();
	int	more()		{ return curr && curr->rp; }
	int	height();
	int	rawht();
};

// A generator iterates through all the ranges of a stream
// (not just the root ranges of nestranges).
class generator {
	stream	s;
	generator *child;
  public:
	generator()		{ child = 0; }
	generator(stream *sp)	{ s = *sp; child = 0; }
	range	*next();
};

extern stream	ptlist, btlist;		// page titles

#define INFINITY 1000001

// A queue is a distinguished kind of stream.
// It keeps its contents in order by the serial numbers of the ranges.
// A queue can be blocked from dequeuing something to indicate
// that it's not worth considering the queue again on a given page.
class queue : public stream {
	strblk	*newguy;
  protected:
	int	blocked;
	void	check(char *);
  public:
	queue() : blocked(0)	{ }
	range	*enqueue(range *r);
	range	*dequeue();
	void	block()		{ blocked = 1; }
	void	unblock()	{ blocked = 0; }
	int	more()		{ return !blocked && stream::more(); }
	int	empty()		{ return !stream::more(); }
	int	serialno()	{ return empty() ? INFINITY : current()->serialno(); }
};

// functions in range.c
void checkout();
void startup(FILE *);
