/*--------------------------------------------------------------*/
/*	tek4010/14 Driver 1.0 , for GLE V3.0		*/
/*---------------------------------------------------------------------------*/
#include "all.h"
#include <math.h>
#include "core.h"
#include "mygraph.h"
#include "mydev.h"
#define GS 29
#define FF 12
#define MAXX 1023
#define MAXY 767
int ingraphmode;
extern struct gmodel g;
/*---------------------------------------------------------------------------*/
#define pi 3.141592653
#define true (!false)
#define BLACKANDWHITE 1
#define ESC 27
#define false 0
#define dbg if ((gle_debug & 64)>0)
#define stop if ((gle_debug & 128)>0) return
extern int gle_debug;
int incap=true;
int getch(void);
/*---------------------------------------------------------------------------*/
/* The global variables for the PC screen driver */
/*-----------------------------------------------*/

int i,l,j,ix,iy;
double f;


#define gerr() i = graphresult(); if (i!=0) printf("Graph error: %s \n",grapherrormsg(i));
#define xsizecm 21.0
#define ysizecm 18.0
#define sx(v) ( (int) ((v) * d_xscale))
#define sy(v) ( ((int) ((v) * d_yscale)))
#define rx(v) ( (int) ((v) * d_xscale))
#define ry(v) ( ((int) ((v) * d_yscale)))

double d_scale, d_xscale, d_yscale;
int d_graphmode;
int d_fillstyle=1,d_fillcolor;
int d_lstyle,d_lwidth;
int d_maxy;
char outstr[400];

d_devcmd(char *s)
{}
dxy(double x, double y, int *dx, int *dy)
{
	static double fx,fy;
	g_dev(x,y,&fx,&fy);
	*dx = sx(fx);
	*dy = sy(fy);
}
rxy(double x, double y, int *dx, int *dy)
{
	static double fx,fy,zx,zy;
	g_dev(x,y,&fx,&fy);
	g_dev(0.0,0.0,&zx,&zy);
	*dx = (int) ( (fx-zx) * d_xscale);
	*dy = (int) ( (fy-zy) * d_yscale);
}
/*---------------------------------------------------------------------------*/
d_dfont(char *c)
{
	/* only used for the DFONT driver which builds fonts */
}
/*---------------------------------------------------------------------------*/
static char lastline[80];
d_message(char *s)
{
	static int single_step;
	int oldcolor,oldx,oldy;
	if (ingraphmode) {
		textmode();
		printf("%s\n",s);
		graphmode();
	} else {
		w_message(s);
	}
}
/*---------------------------------------------------------------------------*/
d_source(char *s)
{
	s=s;
}
/*---------------------------------------------------------------------------*/
d_get_type(char *t)
{
	strcpy(t,"INTERACTIVE, REGIS, VAX");
}
/*---------------------------------------------------------------------------*/
d_set_path(int onoff)
{}
/*---------------------------------------------------------------------------*/
d_newpath()
{
}
/*---------------------------------------------------------------------------*/
d_open(double width, double height)
{

	graphmode();
	ingraphmode = true;

	/* Get largest rectangle we can fit on the screen */
	d_scale = xsizecm / width;
	f = ysizecm / height;
	if (f<d_scale) d_scale = f;

	d_xscale = d_scale * getmaxx() / xsizecm; /* Device Scale X, Device Scale y */
	d_yscale = d_scale * (getmaxy()-20) / ysizecm;
	d_maxy = getmaxy()-20;
	g.userwidth = width;
	g.userheight = height;
}
/*---------------------------------------------------------------------------*/
d_tidyup()
{
	textmode();
}
d_close()
{

	strcat(outstr,"\x1d");
	tekxy(0,0,true);
	g_flush();
	printf("%c Press <return> to continue ",31);
	text_inkey();
	textmode();
}
/*---------------------------------------------------------------------------*/
d_set_line_cap(int i)
{
	i++;
}
/*---------------------------------------------------------------------------*/
d_set_line_join(int i)
{
	i++;
}
/*---------------------------------------------------------------------------*/
d_set_line_miterlimit(double d)
{
	i++;
}
/*---------------------------------------------------------------------------*/
d_set_line_width(double w)
{
}
/*---------------------------------------------------------------------------*/
d_set_line_styled(double dd)
{}
d_set_line_style(char *s)
{
	d_lstyle = 2;
	if (strcmp(s,"")==0) d_lstyle = 1;
	if (strcmp(s,"1")==0) d_lstyle = 1;
}
/*---------------------------------------------------------------------------*/
d_fill()
{
}
/*---------------------------------------------------------------------------*/
d_fill_ary(int nwk,double (*wkx)[],double (*wky)[])
{
	int i;
/*	fprintf(psfile,"%g %g moveto \n",(*wkx)[0],(*wky)[0]);
	for (i=1;i<nwk;i++)
		fprintf(psfile,"%g %g l \n",(*wkx)[i],(*wky)[i]);
*/
}
d_line_ary(int nwk,double (*wkx)[],double (*wky)[])
{
	int i;
/*
	dxy( (*wkx)[0], (*wky)[0], &ix, &iy);
	moveto(ix,iy);
	for (i=1;i<nwk;i++) {
		dxy( (*wkx)[i], (*wky)[i], &ix, &iy);
		lineto(ix,iy);
	}
*/
}
/*---------------------------------------------------------------------------*/
d_stroke()
{
}
/*---------------------------------------------------------------------------*/
d_clip()
{
}
/*---------------------------------------------------------------------------*/
d_set_matrix(double newmat[3][3])
{
}
/*---------------------------------------------------------------------------*/
d_move(double zx,double zy)
{
}
/*---------------------------------------------------------------------------*/
d_reverse() 	/* reverse the order of stuff in the current path */
{
}
/*---------------------------------------------------------------------------*/
d_closepath()
{
	g_line(g.closex,g.closey);
}
/*---------------------------------------------------------------------------*/
d_line(double zx,double zy)
{
	static int ux,uy;
	char s1[40],s2[40];
	if (g.xinline==false) {
		dxy(g.curx,g.cury,&ux,&uy);
		strcat(outstr,"\x1d");
		tekxy(ux,uy,true);
	}
	dxy(zx,zy,&ix,&iy);
	tekxy(ix,iy,false);
	if (strlen(outstr)>50) d_flush();
}
/*---------------------------------------------------------------------------*/
typedef struct {char h,l;} tekpoint;
tekpoint lastx,lasty;
tekxy(int x,int y, int ismove)
{
	char *s;
	tekpoint nx,ny;

	if (x<0) x = 0;
	if (x>MAXX) x = MAXX;
	if (y<0) y = 0;
	if (y>MAXY) y = MAXY;
	tekpnt(x,&nx); tekpnt(y,&ny);
	if (ismove) reset_tekpnt();

	s = strlen(outstr) + outstr;
	if (lasty.h!=ny.h) 			*s++ = (0x20 | ny.h);
	if (lasty.l!=ny.l  || lastx.h!=nx.h) 	*s++ = (0x60 | ny.l);
	if (lastx.h!=nx.h) 			*s++ = (0x20 | nx.h);
						*s++ = (0x40 | nx.l);
	*s++ = 0;
	lastx = nx;
	lasty = ny;
}
tekpnt(int x, tekpoint *t)
{
	t->l = x & 0x1f;
	t->h = (x & 0x3e0) >> 5;
}
reset_tekpnt()
{
	lastx.h = -1; lastx.l= -1; lasty.h= -1; lasty.l= -1;
}
/*---------------------------------------------------------------------------*/
d_clear()
{
	double width,height;
	int x1,y1,x2,y2;
	width = g.userwidth;
	height = g.userheight;
	/* now draw bounding box of screen */
	x1 = 0;
	y1 = d_maxy-height*d_yscale;
	x2 = width*d_xscale;
	y2 = d_maxy;
 	printf("%c%c",ESC,FF);
}
/*---------------------------------------------------------------------------*/
d_flush()
{
	printf("%s\n%c",outstr,GS);
	outstr[0] = 0;
	reset_tekpnt();
}
/*---------------------------------------------------------------------------*/
d_arcto(dbl x1,dbl y1,dbl x2,dbl y2,dbl rrr)
{
	df_arcto(x1,y1,x2,y2,rrr);
}
/*---------------------------------------------------------------------------*/
d_arc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
{
	df_arc(r,t1,t2,cx,cy);
}
/*---------------------------------------------------------------------------*/
d_narc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
{
	df_arc(r,t1,t2,cx,cy);
}
/*---------------------------------------------------------------------------*/
d_box_fill(dbl x1, dbl y1, dbl x2, dbl y2)
{
	df_box_fill(x1,y1,x2,y2);
}
d_box_stroke(dbl x1, dbl y1, dbl x2, dbl y2)
{
	df_box_stroke(x1,y1,x2,y2);
}
/*---------------------------------------------------------------------------*/
d_circle_stroke(double zr)
{
	df_circle_stroke(zr);
}
d_circle_fill(double zr)
{
	df_circle_fill(zr);
}
/*---------------------------------------------------------------------------*/
d_bezier(dbl x1,dbl y1,dbl x2,dbl y2,dbl x3,dbl y3)
{
	double ax,bx,cx,ay,by,cy,dist;
	double xxx,yyy,i,t,nstep,x0,y0;
	g_get_xy(&x0,&y0);
	dist = fabs(x3-x0) + fabs(y3-y0);
	nstep = 10;
	if (dist>3) nstep = 20;
	if (dist<.5) nstep = 5;
	if (dist<.3) nstep = 3;
 	if (dist<.1) {
		g_line(x3,y3);
		return;
	}
	cx = (x1-x0)*3;
	bx = (x2-x1)*3-cx;
	ax = x3-x0-cx-bx;
	cy = (y1-y0)*3;
	by = (y2-y1)*3-cy;
	ay = y3-y0-cy-by;
	for (i=0;i<=nstep;i++) {
		t = i/nstep;
		xxx = ax*pow(t,3.0) + bx*t*t + cx*t + x0;
		yyy = ay*pow(t,3.0) + by*t*t + cy*t + y0;
		g_line(xxx,yyy);
	}
}
/*---------------------------------------------------------------------------*/
d_set_color(long f)
{
	int i;
	colortyp  cc;
	cc.l = f;
	i = 0;
	if (cc.b[B_R]>100) i = 4;
	if (cc.b[B_B]>100) i = 1;
	if (cc.b[B_G]>100) i = 2;
/*
	if (cc.b[B_R]>100 && cc.b[B_G]>100 && cc.b[B_B]>100) i = getmaxcolor();
	if (i>getmaxcolor()) i = getmaxcolor();
*/
}
d_set_fill(long f)
{
}
/*---------------------------------------------------------------------------*/
d_beginclip()
{
}
d_endclip()
{
}
struct char_data {float wx,wy,x1,y1,x2,y2; };
int font_get_chardata(struct char_data **cd, int ff, int cc);
/*---------------------------------------------------------------------------*/
d_char(int font, int cc)
{
	static struct char_data cd;
	static int ix,iy,ix1,ix2,iy1,iy2,fz,fzx;
	static int ux,uy;
	static int safnt;
	char ss[2];

	ss[0] = cc;
	ss[1] = 0;
	if (safnt==0) safnt = pass_font("PLSR");
	if (font_get_encoding(font)>2) {
		my_char(font,cc);
		return;
	}
	my_char(safnt,cc);
}
getmaxx()
{
	return MAXX;
}
getmaxy()
{
	return MAXY;
}

char tekopenstr[200],tekclosestr[200];
/* THESE TWO SEQUENCES MAY NEED CHANGING FOR OTHER TEK4014 EMULATORS  */
int inittek;
graphmode()
{
	if (!inittek) tek_initstr();
	ingraphmode = true;
	printf(tekopenstr);
	printf("%c",GS);
}
textmode()
{
	if (!inittek) tek_initstr();
	ingraphmode = false;
	printf(tekclosestr);
}

char *getdclsym(char *sym);
tek_initstr()
{
	char  *s;
	inittek = true;
	s = getdclsym("TEK_OPEN");
	if (strlen(s)==0) s = "\x1b[?38h";
	strcpy(tekopenstr,s);
	s = getdclsym("TEK_CLOSE");
	if (strlen(s)==0) s = "\x1b[?38l";
	strcpy(tekclosestr,s);
}
#ifdef VMS
#include <descrip.h>
char *getdclsym(char *sym)
{
	static char mystr[100],*s;
	int r;
	short teklen=80;
	$DESCRIPTOR(symname,sym);
	$DESCRIPTOR(tekval,mystr);
	symname.dsc$w_length = strlen(sym);
	tekval.dsc$w_length = 80;
	r = lib$get_symbol(&symname,&tekval,&teklen,&1);
	mystr[teklen] = 0;
loop1:	s = strchr(mystr,'^');
	if (s!=NULL) {
		*(s+1) = *(s+1) - 64;
		memmove(s,s+1,strlen(s+1)+1);
		goto loop1;
	}
	return mystr;
}
#else
/* Should add code to read unix symbols here */
char *getdclsym(char *sym)
{
	static char mystr[100],*s;
	int r;
	strcpy(mystr,(char *) getsymbol(sym));
loop1:	s = strchr(mystr,'^');
	if (s!=NULL) {
		*(s+1) = *(s+1) - 64;
		memmove(s,s+1,strlen(s+1)+1);
		goto loop1;
	}
	return mystr;
}
#endif
