#include <u.h>
#include <libc.h>
#include <stdio.h>
#include "iplot.h"
#define	INF	1.e+37
#define	F	.25

struct xy {
	int	xlbf;		/*flag:explicit lower bound*/
	int 	xubf;		/*flag:explicit upper bound*/
	int	xqf;		/*flag:explicit quantum*/
	double (*xf)(double);	/*transform function, e.g. log*/
	float	xa,xb;		/*scaling coefficients*/
	float	xlb,xub;	/*lower and upper bound*/
	float	xquant;		/*quantum*/
	float	xoff;		/*screen offset fraction*/
	float	xsize;		/*screen fraction*/
	int	xbot,xtop;	/*screen coords of border*/	
	float	xmult;		/*scaling constant*/
} xd,yd;
struct val {
	float xv;
	float yv;
	int lblptr;
} *xx;

char *labels;
int labelsiz;

int tick = 50;
int top = 4000;
int bot = 200;
float absbot;
int	n;
int	erasf = 1;
int	gridf = 2;
int	symbf = 0;
int	absf = 0;
int	transf;
int	equf;
int	brkf;
int	ovlay = 1;
float	dx;
char	*plotsymb;

#define BSIZ 80
char	labbuf[BSIZ];
char	titlebuf[BSIZ];

char *modes[] = {
	"disconnected",
	"solid",
	"dotted",
	"dotdashed",
	"shortdashed",
	"longdashed"
};
int mode = 1;
double ident(double x){
	return(x);
}

struct z {
	float lb,ub,mult,quant;
};
void init(struct xy *);
void setopt(int, char *[]);
void readin(void);
void transpose(void);
void getlim(struct xy *, struct val *);
void equilibrate(struct xy *, struct xy *);
void scale(struct xy *);
void limread(struct xy *, int *, char ***);
int numb(float *, int *, char ***);
int copystring(int);
struct z setloglim(int, int, float, float);
struct z setlinlim(int, int, float, float);
void axes(void);
int setmark(int *, struct xy *);
void submark(int *, int *, float, struct xy *);
void plot(void);
int getfloat(float *);
int getstring(void);
void title(void);
void badarg(void);
int conv(float, struct xy *, int *);
int symbol(int, int, int);
void axlab(char, struct xy *, char *);

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

	openpl();
	range(0,0,4096,4096);
	init(&xd);
	init(&yd);
	xd.xsize = yd.xsize = 1.;
	xx = (struct val *)malloc((unsigned)sizeof(struct val));
	labels = malloc(1);
	labels[labelsiz++] = 0;
	setopt(argc,argv);
	if(erasf)
		erase();
	readin();
	transpose();
	getlim(&xd,(struct val *)&xx->xv);
	getlim(&yd,(struct val *)&xx->yv);
	if(equf) {
		equilibrate(&xd,&yd);
		equilibrate(&yd,&xd);
	}
	scale(&xd);
	scale(&yd);
	axes();
	title();
	plot();
	closepl();
	exits(0);
	return 0;	/* gcc */
}

void init(struct xy *p){
	p->xf = ident;
	p->xmult = 1;
}

void setopt(int argc, char *argv[]){
	char *p1, *p2;
	float temp;

	xd.xlb = yd.xlb = INF;
	xd.xub = yd.xub = -INF;
	while(--argc > 0) {
		argv++;
again:		switch(argv[0][0]) {
		case '-':
			argv[0]++;
			goto again;
		case 'l': /* label for plot */
			p1 = titlebuf;
			if (argc>=2) {
				argv++;
				argc--;
				p2 = argv[0];
				while (*p1++ = *p2++);
			}
			break;

		case 'd':	/*disconnected,obsolete option*/
		case 'm': /*line mode*/
			mode = 0;
			if(!numb(&temp,&argc,&argv))
				break;
			if(temp>=sizeof(modes)/sizeof(*modes))
				mode = 1;
			else if(temp>=-1)
				mode = temp;
			break;

		case 'o':
			if(numb(&temp,&argc,&argv) && temp>=1)
				ovlay = temp;
			break;
		case 'a': /*automatic abscissas*/
			absf = 1;
			dx = 1;
			if(!numb(&dx,&argc,&argv))
				break;
			if(numb(&absbot,&argc,&argv))
				absf = 2;
			break;

		case 's': /*save screen, overlay plot*/
			erasf = 0;
			break;

		case 'g': /*grid style 0 none, 1 ticks, 2 full*/
			gridf = 0;
			if(!numb(&temp,&argc,&argv))
				temp = argv[0][1]-'0';	/*for caompatibility*/
			if(temp>=0&&temp<=2)
				gridf = temp;
			break;

		case 'c': /*character(s) for plotting*/
			if(argc >= 2) {
				symbf = 1;
				plotsymb = argv[1];
				argv++;
				argc--;
			}
			break;

		case 't':	/*transpose*/
			transf = 1;
			break;
		case 'e':	/*equal scales*/
			equf = 1;
			break;
		case 'b':	/*breaks*/
			brkf = 1;
			break;
		case 'x':	/*x limits */
			limread(&xd,&argc,&argv);
			break;
		case 'y':
			limread(&yd,&argc,&argv);
			break;
		case 'h': /*set height of plot */
			if(!numb(&yd.xsize, &argc,&argv))
				badarg();
			break;
		case 'w': /*set width of plot */
			if(!numb(&xd.xsize, &argc, &argv))
				badarg();
			break;
		case 'r': /* set offset to right */
			if(!numb(&xd.xoff, &argc, &argv))
				badarg();
			break;
		case 'u': /*set offset up the screen*/
			if(!numb(&yd.xoff,&argc,&argv))
				badarg();
			break;
		default:
			badarg();
		}
	}
}

void limread(struct xy *p, int *argcp, char ***argvp){
	if(*argcp>1 && (*argvp)[1][0]=='l') {
		(*argcp)--;
		(*argvp)++;
		p->xf = log10;
	}
	if(!numb(&p->xlb,argcp,argvp))
		return;
	p->xlbf = 1;
	if(!numb(&p->xub,argcp,argvp))
		return;
	p->xubf = 1;
	if(!numb(&p->xquant,argcp,argvp))
		return;
	p->xqf = 1;
}

#ifdef NOTDEF
isdigit(char c){
	return '0'<=c && c<='9';
}
#endif

int
numb(float *np, int *argcp, char ***argvp){
	char c;

	if(*argcp <= 1)
		return(0);
	while((c=(*argvp)[1][0]) == '+')
		(*argvp)[1]++;
	if(!(isdigit(c) || c=='-'&&(*argvp)[1][1]<'A' || c=='.'))
		return(0);
	*np = atof((*argvp)[1]);
	(*argcp)--;
	(*argvp)++;
	return(1);
}

void readin(void){
	int i, t;
	struct val *temp;

	if(absf==1) {
		if(xd.xlbf)
			absbot = xd.xlb;
		else if(xd.xf==log10)
			absbot = 1;
	}
	for(;;) {
		temp = (struct val *)realloc((char*)xx,
			(unsigned)(n+ovlay)*sizeof(struct val));
		if(temp==0)
			return;
		xx = temp;
		if(absf)
			xx[n].xv = n*dx/ovlay + absbot;
		else
			if(!getfloat(&xx[n].xv))
				return;
		t = 0;	/* silence compiler */
		for(i=0;i<ovlay;i++) {
			xx[n+i].xv = xx[n].xv;
			if(!getfloat(&xx[n+i].yv))
				return;
			xx[n+i].lblptr = -1;
			t = getstring();
			if(t>0)
				xx[n+i].lblptr = copystring(t);
			if(t<0 && i+1<ovlay)
				return;
		}
		n += ovlay;
		if(t<0)
			return;
	}
}

void transpose(void){
	int i;
	float f;
	struct xy t;
	if(!transf)
		return;
	t = xd; xd = yd; yd = t;
	for(i= 0;i<n;i++) {
		f = xx[i].xv; xx[i].xv = xx[i].yv; xx[i].yv = f;
	}
}

int copystring(int k){
	char *temp;
	int i;
	int q;

	temp = realloc(labels,(unsigned)(labelsiz+1+k));
	if(temp==0)
		return(0);
	labels = temp;
	q = labelsiz;
	for(i=0;i<=k;i++)
		labels[labelsiz++] = labbuf[i];
	return(q);
}

float modceil(float f, float t){

	t = fabs(t);
	return(ceil(f/t)*t);
}

float
modfloor(float f, float t){
	t = fabs(t);
	return(floor(f/t)*t);
}

void getlim(struct xy *p, struct val *v){
	int i;

	i = 0;
	do {
		if(!p->xlbf && p->xlb>v[i].xv)
			p->xlb = v[i].xv;
		if(!p->xubf && p->xub<v[i].xv)
			p->xub = v[i].xv;
		i++;
	} while(i < n);
}

void setlim(struct xy *p){
	float t,delta,sign;
	struct z z;
	int mark[50];
	float lb,ub;
	int lbf,ubf;

	lb = p->xlb;
	ub = p->xub;
	delta = ub-lb;
	if(p->xqf) {
		if(delta*p->xquant <=0 )
			badarg();
		return;
	}
	sign = 1;
	lbf = p->xlbf;
	ubf = p->xubf;
	if(delta < 0) {
		sign = -1;
		t = lb;
		lb = ub;
		ub = t;
		t = lbf;
		lbf = ubf;
		ubf = t;
	}
	else if(delta == 0) {
		if(ub > 0) {
			ub = 2*ub;
			lb = 0;
		} 
		else
			if(lb < 0) {
				lb = 2*lb;
				ub = 0;
			} 
			else {
				ub = 1;
				lb = -1;
			}
	}
	if(p->xf==log10 && lb>0 && ub>lb) {
		z = setloglim(lbf,ubf,lb,ub);
		p->xlb = z.lb;
		p->xub = z.ub;
		p->xmult *= z.mult;
		p->xquant = z.quant;
		if(setmark(mark,p)<2) {
			p->xqf = lbf = ubf = 1;
			lb = z.lb; ub = z.ub;
		} else
			return;
	}
	z = setlinlim(lbf,ubf,lb,ub);
	if(sign > 0) {
		p->xlb = z.lb;
		p->xub = z.ub;
	} else {
		p->xlb = z.ub;
		p->xub = z.lb;
	}
	p->xmult *= z.mult;
	p->xquant = sign*z.quant;
}

struct z
setloglim(int lbf, int ubf, float lb, float ub){
	float r,s,t;
	struct z z;

	for(s=1; lb*s<1; s*=10) ;
	lb *= s;
	ub *= s;
	for(r=1; 10*r<=lb; r*=10) ;
	for(t=1; t<ub; t*=10) ;
	z.lb = !lbf ? r : lb;
	z.ub = !ubf ? t : ub;
	if(ub/lb<100) {
		if(!lbf) {
			if(lb >= 5*z.lb)
				z.lb *= 5;
			else if(lb >= 2*z.lb)
				z.lb *= 2;
		}
		if(!ubf) {
			if(ub*5 <= z.ub)
				z.ub /= 5;
			else if(ub*2 <= z.ub)
				z.ub /= 2;
		}
	}
	z.mult = s;
	z.quant = r;
	return(z);
}

struct z
setlinlim(int lbf, int ubf, float xlb, float xub){
	struct z z;
	float r,s,delta;
	float ub,lb;

loop:
	ub = xub;
	lb = xlb;
	delta = ub - lb;
	/*scale up by s, a power of 10, so range (delta) exceeds 1*/
	/*find power of 10 quantum, r, such that delta/10<=r<delta*/
	r = s = 1;
	while(delta*s < 10)
		s *= 10;
	delta *= s;
	while(10*r < delta)
		r *= 10;
	lb *= s;
	ub *= s;
	/*set r=(1,2,5)*10**n so that 3-5 quanta cover range*/
	if(r>=delta/2)
		r /= 2;
	else if(r<delta/5)
		r *= 2;
	z.ub = ubf? ub: modceil(ub,r);
	z.lb = lbf? lb: modfloor(lb,r);
	if(!lbf && z.lb<=r && z.lb>0) {
		xlb = 0;
		goto loop;
	}
	else if(!ubf && z.ub>=-r && z.ub<0) {
		xub = 0;
		goto loop;
	}
	z.quant = r;
	z.mult = s;
	return(z);
}

void scale(struct xy *p){
	float edge;

	setlim(p);
	edge = top-bot;
	p->xa = p->xsize*edge/((*p->xf)(p->xub) - (*p->xf)(p->xlb));
	p->xbot = bot + edge*p->xoff;
	p->xtop = p->xbot + (top-bot)*p->xsize;
	p->xb = p->xbot - (*p->xf)(p->xlb)*p->xa + .5;
}

void equilibrate(struct xy *p, struct xy *q){
	if(p->xlbf||	/* needn't test xubf; it implies xlbf*/
	   q->xubf&&q->xlb>q->xub)
		return;
	if(p->xlb>q->xlb) {
		p->xlb = q->xlb;
		p->xlbf = q->xlbf;
	}
	if(p->xub<q->xub) {
		p->xub = q->xub;
		p->xubf = q->xubf;
	}
}

void axes(void){
	int i;
	int mark[50];
	int xn, yn;
	if(gridf==0)
		return;

	line(xd.xbot,yd.xbot,xd.xtop,yd.xbot);
	vec(xd.xtop,yd.xtop);
	vec(xd.xbot,yd.xtop);
	vec(xd.xbot,yd.xbot);

	xn = setmark(mark,&xd);
	for(i=0; i<xn; i++) {
		if(gridf==2)
			line(mark[i],yd.xbot,mark[i],yd.xtop);
		if(gridf==1) {
			line(mark[i],yd.xbot,mark[i],yd.xbot+tick);
			line(mark[i],yd.xtop-tick,mark[i],yd.xtop);
		}
	}
	yn = setmark(mark,&yd);
	for(i=0; i<yn; i++) {
		if(gridf==2)
			line(xd.xbot,mark[i],xd.xtop,mark[i]);
		if(gridf==1) {
			line(xd.xbot,mark[i],xd.xbot+tick,mark[i]);
			line(xd.xtop-tick,mark[i],xd.xtop,mark[i]);
		}
	}
}

int
setmark(int *xmark, struct xy *p){
	int xn = 0;
	float x,xl,xu;
	float q;
	if(p->xf==log10&&!p->xqf) {
		for(x=p->xquant; x<p->xub; x*=10) {
			submark(xmark,&xn,x,p);
			if(p->xub/p->xlb<=100) {
				submark(xmark,&xn,2*x,p);
				submark(xmark,&xn,5*x,p);
			}
		}
	} else {
		xn = 0;
		q = p->xquant;
		if(q>0) {
			xl = modceil(p->xlb+q/6,q);
			xu = modfloor(p->xub-q/6,q)+q/2;
		} else {
			xl = modceil(p->xub-q/6,q);
			xu = modfloor(p->xlb+q/6,q)-q/2;
		}
		for(x=xl; x<=xu; x+=fabs(p->xquant))
			xmark[xn++] = (*p->xf)(x)*p->xa + p->xb;
	}
	return(xn);
}
void submark(int *xmark, int *pxn, float x, struct xy *p){
	if(1.001*p->xlb < x && .999*p->xub > x)
		xmark[(*pxn)++] = log10(x)*p->xa + p->xb;
}

void plot(void){
	int ix,iy;
	int i,j;
	int conn;

	for(j=0;j<ovlay;j++) {
		switch(mode) {
		case -1:
			pen(modes[j%(sizeof modes/sizeof *modes-1)+1]);
			break;
		case 0:
			break;
		default:
			pen(modes[mode]);
		}
		conn = 0;
		for(i=j; i<n; i+=ovlay) {
			if(!conv(xx[i].xv,&xd,&ix) ||
			   !conv(xx[i].yv,&yd,&iy)) {
				conn = 0;
				continue;
			}
			if(mode!=0) {
				if(conn != 0)
					vec(ix,iy);
				else
					move(ix,iy);
				conn = 1;
			}
			conn &= symbol(ix,iy,xx[i].lblptr);
		}
	}
	pen(modes[1]);
}

int
conv(float xv, struct xy *p, int *ip){
	long ix;
	ix = p->xa*(*p->xf)(xv*p->xmult) + p->xb;
	if(ix<p->xbot || ix>p->xtop)
		return(0);
	*ip = ix;
	return(1);
}

int
getfloat(float *p){
	int i;

	i = scanf("%f",p);
	return(i==1);
}

int
getstring(void){
	int i;
	char junk[20];
	i = scanf("%1s",labbuf);
	if(i==-1)
		return(-1);
	switch(*labbuf) {
	default:
		if(!isdigit(*labbuf)) {
			ungetc(*labbuf,stdin);
			i = scanf("%s",labbuf);
			break;
		}
	case '.':
	case '+':
	case '-':
		ungetc(*labbuf,stdin);
		return(0);
	case '"':
		i = scanf("%[^\"\n]",labbuf);
		scanf("%[\"]",junk);
		break;
	}
	if(i==-1)
		return(-1);
	return(strlen(labbuf));
}

int
symbol(int ix, int iy, int k){

	if(symbf==0&&k<0) {
		if(mode==0)
			point(ix,iy);
		return(1);
	} 
	else {
		move(ix,iy);
		text(k>=0?labels+k:plotsymb);
		move(ix,iy);
		return(!brkf|k<0);
	}
}

void title(void){
	char buf[BSIZ+100];
	buf[0] = ' ';
	buf[1] = ' ';
	buf[2] = ' ';
	strcpy(buf+3,titlebuf);
	if(erasf&&gridf) {
		axlab('x',&xd,buf);
		strcat(buf,",");
		axlab('y',&yd,buf);
	}
	move(xd.xbot,yd.xbot-60);
	text(buf);
}

void axlab(char c, struct xy *p, char *b){
	char *dir;
	dir = p->xlb<p->xub? "<=": ">=";
	sprintf(b+strlen(b), " %g %s %c%s %s %g", p->xlb/p->xmult,
		dir, c, p->xf==log10?" (log)":"", dir, p->xub/p->xmult);
}

void badarg(void){
	fprintf(stderr,"graph: error in arguments\n");
	closepl();
	exits("bad arg");
}
