#include "all.h"
#include "mygraph.h"
#include "justify.h"
#include "color.h"
/* for key command and gx(), gy() */
extern double graph_x1,graph_y1,graph_x2,graph_y2;  /* in cm */
extern double graph_xmin,graph_ymin,graph_xmax,graph_ymax; /* graph units */
#define BEGINDEF extern
#include "begin.h"
#include <math.h>
#define dbg if ((gle_debug & 64)>0)
#define LARGE_NUM 1E30
char *un_quote(char *ct);
extern int gle_debug;
int doskip(char *s,int *ct);
double get_next_exp(TOKENS tk,int *ntk,int *curtok);
#define kw(ss) if (strcmp(tk[ct],ss)==0)
#define true (!false)
#define false 0
#define skipspace doskip(tk[ct],&ct)
#define tok(n)  (*tk)[n]
#define next_exp (get_next_exp((TOKENS) tk,&ntk,&ct))
#define next_font ((ct+=1),pass_font(tk[ct]))
#define next_marker ((ct+=1),pass_marker(tk[ct]))
#define next_color ((ct+=1),pass_color(tk[ct]))
#define next_fill ((ct+=1),pass_color(tk[ct]))
#define next_str(s)  (ct+=1,strcpy(s,tk[ct]))
#define next_vstr(s)  (ct+=1,mystrcpy(&s,tk[ct]))
#define next_vquote(s) (ct+=1,mystrcpy(&s,un_quote(tk[ct])))
#define next_quote(s) (ct+=1,strcpy(&s,un_quote(tk[ct])))

#define ifer if (erflg)

struct key_struct {
	char lstyle[9];
	long color,fill;
	int marker;
	double msize,lwidth;
	char *descrip;
};
struct key_struct *kd[100];

begin_key(int *pln,long *pcode, int *cp)
{
    int nkd=0;
    double koffsetx=0,koffsety=0,khei=0,zzhei;
    char kpos[34];
    int knobox=0,st;
    int sl,ct,i,ncol,ntmp,np,c,*m,t,d,b;

	g_get_hei(&zzhei);

    begin_init();
    for (;;) {
	st = begin_token(&pcode,cp,pln,srclin,(char *) tk,&ntk,outbuff);
	if (!st) break;
	ct = 1;
	while (ct<=ntk)  {
		skipspace;
	     	kw("OFFSET") {
			koffsetx = next_exp;
			koffsety = next_exp;
		}
	else 	kw("NOBOX") 	knobox = true;
	else 	kw("HEI")	khei = next_exp;
	else 	kw("POSITION") next_str(kpos);
	else 	kw("POS") next_str(kpos);
	else 	kw("JUSTIFY") next_str(kpos);
	else {
		if (ct==1) {
			nkd++;
			kd[nkd] = myallocz(sizeof(*kd[1]));
		}
		if (nkd==0) return;
		kw("TEXT")  	next_vquote(kd[nkd]->descrip);
	 else 	kw("MARKER")  	{kd[nkd]->marker = next_marker;
		}
	 else 	kw("MSIZE")	kd[nkd]->msize = next_exp;
	 else 	kw("MSCALE")	kd[nkd]->msize = (next_exp) * zzhei;
	 else 	kw("COLOR") 	kd[nkd]->color = next_color;
	 else 	kw("FILL") 	kd[nkd]->fill = next_fill;
	 else 	kw("LSTYLE") 	next_str(kd[nkd]->lstyle);
	 else 	kw("LINE") 	strcpy(kd[nkd]->lstyle,"1");
	 else 	kw("LWIDTH") 	kd[nkd]->lwidth = next_exp;
	 else gprint("Unrecognised KEY sub command {%s} %d \n ",tk[ct],ct);
	}
	ct++;
	}
	if (!begin_next_line(pcode,cp)) break;
    }
draw_it:
	draw_key(nkd,koffsetx,koffsety,kpos,khei,knobox);
}
draw_key(int nkd, double koffsetx, double koffsety, char *kpos
	,double khei, int knobox)
{
	int kl=0,km=0,kf=0;
	int i;
	long old_color;
	double cx,cy,maxwid=0,z;
	double ox,oy,bl,br,bu,bd,savex,savey;
	double sx=0,sy=0;
	double cr,savelw,midx,midy;

	g_get_xy(&savex,&savey);
	if (nkd==0) return;
	if (khei==0) g_get_hei(&khei);
	cr = 1.2*khei;
	for (i=nkd;i>=1;i--) {
		if (kd[i]->lstyle[0]==0) if (kd[i]->lwidth>0)
			kd[i]->lstyle[0]='1';
		if (kd[i]->lstyle[0]!=0) kl = true;
		if (kd[i]->lwidth>0) kl = true;
		if (kd[i]->marker!=0) km = true;
		if (kd[i]->fill!=0) kf = true;
	}

	g_set_hei(khei);
	for (i=nkd;i>=1;i--) {
		if (kd[i]->descrip!=NULL) {
			g_measure(kd[i]->descrip,&bl,&br,&bu,&bd);
			if (maxwid < br) maxwid = br;
		}
	}
	sx = 0;
	if (kl) sx = sx + 2*cr;
	if (km) sx = sx + 1.5*cr;
	if (kf) sx = sx + 1.3*cr;
	sx = sx + maxwid;
	sx = sx + 1.2*cr;
	sy = nkd*cr + 1.2*cr-.3*khei;
	if (koffsetx==0 && koffsety==0) {
	  midx = graph_x1 + (graph_x2-graph_x1)/2;
  	  midy = graph_y1 + (graph_y2-graph_y1)/2;
	  if (strcmp(kpos,"TL")==0) {ox = graph_x1;oy = graph_y2-sy;}
	  else if (strcmp(kpos,"BL")==0) {ox = graph_x1; oy = graph_y1;}
	  else if (strcmp(kpos,"BR")==0) {ox = graph_x2-sx;oy = graph_y1;}
	  else if (strcmp(kpos,"TR")==0) {ox = graph_x2-sx; oy = graph_y2-sy;}
	  else if (strcmp(kpos,"TC")==0) {ox = midx-sx/2; oy = graph_y2-sy;}
	  else if (strcmp(kpos,"BC")==0) {ox = midx-sx/2; oy = graph_y1;}
	  else if (strcmp(kpos,"RC")==0) {ox = graph_x2-sx; oy = midy-sy/2;}
	  else if (strcmp(kpos,"LC")==0) {ox = graph_x1; oy = midy-sy/2;}
	  else if (strcmp(kpos,"CC")==0) {ox = midx-sx/2; oy = midy-sy/2;}
	  else {
		if (strlen(kpos)>0) gprint("Expecting POS BL,BR,TR or TL \n");
		ox = graph_x2-sx; oy = graph_y2-sy;
	  }
	} else {
		g_get_xy(&ox,&oy);
		ox = ox + koffsetx;
		oy = oy + koffsety;
	}
	g_get_color(&old_color);
	g_set_fill(COLOR_WHITE);
	if (!knobox) g_box_fill(ox,oy,ox+sx,oy+sy);

	g_set_color(old_color);
	for (i=nkd; i>=1; i--)  {
		g_move(ox+.6*cr,oy+.6*cr+cr*(nkd-i));
		g_get_xy(&cx,&cy);
		if (kd[i]->color!=0) g_set_color(kd[i]->color);
		if (km) {
			g_rmove(cr/2,khei*.35);
			z = kd[i]->msize;
			if (z==0) z = khei;
			if (kd[i]->marker!=0) g_marker(kd[i]->marker,z);
			g_rmove(cr,-khei*.35);
		}
		if (kl) {
			g_set_line_style(kd[i]->lstyle);
			g_get_line_width(&savelw);
			g_set_line_width(kd[i]->lwidth);
			g_rmove(0.0,cr*.3);
			if (kd[i]->lstyle[0]==0) g_rmove(1.5*cr,0.0);
			else g_rline(1.5*cr,0.0);
			g_rmove(cr/2,-cr*.3);
			g_set_line_style("1");
			g_set_line_width(savelw);
		}
		if (kf) {
			if (kd[i]->fill!=0) {
				g_set_fill(kd[i]->fill);
				g_get_xy(&cx,&cy);
				g_box_fill(cx,cy,cx+cr*.7,cy+cr*.66);
				g_box_stroke(cx,cy,cx+cr*.7,cy+cr*.66);
			}
			g_rmove(1.3*cr,0.0);
		}
		g_get_xy(&cx,&cy);
		if (kd[i]->color!=0) g_set_color(old_color);
		g_set_just(JUST_LEFT);
		if (kd[i]->descrip!=NULL) g_text(kd[i]->descrip);
	}
	if (!knobox) g_box_stroke(ox,oy,ox+sx,oy+sy);
	g_move(savex,savey);
}

