#include <u.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include "grap.h"
#include "y.tab.h"

double	margin	= MARGIN;	/* extra space around edges */
extern	double	frame_ht, frame_wid, ticklen;
extern int just, sizeop, tick_dir;
extern double sizexpr, lab_up, lab_rt;

char	graphname[50] = "Graph";
char	graphpos[200] = "";

void print(void)	/* arrange final output */
{
	FILE *fd;
	Obj *p, *dfp;
	int c;
	double dx, dy, xfac, yfac;

	if (tfd != NULL) {
		fclose(tfd);	/* end the temp file */
		tfd = stdout;
	}

	if ((p=lookup("margin",0)) != NULL)
		margin = p->fval;
	if (frame_ht < 0)	/* wasn't set explicitly, so use default */
		frame_ht = getvar(lookup("frameht", 0));
	if (frame_wid < 0)
		frame_wid = getvar(lookup("framewid", 0));
	dfp = NULL;
	for (p = objlist; p; p = p->next) {
		dprintf("print: name = <%s>, type = %d\n", p->name, p->type);
		if (p->type == NAME) {
			Point pt, pt1;	
			pt = p->pt;
			pt1 = p->pt1;
			fprintf(tfd, "\t# %s %g .. %g, %g .. %g\n",
				p->name, pt.x, pt1.x, pt.y, pt1.y);
			if (p->log & XFLAG) {
				if (pt.x <= 0.0)
					ERROR "can't take log of x coord %g", pt.x FATAL;
				logit(pt.x);
				logit(pt1.x);
			}
			if (p->log & YFLAG) {
				if (pt.y <= 0.0)
					ERROR "can't take log of y coord %g", pt.y FATAL;
				logit(pt.y);
				logit(pt1.y);
			}
			if (!(p->coord & XFLAG)) {
				dx = pt1.x - pt.x;
				pt.x -= margin * dx;
				pt1.x += margin * dx;
			}
			if (!(p->coord & YFLAG)) {
				dy = pt1.y - pt.y;
				pt.y -= margin * dy;
				pt1.y += margin * dy;
			}
			if (autoticks && strcmp(p->name, dflt_coord) == 0) {
				p->pt = pt;
				p->pt1 = pt1;
				if (p->log & XFLAG) {
					p->pt.x = pow(10.0, pt.x);
					p->pt1.x = pow(10.0, pt1.x);
				}
				if (p->log & YFLAG) {
					p->pt.y = pow(10.0, pt.y);
					p->pt1.y = pow(10.0, pt1.y);
				}
				dfp = setauto();
			}		
			dx = pt1.x - pt.x;
			dy = pt1.y - pt.y;
			xfac = dx > 0 ? frame_wid/dx : frame_wid/2;
			yfac = dy > 0 ? frame_ht/dy : frame_ht/2;

			fprintf(tfd, "define xy_%s @ ", p->name);
			if (dx > 0)
				fprintf(tfd, "\t(($1)-(%g))*%g", pt.x, xfac);
			else
				fprintf(tfd, "\t%g", xfac);
			if (dy > 0)
				fprintf(tfd, ", (($2)-(%g))*%g @\n", pt.y, yfac);
			else
				fprintf(tfd, ", %g @\n", yfac);
			fprintf(tfd, "define x_%s @ ", p->name);
			if (dx > 0)
				fprintf(tfd, "\t(($1)-(%g))*%g @\n", pt.x, xfac);
			else
				fprintf(tfd, "\t%g @\n", xfac);
			fprintf(tfd, "define y_%s @ ", p->name);
			if (dy > 0)
				fprintf(tfd, "\t(($1)-(%g))*%g @\n", pt.y, yfac);
			else
				fprintf(tfd, "\t%g @\n", yfac);
		}
	}
	if (codegen)
		frame();
	if (codegen && autoticks && dfp)
		do_autoticks(dfp);

	if ((fd = fopen(tempfile, "r")) != NULL) {
		while ((c = getc(fd)) != EOF)
			putc(c, tfd);
		fclose(fd);
	}
	tfd = NULL;
}

void endstat(void)	/* clean up after each statement */
{

	just = sizeop = 0;
	lab_up = lab_rt = 0.0;
	sizexpr = 0.0;
	nnum = 0;
	ntick = 0;
	tside = 0;
	tick_dir = OUT;
	ticklen = TICKLEN;
}

void graph(char *s)	/* graph statement */
{
	char *p, *os;
	int c;

	if (codegen) {
		fprintf(stdout, "%s: [\n", graphname);
		print();	/* pump out previous graph */
		fprintf(stdout, "\n] %s\n", graphpos);
		reset();
	}
	if (s) {
		dprintf("into graph with <%s>\n", s);
		opentemp();
		os = s;
		while ((c = *s) == ' ' || c == '\t')
			s++;
		if (c == '\0')
			ERROR "no name on graph statement" WARNING;
		if (!isupper((uchar)s[0]))
			ERROR "graph name %s must be capitalized", s WARNING;
		for (p=graphname; (c = *s) != ' ' && c != '\t' && c != '\0'; )
			*p++ = *s++;
		*p = '\0';
		strcpy(graphpos, s);
		dprintf("graphname = <%s>, graphpos = <%s>\n", graphname, graphpos);
		free(os);
	}
}

void setup(void)		/* done at each .G1 */
{
	static int firstG1 = 0;

	reset();
	opentemp();
	frame_ht = frame_wid = -1;	/* reset in frame() */
	ticklen = getvar(lookup("ticklen", 0));
	if (firstG1++ == 0)
		do_first();
	codegen = synerr = 0;
	strcpy(graphname, "Graph");
	strcpy(graphpos, "");
}

void do_first(void)	/* done at first .G1:  definitions, etc. */
{
	extern int lib;
	extern char *lib_defines;
	static char buf[100], buf1[100];	/* static because pbstr uses them */
	FILE *fp;
	extern int getpid(void);

	snprintf(buf, sizeof buf, "define pid /%d/\n", getpid());
	pbstr(buf);	
	if (lib != 0) {
		if ((fp = fopen(lib_defines, "r")) != NULL) {
			snprintf(buf1, sizeof buf, "copy \"%s\"\n", lib_defines);
			pbstr(buf1);
			fclose(fp);
		} else {
			fprintf(stderr, "grap warning: can't open %s\n", lib_defines);
		}
	}
}

void reset(void)		/* done at each "graph ..." statement */
{
	Obj *p, *np, *deflist;
	extern int tlist, toffside, autodir;

	curr_coord = dflt_coord;
	ncoord = auto_x = 0;
	autoticks = LEFT|BOT;
	autodir = 0;
	tside = tlist = toffside = 0;
	tick_dir = OUT;
	margin = MARGIN;
	deflist = NULL;
	for (p = objlist; p; p = np) {
		np = p->next;
		if (p->type == DEFNAME || p->type == VARNAME) {
			p->next = deflist;
			deflist = p;
		} else {
			free(p->name);
			freeattr(p->attr);
			free((char *) p);
		}
	}
	objlist = deflist;
}

void opentemp(void)
{
	if (tfd != NULL)
		fclose(tfd);
	if (tfd != stdout) {
		if (tfd != NULL)
			fclose(tfd);
		if ((tfd = fopen(tempfile, "w")) == NULL) {
			fprintf(stderr, "grap: can't open %s\n", tempfile);
			exit(1);
		}
  	}
}
