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

int	nnum	= 0;	/* number of saved numbers */
double	num[MAXNUM];

int	just;		/* current justification mode (RJUST, etc.) */
int	sizeop;		/* current optional operator for size change */
double	sizexpr;	/* current size change expression */

void savenum(int n, double f)	/* save f in num[n] */
{
	num[n] = f;
	nnum = n+1;
	if (nnum >= MAXNUM)
		ERROR "too many numbers" WARNING;
}

void setjust(int j)
{
	just |= j;
}

void setsize(int op, double expr)
{
	sizeop = op;
	sizexpr = expr;
}

char *tostring(char *s)
{
	register char *p;

	p = malloc(strlen(s)+1);
	if (p == NULL)
		ERROR "out of space in tostring on %s", s FATAL;
	strcpy(p, s);
	return(p);
}

void range(Point pt)	/* update the range for point pt */
{
	Obj *p = pt.obj;

	if (!(p->coord & XFLAG)) {
		if (pt.x > p->pt1.x)
			p->pt1.x = pt.x;
		if (pt.x < p->pt.x)
			p->pt.x = pt.x;
	}
	if (!(p->coord & YFLAG)) {
		if (pt.y > p->pt1.y)
			p->pt1.y = pt.y;
		if (pt.y < p->pt.y)
			p->pt.y = pt.y;
	}
}

void halfrange(Obj *p, int side, double val)	/* record max and min for one direction */
{
	if (!(p->coord&XFLAG) && (side == LEFT || side == RIGHT)) {
		if (val < p->pt.y)
			p->pt.y = val;
		if (val > p->pt1.y)
			p->pt1.y = val;
	} else if (!(p->coord&YFLAG) && (side == TOP || side == BOT)) {
		if (val < p->pt.x)
			p->pt.x = val;
		if (val > p->pt1.x)
			p->pt1.x = val;
	}
}


Obj *lookup(char *s, int inst)	/* find s in objlist, install if inst */
{
	Obj *p;
	int found = 0;

	for (p = objlist; p; p = p->next){
		if (strcmp(s, p->name) == 0) {
			found = 1;
			break;
		}
	}
	if (p == NULL && inst != 0) {
		p = (Obj *) calloc(1, sizeof(Obj));
		if (p == NULL)
			ERROR "out of space in lookup" FATAL;
		p->name = tostring(s);
		p->type = NAME;
		p->pt = ptmax;
		p->pt1 = ptmin;
		p->fval = 0.0;
		p->next = objlist;
		objlist = p;
	}
	dprintf("lookup(%s,%d) = %d\n", s, inst, found);
	return p;
}

double getvar(Obj *p)	/* return value of variable */
{
	return p->fval;
}

double setvar(Obj *p, double f)	/* set value of variable to f */
{
	if (strcmp(p->name, "pointsize") == 0) {	/* kludge */
		pointsize = f;
		ps_set = 1;
	}
	p->type = VARNAME;
	return p->fval = f;
}

Point makepoint(Obj *s, double x, double y)	/* make a Point */
{
	Point p;
	
	dprintf("makepoint: %s, %g,%g\n", s->name, x, y);
	p.obj = s;
	p.x = x;
	p.y = y;
	return p;
}

Attr *makefattr(int type, double fval)	/* set double in attribute */
{
	return makeattr(type, fval, (char *) 0, 0, 0);
}

Attr *makesattr(char *s)		/* make an Attr cell containing s */
{
	Attr *ap = makeattr(STRING, sizexpr, s, just, sizeop);
	just = sizeop = 0;
	sizexpr = 0.0;
	return ap;
}

Attr *makeattr(int type, double fval, char *sval, int just, int op)
{
	Attr *a;

	a = (Attr *) malloc(sizeof(Attr));
	if (a == NULL)
		ERROR "out of space in makeattr" FATAL;
	a->type = type;
	a->fval = fval;
	a->sval = sval;
	a->just = just;
	a->op = op;
	a->next = NULL;
	return a;
}

Attr *addattr(Attr *a1, Attr *ap)	/* add attr ap to end of list a1 */
{
	Attr *p;

	if (a1 == 0)
		return ap;
	if (ap == 0)
		return a1;
	for (p = a1; p->next; p = p->next)
		;
	p->next = ap;
	return a1;
}

void freeattr(Attr *ap)	/* free an attribute list */
{
	Attr *p;

	while (ap) {
		p = ap->next;	/* save next */
		if (ap->sval)
			free(ap->sval);
		free((char *) ap);
		ap = p;
	}
}

char *slprint(Attr *stringlist)	/* print strings from stringlist */
{
	int ntext, n, last_op, last_just;
	double last_fval;
	static char buf[1000];
	Attr *ap;

	buf[0] = '\0';
	last_op = last_just = 0;
	last_fval = 0.0;
	for (ntext = 0, ap = stringlist; ap != NULL; ap = ap->next)
		ntext++;
	sprintf(buf, "box invis wid 0 ht %d*textht", ntext);
	n = strlen(buf);
	for (ap = stringlist; ap != NULL; ap = ap->next) {
		if (ap->op == 0) {	/* propagate last value */
			ap->op = last_op;
			ap->fval = last_fval;
		} else {
			last_op = ap->op;
			last_fval = ap->fval;
		}
		sprintf(buf+n, " \"%s\"", ps_set || ap->op ? sizeit(ap) : ap->sval);
		if (ap->just)
			last_just = ap->just;
		if (last_just)
			strcat(buf+n, juststr(last_just));
		n = strlen(buf);
	}
	return buf;	/* watch it:  static */
}

char *juststr(int j)	/* convert RJUST, etc., into string */
{
	static char buf[50];

	buf[0] = '\0';
	if (j & RJUST)
		strcat(buf, " rjust");
	if (j & LJUST)
		strcat(buf, " ljust");
	if (j & ABOVE)
		strcat(buf, " above");
	if (j & BELOW)
		strcat(buf, " below");
	return buf;	/* watch it:  static */
}

char *sprntf(char *s, Attr *ap)	/* sprintf(s, attrlist ap) */
{
	char buf[500];
	int n;
	Attr *p;

	for (n = 0, p = ap; p; p = p->next)
		n++;
	switch (n) {
	case 0:
		return s;
	case 1:
		sprintf(buf, s, ap->fval);
		break;
	case 2:
		sprintf(buf, s, ap->fval, ap->next->fval);
		break;
	case 3:
		sprintf(buf, s, ap->fval, ap->next->fval, ap->next->next->fval);
		break;
	case 5:
		ERROR "too many expressions in sprintf" WARNING;
	case 4:
		sprintf(buf, s, ap->fval, ap->next->fval, ap->next->next->fval, ap->next->next->next->fval);
		break;
	}
	free(s);
	return tostring(buf);
}
