#include	<u.h>
#include	<libc.h>
#include	<ctype.h>
#include	<draw.h>
#include	<event.h>
#include	<cursor.h>
#include	<stdio.h>

#define Never	0xffffffff	/* Maximum ulong */
#define LOG2  0.301029995664
#define Button_bit(b)	(1 << ((b)-1))

enum {
	But1	= Button_bit(1),/* mouse buttons for events */
	But2	= Button_bit(2),
	But3	= Button_bit(3)
};
int cantmv = 1;			/* disallow rotate and move? 0..1 */
int top_border, bot_border, lft_border, rt_border;
int lft_border0;		/* lft_border for y-axis labels >0 */
int top_left, top_right;	/* edges of top line free space */
int Mv_delay = 400;		/* msec for button click vs. button hold down */
int Dotrad = 2;			/* dot radius in pixels */
int framewd=1;			/* line thickness for frame (pixels) */
int framesep=1;			/* distance between frame and surrounding text */
int outersep=1;			/* distance: surrounding text to screen edge */
Point sdigit;			/* size of a digit in the font */
Point smaxch;			/* assume any character in font fits in this */
double underscan = .05;		/* fraction of frame initially unused per side */
double fuzz = 6;		/* selection tolerance in pixels */
int tick_len = 15;		/* length of axis label tick mark in pixels */
FILE* logfil = 0;		/* dump selected points here if nonzero */

#define labdigs  3		/* allow this many sig digits in axis labels */
#define digs10pow 1000		/* pow(10,labdigs) */
#define axis_color  clr_im(DLtblue)




/********************************* Utilities  *********************************/

/* Prepend string s to null-terminated string in n-byte buffer buf[], truncating if
   necessary and using a space to separate s from the rest of buf[].
*/
char* str_insert(char* buf, char* s, int n)
{
	int blen, slen = strlen(s) + 1;
	if (slen >= n)
		{strncpy(buf,s,n); buf[n-1]='\0'; return buf;}
	blen = strlen(buf);
	if (blen >= n-slen)
		buf[blen=n-slen-1] = '\0';
	memmove(buf+slen, buf, slen+blen+1);
	memcpy(buf, s, slen-1);
	buf[slen-1] = ' ';
	return buf;
}

/* Alter string smain (without lengthening it) so as to remove the first occurrence of
   ssub, assuming ssub is ASCII.  Return nonzero (true) if string smain had to be changed.
   In spite of the ASCII-centric appearance, I think this can handle UTF in smain.
*/
int remove_substr(char* smain, char* ssub)
{
	char *ss, *s = strstr(smain, ssub);
	int n = strlen(ssub);
	if (s==0)
		return 0;
	if (islower((uchar)s[n]))
		s[0] ^= 32;			/* probably tolower(s[0]) or toupper(s[0]) */
	else {
		for (ss=s+n; *ss!=0; s++, ss++)
			*s = *ss;
		*s = '\0';
	}
	return 1;
}

void adjust_border(Font* f)
{
	int sep = framesep + outersep;
	sdigit = stringsize(f, "8");
	smaxch = stringsize(f, "MMMg");
	smaxch.x = (smaxch.x + 3)/4;
	lft_border0 = (1+labdigs)*sdigit.x + framewd + sep;
	rt_border = (lft_border0 - sep)/2 + outersep;
	bot_border = sdigit.y + framewd + sep;
	top_border = smaxch.y + framewd + sep;
	lft_border = lft_border0;		/* this gets reset later */
}


int is_off_screen(Point p)
{
	const Rectangle* r = &(screen->r);
	return p.x-r->min.x<lft_border || r->max.x-p.x<rt_border
		|| p.y-r->min.y<=top_border || r->max.y-p.y<=bot_border;
}


Cursor	bullseye =
{
	{-7, -7},
	{
		0x1F, 0xF8, 0x3F, 0xFC, 0x7F, 0xFE, 0xFB, 0xDF,
	 	0xF3, 0xCF, 0xE3, 0xC7, 0xFF, 0xFF, 0xFF, 0xFF,
	 	0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC7, 0xF3, 0xCF,
	 	0x7B, 0xDF, 0x7F, 0xFE, 0x3F, 0xFC, 0x1F, 0xF8,
	},
	{
		0x00, 0x00, 0x0F, 0xF0, 0x31, 0x8C, 0x21, 0x84,
		0x41, 0x82, 0x41, 0x82, 0x41, 0x82, 0x7F, 0xFE,
		0x7F, 0xFE, 0x41, 0x82, 0x41, 0x82, 0x41, 0x82,
		0x21, 0x84, 0x31, 0x8C, 0x0F, 0xF0, 0x00, 0x00,
	}
};

int get_1click(int but, Mouse* m, Cursor* curs)
{
	if (curs)
		esetcursor(curs);
	while (m->buttons==0)
		*m = emouse();
	if (curs)
		esetcursor(0);
	return (m->buttons==Button_bit(but));
}


/* Wait until but goes up or until a mouse event's msec passes tlimit.
   Return a boolean result that tells whether the button went up.
*/
int lift_button(int but, Mouse* m, int tlimit)
{
	do {	*m = emouse();
		if (m->msec >= tlimit)
			return 0;
	} while (m->buttons & Button_bit(but));
	return 1;
}


/* Set *m to the last pending mouse event, or the first one where but is up.
   If no mouse events are pending, wait for the next one.
*/
void latest_mouse(int but, Mouse* m)
{
	int bbit = Button_bit(but);
	do {	*m = emouse();
	} while ((m->buttons & bbit) && ecanmouse());
}



/*********************************** Colors ***********************************/

#define DOrange	0xFFAA00FF
#define Dgray		0xBBBBBBFF
#define DDkgreen	0x009900FF
#define DDkred	0xCC0000FF
#define DViolet		0x990099FF
#define DDkyellow	0xAAAA00FF
#define DLtblue	0xAAAAFFFF
#define DPink		0xFFAAAAFF

	/* draw.h sets DBlack, DBlue, DRed, DYellow, DGreen,
		DCyan, DMagenta, DWhite */

typedef struct color_ref {
	ulong c;			/* RGBA pixel color */
	char* nam;			/* ASCII name (matched to input, used in output)*/
	Image* im;			/* replicated solid-color image */
} color_ref;

color_ref clrtab[] = {
	DRed,		"Red",		0,
	DPink,		"Pink",		0,
	DDkred,		"Dkred",	0,
	DOrange,	"Orange",	0,
	DYellow,	"Yellow",	0,
	DDkyellow,	"Dkyellow",	0,
	DGreen,		"Green",	0,
	DDkgreen,	"Dkgreen",	0,
	DCyan,		"Cyan",		0,
	DBlue,		"Blue",		0,
	DLtblue,	"Ltblue",	0,
	DMagenta,	"Magenta",	0,
	DViolet,	"Violet",	0,
	Dgray,		"Gray",		0,
	DBlack,		"Black",	0,
	DWhite,		"White",	0,
	DNofill,	0,		0	/* DNofill means "end of data" */
};


void  init_clrtab(void)
{
	int i;
	Rectangle r = Rect(0,0,1,1);
	for (i=0; clrtab[i].c!=DNofill; i++)
		clrtab[i].im = allocimage(display, r, CMAP8, 1, clrtab[i].c);
		/* should check for 0 result? */
}


int clrim_id(Image* clr)
{
	int i;
	for (i=0; clrtab[i].im!=clr; i++)
		if (clrtab[i].c==DNofill)
			exits("bad image color");
	return i;
}

int clr_id(int clr)
{
	int i;
	for (i=0; clrtab[i].c!=clr; i++)
		if (clrtab[i].c==DNofill)
			exits("bad color");
	return i;
}

#define clr_im(clr)	clrtab[clr_id(clr)].im


/* This decides what color to use for a polyline based on the label it has in the
   input file.  Whichever color name comes first is the winner, otherwise return black.
*/
Image* nam2clr(const char* nam, int *idxdest)
{
	char *c, *cbest=(char*)nam;
	int i, ibest=-1;
	if (*nam!=0)
		for (i=0; clrtab[i].nam!=0; i++) {
			c = strstr(nam,clrtab[i].nam);
			if (c!=0 && (ibest<0 || c<cbest))
				{ibest=i; cbest=c;}
		}
	if (idxdest!=0)
		*idxdest = (ibest<0) ? clr_id(DBlack) : ibest;
	return (ibest<0) ? clr_im(DBlack) : clrtab[ibest].im;
}

/* A polyline is initial drawn in thick mode iff its label in the file contains "Thick" */
int nam2thick(const char* nam)
{
	return strstr(nam,"Thick")==0 ? 0 : 1;
}


/* Alter string nam so that nam2thick() and nam2clr() agree with th and clr, using
   buf[] (a buffer of length bufn) to store the result if it differs from nam.
   We go to great pains to perform this alteration in a manner that will seem natural
   to the user, i.e., we try removing a suitably isolated color name before inserting
   a new one.
*/
char* nam_with_thclr(char* nam, int th, Image* clr, char* buf, int bufn)
{
	int clr0i, th0=nam2thick(nam);
	Image* clr0 = nam2clr(nam, &clr0i);
	char *clr0s;
	if (th0==th && clr0==clr)
		return nam;
	clr0s = clrtab[clr0i].nam;
	if (strlen(nam)<bufn) strcpy(buf,nam);
	else {strncpy(buf,nam,bufn); buf[bufn-1]='\0';}
	if (clr0 != clr)
		remove_substr(buf, clr0s);
	if (th0 > th)
		while (remove_substr(buf, "Thick"))
			/* do nothing */;
	if (nam2clr(buf,0) != clr)
		str_insert(buf, clrtab[clrim_id(clr)].nam, bufn);
	if (th0 < th)
		str_insert(buf, "Thick", bufn);
	return buf;
}



/****************************** Data structures  ******************************/

Image* mv_bkgd;				/* Background image (usually 0) */

typedef struct fpoint {
	double x, y;
} fpoint;

typedef struct frectangle {
	fpoint min, max;
} frectangle;

frectangle empty_frect = {1e30, 1e30, -1e30, -1e30};


/* When *r2 is transformed by y=y-x*slant, might it intersect *r1 ?
*/
int fintersects(const frectangle* r1, const frectangle* r2, double slant)
{
	double x2min=r2->min.x, x2max=r2->max.x;
	if (r1->max.x <= x2min || x2max <= r1->min.x)
		return 0;
	if (slant >=0)
		{x2min*=slant; x2max*=slant;}
	else	{double t=x2min*slant; x2min=x2max*slant; x2max=t;}
	return r1->max.y > r2->min.y-x2max && r2->max.y-x2min > r1->min.y;
}

int fcontains(const frectangle* r, fpoint p)
{
	return r->min.x <=p.x && p.x<= r->max.x && r->min.y <=p.y && p.y<= r->max.y;
}


void grow_bb(frectangle* dest, const frectangle* r)
{
	if (r->min.x < dest->min.x) dest->min.x=r->min.x;
	if (r->min.y < dest->min.y) dest->min.y=r->min.y;
	if (r->max.x > dest->max.x) dest->max.x=r->max.x;
	if (r->max.y > dest->max.y) dest->max.y=r->max.y;
}


void slant_frect(frectangle *r, double sl)
{
	r->min.y += sl*r->min.x;
	r->max.y += sl*r->max.x;
}


fpoint fcenter(const frectangle* r)
{
	fpoint c;
	c.x = .5*(r->max.x + r->min.x);
	c.y = .5*(r->max.y + r->min.y);
	return c;
}


typedef struct fpolygon {
	fpoint* p;			/* a malloc'ed array */
	int n;				/* p[] has n elements: p[0..n] */
	frectangle bb;			/* bounding box */
	char* nam;			/* name of this polygon (malloc'ed) */
	int thick;			/* use 1+2*thick pixel wide lines */
	Image* clr;			/* Color to use when drawing this */
	struct fpolygon* link;
} fpolygon;

typedef struct fpolygons {
	fpolygon* p;			/* the head of a linked list */
	frectangle bb;			/* overall bounding box */
	frectangle disp;		/* part being mapped onto screen->r */
	double slant_ht;		/* controls how disp is slanted */
} fpolygons;


fpolygons univ = {			/* everything there is to display */
	0,
	1e30, 1e30, -1e30, -1e30,
	0, 0, 0, 0,
	2*1e30
};


void set_default_clrs(fpolygons* fps, fpolygon* fpstop)
{
	fpolygon* fp;
	for (fp=fps->p; fp!=0 && fp!=fpstop; fp=fp->link) {
		fp->clr = nam2clr(fp->nam,0);
		fp->thick = nam2thick(fp->nam);
	}
}


void fps_invert(fpolygons* fps)
{
	fpolygon *p, *r=0;
	for (p=fps->p; p!=0;) {
		fpolygon* q = p;
		p = p->link;
		q->link = r;
		r = q;
	}
	fps->p = r;
}


void fp_remove(fpolygons* fps, fpolygon* fp)
{
	fpolygon *q, **p = &fps->p;
	while (*p!=fp)
		if (*p==0)
			return;
		else	p = &(*p)->link;
	*p = fp->link;
	fps->bb = empty_frect;
	for (q=fps->p; q!=0; q=q->link)
		grow_bb(&fps->bb, &q->bb);
}


/* The transform maps abstract fpoint coordinates (the ones used in the input)
   to the current screen coordinates.  The do_untransform() macros reverses this.
   If univ.slant_ht is not the height of univ.disp, the actual region in the
   abstract coordinates is a parallelogram inscribed in univ.disp with two
   vertical edges and two slanted slanted edges: slant_ht>0 means that the
   vertical edges have height slant_ht and the parallelogram touches the lower
   left and upper right corners of univ.disp; slant_ht<0 refers to a parallelogram
   of height -slant_ht that touches the other two corners of univ.disp.
   NOTE: the ytransform macro assumes that tr->sl times the x coordinate has
   already been subtracted from yy.
*/
typedef struct transform {
	double sl;
	fpoint o, sc;		/* (x,y):->(o.x+sc.x*x, o.y+sc.y*y+sl*x) */
} transform;

#define do_transform(d,tr,s)	((d)->x = (tr)->o.x + (tr)->sc.x*(s)->x,  \
				(d)->y = (tr)->o.y + (tr)->sc.y*(s)->y    \
					+ (tr)->sl*(s)->x)
#define do_untransform(d,tr,s)	((d)->x = (.5+(s)->x-(tr)->o.x)/(tr)->sc.x,    \
				(d)->y = (.5+(s)->y-(tr)->sl*(d)->x-(tr)->o.y) \
					/(tr)->sc.y)
#define xtransform(tr,xx)	((tr)->o.x + (tr)->sc.x*(xx))
#define ytransform(tr,yy)	((tr)->o.y + (tr)->sc.y*(yy))
#define dxuntransform(tr,xx)	((xx)/(tr)->sc.x)
#define dyuntransform(tr,yy)	((yy)/(tr)->sc.y)


transform cur_trans(void)
{
	transform t;
	Rectangle d = screen->r;
	const frectangle* s = &univ.disp;
	double sh = univ.slant_ht;
	d.min.x += lft_border;
	d.min.y += top_border;
	d.max.x -= rt_border;
	d.max.y -= bot_border;
	t.sc.x = (d.max.x - d.min.x)/(s->max.x - s->min.x);
	t.sc.y = -(d.max.y - d.min.y)/fabs(sh);
	if (sh > 0) {
		t.sl = -t.sc.y*(s->max.y-s->min.y-sh)/(s->max.x - s->min.x);
		t.o.y = d.min.y - t.sc.y*s->max.y - t.sl*s->max.x;
	} else {
		t.sl = t.sc.y*(s->max.y-s->min.y+sh)/(s->max.x - s->min.x);
		t.o.y = d.min.y - t.sc.y*s->max.y - t.sl*s->min.x;
	}
	t.o.x = d.min.x - t.sc.x*s->min.x;
	return t;
}


double u_slant_amt(fpolygons *u)
{
	double sh=u->slant_ht, dy=u->disp.max.y - u->disp.min.y;
	double dx = u->disp.max.x - u->disp.min.x;
	return (sh>0) ? (dy-sh)/dx : -(dy+sh)/dx;
}


/* Set *y0 and *y1 to the lower and upper bounds of the set of y-sl*x values that
   *u says to display, where sl is the amount of slant.
*/
double set_unslanted_y(fpolygons *u, double *y0, double *y1)
{
	double yy1, sl=u_slant_amt(u);
	if (u->slant_ht > 0) {
		*y0 = u->disp.min.y - sl*u->disp.min.x;
		yy1 = *y0 + u->slant_ht;
	} else {
		yy1 = u->disp.max.y - sl*u->disp.min.x;
		*y0 = yy1 + u->slant_ht;
	}
	if (y1 != 0)
		*y1 = yy1;
	return sl;
}




/*************************** The region to display ****************************/

void nontrivial_interval(double *lo, double *hi)
{
	if (*lo >= *hi) {
		double mid = .5*(*lo + *hi);
		double tweak = 1e-6 + 1e-6*fabs(mid);
		*lo = mid - tweak;
		*hi = mid + tweak;
	}
}


void init_disp(void)
{
	double dw = (univ.bb.max.x - univ.bb.min.x)*underscan;
	double dh = (univ.bb.max.y - univ.bb.min.y)*underscan;
	univ.disp.min.x = univ.bb.min.x - dw;
	univ.disp.min.y = univ.bb.min.y - dh;
	univ.disp.max.x = univ.bb.max.x + dw;
	univ.disp.max.y = univ.bb.max.y + dh;
	nontrivial_interval(&univ.disp.min.x, &univ.disp.max.x);
	nontrivial_interval(&univ.disp.min.y, &univ.disp.max.y);
	univ.slant_ht = univ.disp.max.y - univ.disp.min.y;	/* means no slant */
}


void recenter_disp(Point c)
{
	transform tr = cur_trans();
	fpoint cc, off;
	do_untransform(&cc, &tr, &c);
	off.x = cc.x - .5*(univ.disp.min.x + univ.disp.max.x);
	off.y = cc.y - .5*(univ.disp.min.y + univ.disp.max.y);
	univ.disp.min.x += off.x;
	univ.disp.min.y += off.y;
	univ.disp.max.x += off.x;
	univ.disp.max.y += off.y;
}


/* Find the upper-left and lower-right corners of the bounding box of the
   parallelogram formed by untransforming the rectangle rminx, rminy, ... (given
   in screen coordinates), and return the height of the parallelogram (negated
   if it slopes downward).
*/
double untransform_corners(double rminx, double rminy, double rmaxx, double rmaxy,
		fpoint *ul, fpoint *lr)
{
	fpoint r_ur, r_ul, r_ll, r_lr;	/* corners of the given recangle */
	fpoint ur, ll;			/* untransformed versions of r_ur, r_ll */
	transform tr = cur_trans();
	double ht;
	r_ur.x=rmaxx;  r_ur.y=rminy;
	r_ul.x=rminx;  r_ul.y=rminy;
	r_ll.x=rminx;  r_ll.y=rmaxy;
	r_lr.x=rmaxx;  r_lr.y=rmaxy;
	do_untransform(ul, &tr, &r_ul);
	do_untransform(lr, &tr, &r_lr);
	do_untransform(&ur, &tr, &r_ur);
	do_untransform(&ll, &tr, &r_ll);
	ht = ur.y - lr->y;
	if (ll.x < ul->x)
		ul->x = ll.x;
	if (ur.y > ul->y)
		ul->y = ur.y;
	else	ht = -ht;
	if (ur.x > lr->x)
		lr->x = ur.x;
	if (ll.y < lr->y)
		lr->y = ll.y;
	return ht;
}


void disp_dozoom(double rminx, double rminy, double rmaxx, double rmaxy)
{
	fpoint ul, lr;
	double sh = untransform_corners(rminx, rminy, rmaxx, rmaxy, &ul, &lr);
	if (ul.x==lr.x || ul.y==lr.y)
		return;
	univ.slant_ht = sh;
	univ.disp.min.x = ul.x;
	univ.disp.max.y = ul.y;
	univ.disp.max.x = lr.x;
	univ.disp.min.y = lr.y;
	nontrivial_interval(&univ.disp.min.x, &univ.disp.max.x);
	nontrivial_interval(&univ.disp.min.y, &univ.disp.max.y);
}


void disp_zoomin(Rectangle r)
{
	disp_dozoom(r.min.x, r.min.y, r.max.x, r.max.y);
}


void disp_zoomout(Rectangle r)
{
	double qminx, qminy, qmaxx, qmaxy;
	double scx, scy;
	Rectangle s = screen->r;
	if (r.min.x==r.max.x || r.min.y==r.max.y)
		return;
	s.min.x += lft_border;
	s.min.y += top_border;
	s.max.x -= rt_border;
	s.max.y -= bot_border;
	scx = (s.max.x - s.min.x)/(r.max.x - r.min.x);
	scy = (s.max.y - s.min.y)/(r.max.y - r.min.y);
	qminx = s.min.x + scx*(s.min.x - r.min.x);
	qmaxx = s.max.x + scx*(s.max.x - r.max.x);
	qminy = s.min.y + scy*(s.min.y - r.min.y);
	qmaxy = s.max.y + scy*(s.max.y - r.max.y);
	disp_dozoom(qminx, qminy, qmaxx, qmaxy);
}


void expand2(double* a, double* b, double f)
{
	double mid = .5*(*a + *b);
	*a = mid + f*(*a - mid);
	*b = mid + f*(*b - mid);
}

void disp_squareup(void)
{
	double dx = univ.disp.max.x - univ.disp.min.x;
	double dy = univ.disp.max.y - univ.disp.min.y;
	dx /= screen->r.max.x - lft_border - screen->r.min.x - rt_border;
	dy /= screen->r.max.y - bot_border - screen->r.min.y - top_border;
	if (dx > dy)
		expand2(&univ.disp.min.y, &univ.disp.max.y, dx/dy);
	else	expand2(&univ.disp.min.x, &univ.disp.max.x, dy/dx);
	univ.slant_ht = univ.disp.max.y - univ.disp.min.y;
}


/* Slant so that p and q appear at the same height on the screen and the
   screen contains the smallest possible superset of what its previous contents.
*/
void slant_disp(fpoint p, fpoint q)
{
	double yll, ylr, yul, yur;	/* corner y coords of displayed parallelogram */
	double sh, dy;
	if (p.x == q.x)
		return;
	sh = univ.slant_ht;
	if (sh > 0) {
		yll=yul=univ.disp.min.y;  yul+=sh;
		ylr=yur=univ.disp.max.y;  ylr-=sh;
	} else {
		yll=yul=univ.disp.max.y;  yll+=sh;
		ylr=yur=univ.disp.min.y;  yur-=sh;
	}
	dy = (univ.disp.max.x-univ.disp.min.x)*(q.y - p.y)/(q.x - p.x);
	dy -= ylr - yll;
	if (dy > 0)
		{yll-=dy; yur+=dy;}
	else	{yul-=dy; ylr+=dy;}
	if (ylr > yll) {
		univ.disp.min.y = yll;
		univ.disp.max.y = yur;
		univ.slant_ht = yur - ylr;
	} else {
		univ.disp.max.y = yul;
		univ.disp.min.y = ylr;
		univ.slant_ht = ylr - yur;
	}
}




/******************************** Ascii input  ********************************/

void set_fbb(fpolygon* fp)
{
	fpoint lo=fp->p[0], hi=fp->p[0];
	const fpoint *q, *qtop;
	for (qtop=(q=fp->p)+fp->n; ++q<=qtop;) {
		if (q->x < lo.x) lo.x=q->x;
		if (q->y < lo.y) lo.y=q->y;
		if (q->x > hi.x) hi.x=q->x;
		if (q->y > hi.y) hi.y=q->y;
	}
	fp->bb.min = lo;
	fp->bb.max = hi;
}

char* mystrdup(char* s)
{
	char *r, *t = strrchr(s,'"');
	if (t==0) {
		t = s + strlen(s);
		while (t>s && (t[-1]=='\n' || t[-1]=='\r'))
			t--;
	}
	r = malloc(1+(t-s));
	memcpy(r, s, t-s);
	r[t-s] = 0;
	return r;
}

int is_valid_label(char* lab)
{
	char* t;
	if (lab[0]=='"')
		return (t=strrchr(lab,'"'))!=0 && t!=lab && strspn(t+1," \t\r\n")==strlen(t+1);
	return strcspn(lab," \t")==strlen(lab);
}

/* Read a polyline and update the number of lines read.  A zero result indicates bad
   syntax if *lineno increases; otherwise it indicates end of file.
*/
fpolygon* rd_fpoly(FILE* fin, int *lineno)
{
	char buf[1024], junk[2];
	fpoint q;
	fpolygon* fp;
	int allocn;
	if (!fgets(buf,sizeof buf,fin))
		return 0;
	(*lineno)++;
	if (sscanf(buf,"%lg%lg%1s",&q.x,&q.y,junk) != 2)
		return 0;
	fp = malloc(sizeof(fpolygon));
	allocn = 16;
	fp->p = malloc(allocn*sizeof(fpoint));
	fp->p[0] = q;
	fp->n = 0;
	fp->nam = "";
	fp->thick = 0;
	fp->clr = clr_im(DBlack);
	while (fgets(buf,sizeof buf,fin)) {
		(*lineno)++;
		if (sscanf(buf,"%lg%lg%1s",&q.x,&q.y,junk) != 2) {
			if (!is_valid_label(buf))
				{free(fp->p); free(fp); return 0;}
			fp->nam = (buf[0]=='"') ? buf+1 : buf;
			break;
		}
		if (++(fp->n) == allocn)
			fp->p = realloc(fp->p, (allocn<<=1)*sizeof(fpoint));
		fp->p[fp->n] = q;
	}
	fp->nam = mystrdup(fp->nam);
	set_fbb(fp);
	fp->link = 0;
	return fp;
}


/* Read input into *fps and return 0 or a line number where there's a syntax error */
int rd_fpolys(FILE* fin, fpolygons* fps)
{
	fpolygon *fp, *fp0=fps->p;
	int lineno=0, ok_upto=0;
	while ((fp=rd_fpoly(fin,&lineno)) != 0) {
		ok_upto = lineno;
		fp->link = fps->p;
		fps->p = fp;
		grow_bb(&fps->bb, &fp->bb);
	}
	set_default_clrs(fps, fp0);
	return (ok_upto==lineno) ? 0 : lineno;
}


/* Read input from file fnam and return an error line no., -1 for "can't open"
   or 0 for success.
*/
int doinput(char* fnam)
{
	FILE* fin = strcmp(fnam,"-")==0 ? stdin : fopen(fnam, "r");
	int errline_or0;
	if (fin==0)
		return -1;
	errline_or0 = rd_fpolys(fin, &univ);
	fclose(fin);
	return errline_or0;
}



/******************************** Ascii output ********************************/

fpolygon* fp_reverse(fpolygon* fp)
{
	fpolygon* r = 0;
	while (fp!=0) {
		fpolygon* q = fp->link;
		fp->link = r;
		r = fp;
		fp = q;
	}
	return r;
}

void wr_fpoly(FILE* fout, const fpolygon* fp)
{
	char buf[1024];
	int i;
	for (i=0; i<=fp->n; i++)
		fprintf(fout,"%.12g\t%.12g\n", fp->p[i].x, fp->p[i].y);
	fprintf(fout,"\"%s\"\n", nam_with_thclr(fp->nam, fp->thick, fp->clr, buf, 256));
}

void wr_fpolys(FILE* fout, fpolygons* fps)
{
	fpolygon* fp;
	fps->p = fp_reverse(fps->p);
	for (fp=fps->p; fp!=0; fp=fp->link)
		wr_fpoly(fout, fp);
	fps->p = fp_reverse(fps->p);
}


int dooutput(char* fnam)
{
	FILE* fout = fopen(fnam, "w");
	if (fout==0)
		return 0;
	wr_fpolys(fout, &univ);
	fclose(fout);
	return 1;
}




/************************ Clipping to screen rectangle ************************/

/* Find the t values, 0<=t<=1 for which x0+t*(x1-x0) is between xlo and xhi,
   or return 0 to indicate no such t values exist.  If returning 1, set *t0 and
   *t1 to delimit the t interval.
*/
int do_xory(double x0, double x1, double xlo, double xhi, double* t0, double* t1)
{
	*t1 = 1.0;
	if (x0<xlo) {
		if (x1<xlo) return 0;
		*t0 = (xlo-x0)/(x1-x0);
		if (x1>xhi) *t1 = (xhi-x0)/(x1-x0);
	} else if (x0>xhi) {
		if (x1>xhi) return 0;
		*t0 = (xhi-x0)/(x1-x0);
		if (x1<xlo) *t1 = (xlo-x0)/(x1-x0);
	} else {
		*t0 = 0.0;
		if (x1>xhi) *t1 = (xhi-x0)/(x1-x0);
		else if (x1<xlo) *t1 = (xlo-x0)/(x1-x0);
		else *t1 = 1.0;
	}
	return 1;
}


/* After mapping y to y-slope*x, what initial fraction of the *p to *q edge is
   outside of *r?  Note that the edge could start outside *r, pass through *r,
   and wind up outside again.
*/
double frac_outside(const fpoint* p, const fpoint* q, const frectangle* r,
		double slope)
{
	double t0, t1, tt0, tt1;
	double px=p->x, qx=q->x;
	if (!do_xory(px, qx, r->min.x, r->max.x, &t0, &t1))
		return 1;
	if (!do_xory(p->y-slope*px, q->y-slope*qx, r->min.y, r->max.y, &tt0, &tt1))
		return 1;
	if (tt0 > t0)
		t0 = tt0;
	if (t1<=t0 || tt1<=t0)
		return 1;
	return t0;
}


/* Think of p0..pn as piecewise-linear function F(t) for t=0..pn-p0, and find
   the maximum tt such that F(0..tt) is all inside of r, assuming p0 is inside.
   Coordinates are transformed by y=y-x*slope before testing against r.
*/
double in_length(const fpoint* p0, const fpoint* pn, frectangle r, double slope)
{
	const fpoint* p = p0;
	double px, py;
	do if (++p > pn)
		return pn - p0;
	while (r.min.x<=(px=p->x) && px<=r.max.x
			&& r.min.y<=(py=p->y-slope*px) && py<=r.max.y);
	return (p - p0) - frac_outside(p, p-1, &r, slope);
}


/* Think of p0..pn as piecewise-linear function F(t) for t=0..pn-p0, and find
   the maximum tt such that F(0..tt) is all outside of *r.  Coordinates are
   transformed by y=y-x*slope before testing against r.
*/
double out_length(const fpoint* p0, const fpoint* pn, frectangle r, double slope)
{
	const fpoint* p = p0;
	double fr;
	do {	if (p->x < r.min.x)
			do if (++p>pn) return pn-p0;
			while (p->x <= r.min.x);
		else if (p->x > r.max.x)
			do if (++p>pn) return pn-p0;
			while (p->x >= r.max.x);
		else if (p->y-slope*p->x < r.min.y)
			do if (++p>pn) return pn-p0;
			while (p->y-slope*p->x <= r.min.y);
		else if (p->y-slope*p->x > r.max.y)
			do if (++p>pn) return pn-p0;
			while (p->y-slope*p->x >= r.max.y);
		else return p - p0;
	} while ((fr=frac_outside(p-1,p,&r,slope)) == 1);
	return (p - p0) + fr-1;
}



/*********************** Drawing frame and axis labels  ***********************/

#define Nthous  7
#define Len_thous  30			/* bound on strlen(thous_nam[i]) */
char* thous_nam[Nthous] = {
	"one", "thousand", "million", "billion",
	"trillion", "quadrillion", "quintillion"
};


typedef struct lab_interval {
	double sep;			/* separation between tick marks */
	double unit;		/* power of 1000 divisor */
	int logunit;		/* log base 1000 of of this divisor */
	double off;			/* offset to subtract before dividing */
} lab_interval;


char* abbrev_num(double x, const lab_interval* iv)
{
	static char buf[16];
	double dx = x - iv->off;
	dx = iv->sep * floor(dx/iv->sep + .5);
	sprintf(buf,"%g", dx/iv->unit);
	return buf;
}


double lead_digits(double n, double r)	/* n truncated to power of 10 above r */
{
	double rr = pow(10, ceil(log10(r)));
	double nn = (n<rr) ? 0.0 : rr*floor(n/rr);
	if (n+r-nn >= digs10pow) {
		rr /= 10;
		nn = (n<rr) ? 0.0 : rr*floor(n/rr);
	}
	return nn;
}


lab_interval next_larger(double s0, double xlo, double xhi)
{
	double nlo, nhi;
	lab_interval r;
	r.logunit = (int) floor(log10(s0) + LOG2);
	r.unit = pow(10, r.logunit);
	nlo = xlo/r.unit;
	nhi = xhi/r.unit;
	if (nhi >= digs10pow)
		r.off = r.unit*lead_digits(nlo, nhi-nlo);
	else if (nlo <= -digs10pow)
		r.off = -r.unit*lead_digits(-nhi, nhi-nlo);
	else	r.off = 0;
	r.sep = (s0<=r.unit) ? r.unit : (s0<2*r.unit ? 2*r.unit : 5*r.unit);
	switch (r.logunit%3) {
	case 1:	r.unit*=.1; r.logunit--;
		break;
	case -1: case 2:
		r.unit*=10; r.logunit++;
		break;
	case -2: r.unit*=100; r.logunit+=2;
	}
	r.logunit /= 3;
	return r;
}


double min_hsep(const transform* tr)
{
	double s = (2+labdigs)*sdigit.x;
	double ss = (univ.disp.min.x<0) ? s+sdigit.x : s;
	return dxuntransform(tr, ss);
}


lab_interval mark_x_axis(const transform* tr)
{
	fpoint p = univ.disp.min;
	Point q, qtop, qbot, tmp;
	double x0=univ.disp.min.x, x1=univ.disp.max.x;
	double seps0, nseps, seps;
	lab_interval iv = next_larger(min_hsep(tr), x0, x1);
	set_unslanted_y(&univ, &p.y, 0);
	q.y = ytransform(tr, p.y) + .5;
	qtop.y = q.y - tick_len;
	qbot.y = q.y + framewd + framesep;
	seps0 = ceil(x0/iv.sep);
	for (seps=0, nseps=floor(x1/iv.sep)-seps0; seps<=nseps; seps+=1) {
		char* num = abbrev_num((p.x=iv.sep*(seps0+seps)), &iv);
		Font* f = display->defaultfont;
		q.x = qtop.x = qbot.x = xtransform(tr, p.x);
		line(screen, qtop, q, Enddisc, Enddisc, 0, axis_color, q);
		tmp = stringsize(f, num);
		qbot.x -= tmp.x/2;
		string(screen, qbot, display->black, qbot, f, num);
	}
	return iv;
}


lab_interval mark_y_axis(const transform* tr)
{
	Font* f = display->defaultfont;
	fpoint p = univ.disp.min;
	Point q, qrt, qlft;
	double y0, y1, seps0, nseps, seps;
	lab_interval iv;
	set_unslanted_y(&univ, &y0, &y1);
	iv = next_larger(dyuntransform(tr,-f->height), y0, y1);
	q.x = xtransform(tr, p.x) - .5;
	qrt.x = q.x + tick_len;
	qlft.x = q.x - (framewd + framesep);
	seps0 = ceil(y0/iv.sep);
	for (seps=0, nseps=floor(y1/iv.sep)-seps0; seps<=nseps; seps+=1) {
		char* num = abbrev_num((p.y=iv.sep*(seps0+seps)), &iv);
		Point qq = stringsize(f, num);
		q.y = qrt.y = qlft.y = ytransform(tr, p.y);
		line(screen, qrt, q, Enddisc, Enddisc, 0, axis_color, q);
		qq.x = qlft.x - qq.x;
		qq.y = qlft.y - qq.y/2;
		string(screen, qq, display->black, qq, f, num);
	}
	return iv;
}


void lab_iv_info(const lab_interval *iv, double slant, char* buf, int *n)
{
	if (iv->off > 0)
		(*n) += sprintf(buf+*n,"-%.12g",iv->off);
	else if (iv->off < 0)
		(*n) += sprintf(buf+*n,"+%.12g",-iv->off);
	if (slant>0)
		(*n) += sprintf(buf+*n,"-%.6gx", slant);
	else if (slant<0)
		(*n) += sprintf(buf+*n,"+%.6gx", -slant);
	if (abs(iv->logunit) >= Nthous)
		(*n) += sprintf(buf+*n," in 1e%d units", 3*iv->logunit);
	else if (iv->logunit > 0)
		(*n) += sprintf(buf+*n," in %ss", thous_nam[iv->logunit]);
	else if (iv->logunit < 0)
		(*n) += sprintf(buf+*n," in %sths", thous_nam[-iv->logunit]);
}


void draw_xy_ranges(const lab_interval *xiv, const lab_interval *yiv)
{
	Point p;
	char buf[2*(19+Len_thous+8)+50];
	int bufn = 0;
	buf[bufn++] = 'x';
	lab_iv_info(xiv, 0, buf, &bufn);
	bufn += sprintf(buf+bufn, "; y");
	lab_iv_info(yiv, u_slant_amt(&univ), buf, &bufn);
	buf[bufn] = '\0';
	p = stringsize(display->defaultfont, buf);
	top_left = screen->r.min.x + lft_border;
	p.x = top_right = screen->r.max.x - rt_border - p.x;
	p.y = screen->r.min.y + outersep;
	string(screen, p, display->black, p, display->defaultfont, buf);
}


transform draw_frame(void)
{
	lab_interval x_iv, y_iv;
	transform tr;
	Rectangle r = screen->r;
	lft_border = (univ.disp.min.y<0) ? lft_border0+sdigit.x : lft_border0;
	tr = cur_trans();
	r.min.x += lft_border;
	r.min.y += top_border;
	r.max.x -= rt_border;
	r.max.y -= bot_border;
	border(screen, r, -framewd, axis_color, r.min);
	x_iv = mark_x_axis(&tr);
	y_iv = mark_y_axis(&tr);
	draw_xy_ranges(&x_iv, &y_iv);
	return tr;
}



/*************************** Finding the selection  ***************************/

typedef struct pt_on_fpoly {
	fpoint p;			/* the point */
	fpolygon* fp;			/* the fpolygon it lies on */
	double t;			/* how many knots from the beginning */
} pt_on_fpoly;


static double myx, myy;
#define mydist(p,o,sl,xwt,ywt)	(myx=(p).x-(o).x, myy=(p).y-sl*(p).x-(o).y,	\
					xwt*myx*myx + ywt*myy*myy)

/* At what fraction of the way from p0[0] to p0[1] is mydist(p,ctr,slant,xwt,ywt)
   minimized?
*/
double closest_time(const fpoint* p0, const fpoint* ctr, double slant,
		double xwt, double ywt)
{
	double p00y=p0[0].y-slant*p0[0].x, p01y=p0[1].y-slant*p0[1].x;
	double dx=p0[1].x-p0[0].x, dy=p01y-p00y;
	double x0=p0[0].x-ctr->x, y0=p00y-ctr->y;
	double bot = xwt*dx*dx + ywt*dy*dy;
	if (bot==0)
		return 0;
	return -(xwt*x0*dx + ywt*y0*dy)/bot;
}


/* Scan the polygonal path of length len knots starting at p0, and find the
   point that the transformation y=y-x*slant makes closest to the center of *r,
   where *r itself defines the distance metric.  Knots get higher priority than
   points between knots.  If psel->t is negative, always update *psel; otherwise
   update *psel only if the scan can improve it.  Return a boolean that says
   whether *psel was updated.
     Note that *r is a very tiny rectangle (tiny when converted screen pixels)
   such that anything in *r is considered close enough to match the mouse click.
   The purpose of this routine is to be careful in case there is a lot of hidden
   detail in the tiny rectangle *r.
*/
int improve_pt(fpoint* p0, double len, const frectangle* r, double slant,
		pt_on_fpoly* psel)
{
	fpoint ctr = fcenter(r);
	double x_wt=2/(r->max.x-r->min.x), y_wt=2/(r->max.y-r->min.y);
	double xwt=x_wt*x_wt, ywt=y_wt*y_wt;
	double d, dbest = (psel->t <0) ? 1e30 : mydist(psel->p,ctr,slant,xwt,ywt);
	double tt, dbest0 = dbest;
	fpoint pp;
	int ilen = (int) len;
	if (len==0 || ilen>0) {
		int i;
		for (i=(len==0 ? 0 : 1); i<=ilen; i++) {
			d = mydist(p0[i], ctr, slant, xwt, ywt);
			if (d < dbest)
				{psel->p=p0[i]; psel->t=i; dbest=d;}
		}
		return (dbest < dbest0);
	}
	tt = closest_time(p0, &ctr, slant, xwt, ywt);
	if (tt > len)
		tt = len;
	pp.x = p0[0].x + tt*(p0[1].x - p0[0].x);
	pp.y = p0[0].y + tt*(p0[1].y - p0[0].y);
	if (mydist(pp, ctr, slant, xwt, ywt) < dbest) {
		psel->p = pp;
		psel->t = tt;
		return 1;
	}
	return 0;
}


/* Test *fp against *r after transforming by y=y-x*slope, and set *psel accordingly.
*/
void select_in_fpoly(fpolygon* fp, const frectangle* r, double slant,
		pt_on_fpoly* psel)
{
	fpoint *p0=fp->p, *pn=fp->p+fp->n;
	double l1, l2;
	if (p0==pn)
		{improve_pt(p0, 0, r, slant, psel); psel->fp=fp; return;}
	while ((l1=out_length(p0,pn,*r,slant)) < pn-p0) {
		fpoint p0sav;
		int i1 = (int) l1;
		p0+=i1; l1-=i1;
		p0sav = *p0;
		p0[0].x += l1*(p0[1].x - p0[0].x);
		p0[0].y += l1*(p0[1].y - p0[0].y);
		l2 = in_length(p0, pn, *r, slant);
		if (improve_pt(p0, l2, r, slant, psel)) {
			if (l1==0 && psel->t!=((int) psel->t)) {
				psel->t = 0;
				psel->p = *p0;
			} else if (psel->t < 1)
				psel->t += l1*(1 - psel->t);
			psel->t += p0 - fp->p;
			psel->fp = fp;
		}
		*p0 = p0sav;
		p0 += (l2>0) ? ((int) ceil(l2)) : 1;
	}
}


/* Test all the fpolygons against *r after transforming by y=y-x*slope, and return
   the resulting selection, if any.
*/
pt_on_fpoly* select_in_univ(const frectangle* r, double slant)
{
	static pt_on_fpoly answ;
	fpolygon* fp;
	answ.t = -1;
	for (fp=univ.p; fp!=0; fp=fp->link)
		if (fintersects(r, &fp->bb, slant))
			select_in_fpoly(fp, r, slant, &answ);
	if (answ.t < 0)
		return 0;
	return &answ;
}



/**************************** Using the selection  ****************************/

pt_on_fpoly cur_sel;			/* current selection if cur_sel.t>=0 */
pt_on_fpoly prev_sel;			/* previous selection if prev_sel.t>=0 (for slant) */
Image* sel_bkg = 0;			/* what's behind the red dot */


void clear_txt(void)
{
	Rectangle r;
	r.min = screen->r.min;
	r.min.x += lft_border;
	r.min.y += outersep;
	r.max.x = top_left;
	r.max.y = r.min.y + smaxch.y;
	draw(screen, r, display->white, display->opaque, r.min);
	top_left = r.min.x;
}


Rectangle sel_dot_box(const transform* tr)
{
	Point ctr;
	Rectangle r;
	if (tr==0)
		ctr.x = ctr.y = Dotrad;
	else	do_transform(&ctr, tr, &cur_sel.p);
	r.min.x=ctr.x-Dotrad;  r.max.x=ctr.x+Dotrad+1;
	r.min.y=ctr.y-Dotrad;  r.max.y=ctr.y+Dotrad+1;
	return r;
}


void unselect(const transform* tr)
{
	transform tra;
	if (sel_bkg==0)
		sel_bkg = allocimage(display, sel_dot_box(0), CMAP8, 0, DWhite);
	clear_txt();
	if (cur_sel.t < 0)
		return;
	prev_sel = cur_sel;
	if (tr==0)
		{tra=cur_trans(); tr=&tra;}
	draw(screen, sel_dot_box(tr), sel_bkg, display->opaque, ZP);
	cur_sel.t = -1;
}


/* Text at top right is written first and this low-level routine clobbers it if
   the new top-left text would overwrite it.  However, users of this routine should
   try to keep the new text short enough to avoid this.
*/
void show_mytext(char* msg)
{
	Point tmp, pt = screen->r.min;
	int siz;
	tmp = stringsize(display->defaultfont, msg);
	siz = tmp.x;
	pt.x=top_left;  pt.y+=outersep;
	if (top_left+siz > top_right) {
		Rectangle r;
		r.min.y = pt.y;
		r.min.x = top_right;
		r.max.y = r.min.y + smaxch.y;
		r.max.x = top_left+siz;
		draw(screen, r, display->white, display->opaque, r.min);
		top_right = top_left+siz;
	}
	string(screen, pt, display->black, ZP, display->defaultfont, msg);
	top_left += siz;
}


double rnd(double x, double tol)	/* round to enough digits for accuracy tol */
{
	double t = pow(10, floor(log10(tol)));
	return t * floor(x/t + .5);
}

double t_tol(double xtol, double ytol)
{
	int t = (int) floor(cur_sel.t);
	fpoint* p = cur_sel.fp->p;
	double dx, dy;
	if (t==cur_sel.t)
		return 1;
	dx = fabs(p[t+1].x - p[t].x);
	dy = fabs(p[t+1].y - p[t].y);
	xtol /= (xtol>dx) ? xtol : dx;
	ytol /= (ytol>dy) ? ytol : dy;
	return (xtol<ytol) ? xtol : ytol;
}

void say_where(const transform* tr)
{
	double xtol=dxuntransform(tr,1), ytol=dyuntransform(tr,-1);
	char buf[100];
	int n, nmax = (top_right - top_left)/smaxch.x;
	if (nmax >= 100)
		nmax = 100-1;
	n = sprintf(buf,"(%.14g,%.14g) at t=%.14g",
			rnd(cur_sel.p.x,xtol), rnd(cur_sel.p.y,ytol),
			rnd(cur_sel.t, t_tol(xtol,ytol)));
	if (cur_sel.fp->nam[0] != 0)
		sprintf(buf+n," %.*s", nmax-n-1, cur_sel.fp->nam);
	show_mytext(buf);
}


void reselect(const transform* tr)	/* uselect(); set cur_sel; call this */
{
	Point pt2, pt3;
	fpoint p2;
	transform tra;
	if (cur_sel.t < 0)
		return;
	if (tr==0)
		{tra=cur_trans(); tr=&tra;}
	do_transform(&p2, tr, &cur_sel.p);
	if (fabs(p2.x)+fabs(p2.y)>1e8 || (pt2.x=p2.x, pt2.y=p2.y, is_off_screen(pt2)))
		{cur_sel.t= -1; return;}
	pt3.x=pt2.x-Dotrad;  pt3.y=pt2.y-Dotrad;
	draw(sel_bkg, sel_dot_box(0), screen, display->opaque, pt3);
	fillellipse(screen, pt2, Dotrad, Dotrad, clr_im(DRed), pt2);
	say_where(tr);
}


void do_select(Point pt)
{
	transform tr = cur_trans();
	fpoint pt1, pt2, ctr;
	frectangle r;
	double slant;
	pt_on_fpoly* psel;
	unselect(&tr);
	do_untransform(&ctr, &tr, &pt);
	pt1.x=pt.x-fuzz;  pt1.y=pt.y+fuzz;
	pt2.x=pt.x+fuzz;  pt2.y=pt.y-fuzz;
	do_untransform(&r.min, &tr, &pt1);
	do_untransform(&r.max, &tr, &pt2);
	slant = u_slant_amt(&univ);
	slant_frect(&r, -slant);
	psel = select_in_univ(&r, slant);
	if (psel==0)
		return;
	if (logfil!=0) {
		fprintf(logfil,"%.14g\t%.14g\n", psel->p.x, psel->p.y);
		fflush(logfil);
	}
	cur_sel = *psel;
	reselect(&tr);
}


/***************************** Prompting for text *****************************/

void unshow_mytext(char* msg)
{
	Rectangle r;
	Point siz = stringsize(display->defaultfont, msg);
	top_left -= siz.x;
	r.min.y = screen->r.min.y + outersep;
	r.min.x = top_left;
	r.max.y = r.min.y + siz.y;
	r.max.x = r.min.x + siz.x;
	draw(screen, r, display->white, display->opaque, r.min);
}


/* Show the given prompt and read a line of user input.  The text appears at the
   top left.  If it runs into the top right text, we stop echoing but let the user
   continue typing blind if he wants to.
*/
char* prompt_text(char* prompt)
{
	static char buf[200];
	int n0, n=0, nshown=0;
	Rune c;
	unselect(0);
	show_mytext(prompt);
	while (n<200-1-UTFmax && (c=ekbd())!='\n') {
		if (c=='\b') {
			buf[n] = 0;
			if (n > 0)
				do n--;
				while (n>0 && (buf[n-1]&0xc0)==0x80);
			if (n < nshown)
				{unshow_mytext(buf+n); nshown=n;}
		} else {
			n0 = n;
			n += runetochar(buf+n, &c);
			buf[n] = 0;
			if (nshown==n0 && top_right-top_left >= smaxch.x)
				{show_mytext(buf+n0); nshown=n;}
		}
	}
	buf[n] = 0;
	while (ecanmouse())
		emouse();
	return buf;
}


/**************************** Redrawing the screen ****************************/

/* Let p0 and its successors define a piecewise-linear function of a paramter t,
   and draw the 0<=t<=n1 portion using transform *tr.
*/
void draw_fpts(const fpoint* p0, double n1, const transform* tr, int thick,
		Image* clr)
{
	int n = (int) n1;
	const fpoint* p = p0 + n;
	fpoint pp;
	Point qq, q;
	if (n1 > n) {
		pp.x = p[0].x + (n1-n)*(p[1].x - p[0].x);
		pp.y = p[0].y + (n1-n)*(p[1].y - p[0].y);
	} else	pp = *p--;
	do_transform(&qq, tr, &pp);
	if (n1==0)
		fillellipse(screen, qq, 1+thick, 1+thick, clr, qq);
	for (; p>=p0; p--) {
		do_transform(&q, tr, p);
		line(screen, qq, q, Enddisc, Enddisc, thick, clr, qq);
		qq = q;
	}
}

void draw_1fpoly(const fpolygon* fp, const transform* tr, Image* clr,
		const frectangle *udisp, double slant)
{
	fpoint *p0=fp->p, *pn=fp->p+fp->n;
	double l1, l2;
	if (p0==pn && fcontains(udisp,*p0))
		{draw_fpts(p0, 0, tr, fp->thick, clr); return;}
	while ((l1=out_length(p0,pn,*udisp,slant)) < pn-p0) {
		fpoint p0sav;
		int i1 = (int) l1;
		p0+=i1; l1-=i1;
		p0sav = *p0;
		p0[0].x += l1*(p0[1].x - p0[0].x);
		p0[0].y += l1*(p0[1].y - p0[0].y);
		l2 = in_length(p0, pn, *udisp, slant);
		draw_fpts(p0, l2, tr, fp->thick, clr);
		*p0 = p0sav;
		p0 += (l2>0) ? ((int) ceil(l2)) : 1;
	}
}


double get_clip_data(const fpolygons *u, frectangle *r)
{
	double slant = set_unslanted_y((fpolygons*)u, &r->min.y, &r->max.y);
	r->min.x = u->disp.min.x;
	r->max.x = u->disp.max.x;
	return slant;
}


void draw_fpoly(const fpolygon* fp, const transform* tr, Image* clr)
{
	frectangle r;
	double slant = get_clip_data(&univ, &r);
	draw_1fpoly(fp, tr, clr, &r, slant);
}


void eresized(int new)
{
	transform tr;
	fpolygon* fp;
	frectangle clipr;
	double slant;
	if(new && getwindow(display, Refmesg) < 0) {
		fprintf(stderr,"can't reattach to window\n");
		exits("reshap");
	}
	draw(screen, screen->r, display->white, display->opaque, screen->r.min);
	tr = draw_frame();
	slant = get_clip_data(&univ, &clipr);
	for (fp=univ.p; fp!=0; fp=fp->link)
		if (fintersects(&clipr, &fp->bb, slant))
			draw_1fpoly(fp, &tr, fp->clr, &clipr, slant);
	reselect(0);
	if (mv_bkgd!=0 && mv_bkgd->repl==0) {
		freeimage(mv_bkgd);
		mv_bkgd = display->white;
	}
	flushimage(display, 1);
}




/********************************* Recoloring *********************************/

int draw_palette(int n)		/* n is number of colors; returns patch dy */
{
	int y0 = screen->r.min.y + top_border;
	int dy = (screen->r.max.y - bot_border - y0)/n;
	Rectangle r;
	int i;
	r.min.y = y0;
	r.min.x = screen->r.max.x - rt_border + framewd;
	r.max.y = y0 + dy;
	r.max.x = screen->r.max.x;
	for (i=0; i<n; i++) {
		draw(screen, r, clrtab[i].im, display->opaque, r.min);
		r.min.y = r.max.y;
		r.max.y += dy;
	}
	return dy;
}


Image* palette_color(Point pt, int dy, int n)
{				/* mouse at pt, patch size dy, n colors */
	int yy;
	if (screen->r.max.x - pt.x > rt_border - framewd)
		return 0;
	yy = pt.y - (screen->r.min.y + top_border);
	if (yy<0 || yy>=n*dy)
		return 0;
	return clrtab[yy/dy].im;
}


void all_set_clr(fpolygons* fps, Image* clr)
{
	fpolygon* p;
	for (p=fps->p; p!=0; p=p->link)
		p->clr = clr;
}
	

void do_recolor(int but, Mouse* m, int alluniv)
{
	int nclr = clr_id(DWhite);
	int dy = draw_palette(nclr);
	Image* clr;
	if (!get_1click(but, m, 0)) {
		eresized(0);
		return;
	}
	clr = palette_color(m->xy, dy, nclr);
	if (clr != 0) {
		if (alluniv)
			all_set_clr(&univ, clr);
		else	cur_sel.fp->clr = clr;
	}
	eresized(0);
	lift_button(but, m, Never);
}


/****************************** Move and rotate  ******************************/

void prepare_mv(const fpolygon* fp)
{
	Rectangle r = screen->r;
	Image* scr0;
	int dt = 1 + fp->thick;
	r.min.x+=lft_border-dt;  r.min.y+=top_border-dt;
	r.max.x-=rt_border-dt;   r.max.y-=bot_border-dt;
	if (mv_bkgd!=0 && mv_bkgd->repl==0)
		freeimage(mv_bkgd);
	mv_bkgd = allocimage(display, r, CMAP8, 0, DNofill);
	if (mv_bkgd==0)
		mv_bkgd = display->white;
	else {	transform tr = cur_trans();
		draw(mv_bkgd, r, screen, display->opaque, r.min);
		draw(mv_bkgd, sel_dot_box(&tr), sel_bkg, display->opaque, ZP);
		scr0 = screen;
		screen = mv_bkgd;
		draw_fpoly(fp, &tr, display->white);
		screen = scr0;
	}
}


void move_fp(fpolygon* fp, double dx, double dy)
{
	fpoint *p, *pn=fp->p+fp->n;
	for (p=fp->p; p<=pn; p++) {
		(p->x) += dx;
		(p->y) += dy;
	}
	(fp->bb.min.x)+=dx;  (fp->bb.min.y)+=dy;
	(fp->bb.max.x)+=dx;  (fp->bb.max.y)+=dy;
}


void rotate_fp(fpolygon* fp, fpoint o, double theta)
{
	double s=sin(theta), c=cos(theta);
	fpoint *p, *pn=fp->p+fp->n;
	for (p=fp->p; p<=pn; p++) {
		double x=p->x-o.x, y=p->y-o.y;
		(p->x) = o.x + c*x - s*y;
		(p->y) = o.y + s*x + c*y;
	}
	set_fbb(fp);
}


/* Move the selected fpolygon so the selected point tracks the mouse, and return
   the total amount of movement.  Button but has already been held down for at
   least Mv_delay milliseconds and the mouse might have moved some distance.
*/
fpoint do_move(int but, Mouse* m)
{
	transform tr = cur_trans();
	int bbit = Button_bit(but);
	fpolygon* fp = cur_sel.fp;
	fpoint loc, loc0=cur_sel.p;
	double tsav = cur_sel.t;
	unselect(&tr);
	do {	latest_mouse(but, m);
		(fp->thick)++;		/* line() DISAGREES WITH ITSELF */
		draw_fpoly(fp, &tr, mv_bkgd);
		(fp->thick)--;
		do_untransform(&loc, &tr, &m->xy);
		move_fp(fp, loc.x-cur_sel.p.x, loc.y-cur_sel.p.y);
		cur_sel.p = loc;
		draw_fpoly(fp, &tr, fp->clr);
	} while (m->buttons & bbit);
	cur_sel.t = tsav;
	reselect(&tr);
	loc.x -= loc0.x;
	loc.y -= loc0.y;
	return loc;
}


double dir_angle(const Point* pt, const transform* tr)
{
	fpoint p;
	double dy, dx;
	do_untransform(&p, tr, pt);
	dy=p.y-cur_sel.p.y;  dx=p.x-cur_sel.p.x;
	return (dx==0 && dy==0) ? 0.0 : atan2(dy, dx);
}


/* Rotate the selected fpolygon around the selection point so as to track the
   direction angle from the selected point to m->xy.  Stop when button but goes
   up and return the total amount of rotation in radians.
*/
double do_rotate(int but, Mouse* m)
{
	transform tr = cur_trans();
	int bbit = Button_bit(but);
	fpolygon* fp = cur_sel.fp;
	double theta0 = dir_angle(&m->xy, &tr);
	double th, theta = theta0;
	do {	latest_mouse(but, m);
		(fp->thick)++;		/* line() DISAGREES WITH ITSELF */
		draw_fpoly(fp, &tr, mv_bkgd);
		(fp->thick)--;
		th = dir_angle(&m->xy, &tr);
		rotate_fp(fp, cur_sel.p, th-theta);
		theta = th;
		draw_fpoly(fp, &tr, fp->clr);
	} while (m->buttons & bbit);
	unselect(&tr);
	cur_sel = prev_sel;
	reselect(&tr);
	return theta - theta0;
}



/********************************* Edit menu  *********************************/

typedef enum e_index {
		Erecolor, Ethick, Edelete, Eundo, Erotate, Eoptions,
		Emove
} e_index;

char* e_items[Eoptions+1];

Menu e_menu = {e_items, 0, 0};


typedef struct e_action {
	e_index typ;			/* What type of action */
	fpolygon* fp;			/* fpolygon the action applies to */
	Image* clr;			/* color to use if typ==Erecolor */
	double amt;			/* rotation angle or line thickness */
	fpoint pt;			/* movement vector or rotation center */
	struct e_action* link;		/* next in a stack */
} e_action;

e_action* unact = 0;			/* heads a linked list of actions */
e_action* do_undo(e_action*);		/* pop off an e_action and (un)do it */
e_action* save_act(e_action*,e_index);	/* append new e_action for status quo */


void save_mv(fpoint movement)
{
	unact = save_act(unact, Emove);
	unact->pt = movement;
}


void init_e_menu(void)
{
	char* u = "can't undo";
	e_items[Erecolor] = "recolor";
	e_items[Edelete] = "delete";
	e_items[Erotate] = "rotate";
	e_items[Eoptions-cantmv] = 0;
	e_items[Ethick] = (cur_sel.fp->thick >0) ? "thin" : "thick";
	if (unact!=0)
		switch (unact->typ) {
		case Erecolor: u="uncolor"; break;
		case Ethick: u=(unact->fp->thick==0) ? "unthin" : "unthicken";
			break;
		case Edelete: u="undelete"; break;
		case Emove: u="unmove"; break;
		case Erotate: u="unrotate"; break;
		}
	e_items[Eundo] = u;
}


void do_emenu(int but, Mouse* m)
{
	int h;
	if (cur_sel.t < 0)
		return;
	init_e_menu();
	h = emenuhit(but, m, &e_menu);
	switch(h) {
	case Ethick: unact = save_act(unact, h);
		cur_sel.fp->thick ^= 1;
		eresized(0);
		break;
	case Edelete: unact = save_act(unact, h);
		fp_remove(&univ, cur_sel.fp);
		unselect(0);
		eresized(0);
		break;
	case Erecolor: unact = save_act(unact, h);
		do_recolor(but, m, 0);
		break;
	case Erotate: unact = save_act(unact, h);
		prepare_mv(cur_sel.fp);
		if (get_1click(but, m, 0)) {
			unact->pt = cur_sel.p;
			unact->amt = do_rotate(but, m);
		}
		break;
	case Eundo: unact = do_undo(unact);
		break;
	}
}



/******************************* Undoing edits  *******************************/

e_action* save_act(e_action* a0, e_index typ)
{					/* append new e_action for status quo */
	e_action* a = malloc(sizeof(e_action));
	a->link = a0;
	a->pt.x = a->pt.y = 0.0;
	a->amt = cur_sel.fp->thick;
	a->clr = cur_sel.fp->clr;
	a->fp = cur_sel.fp;
	a->typ = typ;
	return a;
}


/* This would be trivial except it's nice to preserve the selection in order to make
   it easy to undo a series of moves.  (There's no do_unrotate() because it's harder
   and less important to preserve the selection in that case.)
*/
void do_unmove(e_action* a)
{
	double tsav = cur_sel.t;
	unselect(0);
	move_fp(a->fp, -a->pt.x, -a->pt.y);
	if (a->fp == cur_sel.fp) {
		cur_sel.p.x -= a->pt.x;
		cur_sel.p.y -= a->pt.y;
	}
	cur_sel.t = tsav;
	reselect(0);
}


e_action* do_undo(e_action* a0)		/* pop off an e_action and (un)do it */
{
	e_action* a = a0;
	if (a==0)
		return 0;
	switch(a->typ) {
	case Ethick: a->fp->thick = a->amt;
		eresized(0);
		break;
	case Erecolor: a->fp->clr = a->clr;
		eresized(0);
		break;
	case Edelete: 
		a->fp->link = univ.p;
		univ.p = a->fp;
		grow_bb(&univ.bb, &a->fp->bb);
		eresized(0);
		break;
	case Emove:
		do_unmove(a);
		eresized(0);
		break;
	case Erotate:
		unselect(0);
		rotate_fp(a->fp, a->pt, -a->amt);
		eresized(0);
		break;
	}
	a0 = a->link;
	free(a);
	return a0;
}



/********************************* Main menu  *********************************/

enum m_index {     Mzoom_in,  Mzoom_out,  Munzoom,  Mslant,    Munslant,
		Msquare_up,  Mrecenter,  Mrecolor,  Mrestack,  Mread,
		Mwrite,      Mexit};
char* m_items[] = {"zoom in", "zoom out", "unzoom", "slant",   "unslant",
		"square up", "recenter", "recolor", "restack", "read",
		"write",     "exit", 0};

Menu m_menu = {m_items, 0, 0};


void do_mmenu(int but, Mouse* m)
{
	int e, h = emenuhit(but, m, &m_menu);
	switch (h) {
	case Mzoom_in:
		disp_zoomin(egetrect(but,m));
		eresized(0);
		break;
	case Mzoom_out:
		disp_zoomout(egetrect(but,m));
		eresized(0);
		break;
	case Msquare_up:
		disp_squareup();
		eresized(0);
		break;
	case Munzoom:
		init_disp();
		eresized(0);
		break;
	case Mrecenter:
		if (get_1click(but, m, &bullseye)) {
			recenter_disp(m->xy);
			eresized(0);
			lift_button(but, m, Never);
		}
		break;
	case Mslant:
		if (cur_sel.t>=0 && prev_sel.t>=0) {
			slant_disp(prev_sel.p, cur_sel.p);
			eresized(0);
		}
		break;
	case Munslant:
		univ.slant_ht = univ.disp.max.y - univ.disp.min.y;
		eresized(0);
		break;
	case Mrecolor:
		do_recolor(but, m, 1);
		break;
	case Mrestack:
		fps_invert(&univ);
		eresized(0);
		break;
	case Mread:
		e = doinput(prompt_text("File:"));
		if (e==0)
			eresized(0);
		else if (e<0)
			show_mytext(" - can't read");
		else {
			char ebuf[80];
			snprintf(ebuf, 80, " - error line %d", e);
			show_mytext(ebuf);
		}
		break;
	case Mwrite:
		if (!dooutput(prompt_text("File:")))
			show_mytext(" - can't write");
		break;
	case Mexit:
		exits("");
	}
}



/****************************** Handling events  ******************************/

void doevent(void)
{
	ulong etype;
	int mobile;
	ulong mvtime;
	Event	ev;

	etype = eread(Emouse|Ekeyboard, &ev);
	if(etype & Emouse) {
		if (ev.mouse.buttons & But1) {
			do_select(ev.mouse.xy);
			mvtime = Never;
			mobile = !cantmv && cur_sel.t>=0;
			if (mobile) {
				mvtime = ev.mouse.msec + Mv_delay;
				prepare_mv(cur_sel.fp);
				if (!lift_button(1, &ev.mouse, mvtime))
					save_mv(do_move(1, &ev.mouse));
			}
		} else if (ev.mouse.buttons & But2)
			do_emenu(2, &ev.mouse);
		else if (ev.mouse.buttons & But3)
			do_mmenu(3, &ev.mouse);
	}
	/* no need to check (etype & Ekeyboard)--there are no keyboard commands */
}



/******************************** Main program ********************************/

extern char* argv0;

void usage(void)
{
	int i;
	fprintf(stderr,"Usage %s [options] [infile]\n", argv0);
	fprintf(stderr,
"option ::= -W winsize | -l logfile | -m\n"
"\n"
"Read a polygonal line graph in an ASCII format (one x y pair per line, delimited\n"
"by spaces with a label after each polyline), and view it interactively.  Use\n"
"standard input if no infile is specified.\n"
	);
	fprintf(stderr,
"Option -l specifies a file in which to log the coordinates of each point selected.\n"
"(Clicking a point with button one selects it and displays its coordinates and\n"
"the label of its polylone.)  Option -m allows polylines to be moved and rotated.\n"
"The polyline labels can use the following color names:"
	);
	for (i=0; clrtab[i].c!=DNofill; i++)
		fprintf(stderr,"%s%8s", (i%8==0 ? "\n" : "  "), clrtab[i].nam);
	fputc('\n', stderr);
	exits("usage");
}

void main(int argc, char *argv[])
{
	int e;

	ARGBEGIN {
	case 'm': cantmv=0;
		break;
	case 'l': logfil = fopen(ARGF(),"w");
		break;
	case 'W':
		winsize = EARGF(usage());
		break;
	default: usage();
	} ARGEND

	if(initdraw(0, 0, "gview") < 0)
		exits("initdraw");
	einit(Emouse|Ekeyboard);

	e = doinput(*argv ? *argv : "-");
	if (e < 0) {
		fprintf(stderr,"Cannot read input file %s\n", *argv);
		exits("no valid input file");
	} else if (e > 0) {
		fprintf(stderr,"Bad syntax at line %d in input file\n", e);
		exits("bad syntax in input");
	}
	init_disp();
	init_clrtab();
	set_default_clrs(&univ, 0);
	adjust_border(display->defaultfont);
	cur_sel.t = prev_sel.t = -1;
	eresized(0);
	for(;;)
		doevent();
}
