#include "all.h"
#include "mygraph.h"
#include <math.h>
int text_gprint(int32 *in,int ilen);
int fftext_block(uchar *s,double width,int justify);
char *fontdir(char *s);
char *gledir(char *fname);
void  font_load(void);
void font_init(void);
int g_get_font(int *i);
int do_prim(uchar **in,int32 *out,int *lout);  /*  \frac{text}{text} */

#define true (!false)
#define false 0
#define dbg if ((gle_debug & 32)>0)
extern int gle_debug;
/* typedef char unsigned uchar; */

/*  FONT.DAT contains  names of fonts, and indexes for each font, and
	names of metric, vector and bitmap files
	This enables fonts to be referred to by number, as their index will
	not change */

#include "font.h"

char *font_getname(int i)
{
	return fnt[i].name;
}
char_bbox(int ff,int cc,double *xx1, double *yy1, double *xx2, double *yy2)
{
	if (nfnt==0) font_load();
	if (fnt[ff].chr==NULL) font_load_metric(ff);
	if ( (fnt[ff].chr) != NULL) {
		*xx1 = ((*(fnt[ff].chr))[cc].x1);
		*yy1 = ((*(fnt[ff].chr))[cc].y1);
		*xx2 = ((*(fnt[ff].chr))[cc].x2);
		*yy2 = ((*(fnt[ff].chr))[cc].y2);
	} else {
		*xx1 = 0;
		*xx2 = 0;
		*yy1 = 0;
		*yy2 = 0;
	}

}
font_get_chardata(struct char_data *cd,int ff,int cc)
{
	if ( (fnt[ff].chr) != NULL) {
		cd->x1 = ((*(fnt[ff].chr))[cc].x1);
		cd->y1 = ((*(fnt[ff].chr))[cc].y1);
		cd->x2 = ((*(fnt[ff].chr))[cc].x2);
		cd->y2 = ((*(fnt[ff].chr))[cc].y2);
	} else {
		cd->x1 = 0;
		cd->y1 = 0;
		cd->x2 = 0;
		cd->y2 = 0;
	}

}
int smallf = false;
void font_simple(void)
{
	smallf = true;
}
void font_load(void)
{
	FILE *fptr;
	uchar inbuff[200];
	char fname[80];
	char nbuf[80];
	int n;
	char *s;
	char *cp;
	char *ns;

	strcpy(fname,fontdir("font.dat"));
	fptr = fopen(fname,"r");
	if (fptr==0) {
		gprint("Unable to open font.dat file {%s} \n",fname);
		perror("Reason ");
	}
/* font_load() */
	for (fgets(SC inbuff,200,fptr);!feof(fptr);fgets(SC inbuff,200,fptr)) {
		s = strchr(SC inbuff,'!');
		if (s!=NULL) *s=0;
		s = strtok(SC inbuff," 	,");
		if (s!=NULL) if (*s!='\n') {
		 ncpy(nbuf,s,30);
		 ns = strtok(0," 	,");
		 n = atoi(ns);
		 mystrcpy(&fnt[n].name,nbuf);
		 for (cp = fnt[n].name; *cp!=0; cp++)
	 		*cp = toupper(*cp);
		 s = strtok(0," 	,");
		 if (smallf) mystrcpy(&fnt[n].file_metric,"pstr.fmt");
		 if (s!=0) mystrcpy(&fnt[n].file_metric,s);
		 s = strtok(0," 	,");
		 if (smallf) mystrcpy(&fnt[n].file_vector,"plsr.fve");
		 else if (s!=0) mystrcpy(&fnt[n].file_vector,s);
		 s = strtok(0," 	,");
		 if (s!=0) mystrcpy(&fnt[n].file_bitmap,s);
		 s = strtok(0,"\n");
		 if (s!=0) mystrcpy(&fnt[n].file_bitmap,s);
		 if (nfnt<n) nfnt = n;
		}
	}
	fclose(fptr);

	if (fnt[n].scale==0) fnt[n].scale = 1000.0;
}

FILE *fmt;

font_set(char *s)
{}

font_file_vector(int ff,char *s)
{
	if (nfnt==0) font_load();
	strcpy(s,fnt[ff].file_vector);
}
void plotter_fonts(void)
{
	int i;
	if (nfnt==0) font_load();
	for (i=1;i<9;i++) {
		freefont(i);
		fnt[i].file_vector = "plsr.fve";
		fnt[i].file_metric = "plsr.fmt";
	}
	for (i=82;i<86;i++) {
		fnt[i].file_vector = "plsr.fve";
		fnt[i].file_metric = "plsr.fmt";
	}
}
void font_replace_vector(int ff) /* replace vector file with substitue font */
{
	if (nfnt==0) font_load();
	myfree(fnt[ff].file_vector);
	fnt[ff].file_vector = sdup(fnt[1].file_vector);
}
font_get_encoding(int ff)
{
	if (nfnt==0) font_load();
	if (fnt[ff].chr==NULL) font_load_metric(ff);
	return fnt[ff].encoding;
}
show_font(void)
{
	printf("Font name 1 {%s} 2  {%s} \n",fnt[1].name,fnt[2].name);
}
/* Picks a font at random and frees it, checks to see if enough freemem */
freeafont()
{
	int i,j;
	struct char_datax (*cdx)[256];
	if (coreleft()>75000l) return;
	freeavec();
	if (coreleft()>60000l) return;
	for (i=99;i>0;i--) if (fnt[i].chr != NULL) {
		freefont(i);
		if (coreleft()>60000l) break;
	}
}
void freefont(int i)
{
	int j;
	struct char_datax (*cdx)[256];
	if ( (fnt[i].chr != NULL) && (fnt[i].chrx != NULL) ) {
		myfree(fnt[i].chr);
		fnt[i].chr = NULL;
		cdx = fnt[i].chrx;
		for (j=1;j<255;j++) {
		  if ((*cdx)[j].kern != NULL) myfree((*cdx)[j].kern);
		  if ((*cdx)[j].lig != NULL) myfree((*cdx)[j].lig);
		  if ((*cdx)[j].lrep != NULL) myfree((*cdx)[j].lrep);
		  if ((*cdx)[j].krep != NULL) myfree((*cdx)[j].krep);
		}
		myfree(fnt[i].chrx);
		fnt[i].chrx = NULL;
	}
}
font_load_metric(int ff)
{
	struct char_data (*cd)[256];
	struct char_datax (*cdx)[256];
	int ll,c,i;
	double f;

	/* return; */
	if (ff==0) {
		gprint("There is no zero font, errorloading font \n");
		return;
	}
	if (fnt[ff].chr!=NULL) return;
	if (nfnt==0) font_load();
	dbg printf("Load font number %d \n",ff);
	dbg gprint("Have loaded font.dat \n");
	if (fnt[ff].chr==NULL) {
		if (coreleft()<60000l) freeafont();
		dbg gprint("Loading metrics now \n");
		fnt[ff].chr = myallocz(sizeof(*fnt[1].chr));
		fnt[ff].chrx = myallocz(sizeof(*fnt[1].chrx));
		cd = fnt[ff].chr;
		cdx = fnt[ff].chrx;

#ifdef unix
		fmt = fopen(fontdir(fnt[ff].file_metric),"r");
#else
		fmt = fopen(fontdir(fnt[ff].file_metric),"rb");
#endif
		if (fmt==NULL) {
			gprint("(Warning) Font Metric not found [%d] (%s), Spacing wrong \n"
				,ff,fnt[ff].file_metric);
			myfree(fnt[ff].file_metric);
			fnt[ff].file_metric = sdup(fnt[1].file_metric);
#ifdef unix
			fmt = fopen(fontdir(fnt[1].file_metric),"r");
#else
			fmt = fopen(fontdir(fnt[1].file_metric),"rb");
#endif
			if (fmt==NULL) {
				printf("Couldn't open {%s} \n",fontdir(fnt[1].file_metric));
				gle_abort("Can't open font file \n");
			}
		}

		/* reads in font data */
		fread(&fnt[ff].encoding,4,16,fmt);

		dbg gprint("Encoding %d  slant %f,  box %f %f %f %f \n"
			,fnt[ff].encoding,fnt[ff].slant,fnt[ff].fx1
			,fnt[ff].fy1,fnt[ff].fx2,fnt[ff].fy2);

		fread(cd,sizeof(*cd),1,fmt);


		while (c=fgetc(fmt)) {
			ll = fgetc(fmt);
			get_str((char **) &(*cdx)[c].lig,ll,fmt);
			get_str((char **) &(*cdx)[c].lrep,ll,fmt);
			ll = fgetc(fmt);
			get_str((char **) &(*cdx)[c].kern,ll,fmt);
			get_str((char **) &(*cdx)[c].krep,8*ll,fmt);
			/* f = (*((*cdx)[c].krep+(0))).x;
			 gprint("kern char %d,  %f \n",c,f);
			*/
		}
		fclose(fmt);

	}
}

char_lig(int p_fnt,uchar *c1, int c2)
{
	static struct char_datax (*cdx)[256];
	static uchar *r,*l;
	int a;

	cdx = fnt[p_fnt].chrx;
	l = (*cdx)[*c1].lig;
	if (l==NULL) {
		return 0;
	}
	r = UC strchr(SC l,c2);
	if (r!=NULL) {
		dbg gprint("font p_fnt %d Lig pos %d \n ",p_fnt,r-l);
		*c1 = * (((*cdx)[*c1].lrep ) + (r-l)) ;
		return *c1;
	} else return 0;
}
char_kern(int p_fnt,int c1, int c2, float *w)
{
	static struct char_datax (*cdx)[256];
	static uchar *r,*k;

	cdx = fnt[p_fnt].chrx;
	k = (*cdx)[c1].kern;
	if (k==NULL) {
		*w = 0;
		return;
	}
	r = UC strchr(SC k,c2);
	if (r!=NULL) {
		*w = (*((*cdx)[c1].krep+(r-k))).x;
	} else
		*w = 0;
}
get_str(char **s,int l,FILE *fmt)
{
	if (l==0) return;
	if (l+1==0) gprint("error -1 in get_str \n");
	*s = myallocn(1,l+1);
	fread(*s,1,l,fmt);
}














