/*
 * Copyright 1988 Anant Agarwal
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations about the suitability of this software
 * for any purpose.  It is provided "as is" without express or implied 
 * warranty.
 *
 * Author:  Anant Agarwal, MIT Laboratory for Computer Science
 */

#include <strings.h>	
#include <stdio.h>
#include <math.h>
#include "plotio.h"
#include "defs.h"
#include "structs.h"
#include "plot.h"

extern double getdegrees(), atan(), charheight(),charwidth(),log10(),mylog();

private double keypos[PAIR];
	/* stores top left corner of key */
private double iconsize;
	/*stores length of icon which is total symbol+line length in points*/

private double LocalKeyMul;
static boolean LinTyp;
printkey()
{
int c=0;/* counts curve number */
int k=0;/* counts the lines in the key */
double dtmp;

	keypos[xpt] = graph.keypos[xpt];/* top left hand corner */
	keypos[ypt] = graph.keypos[ypt];
	LinTyp = FALSE;
	switch (graph.key) /* assign iconsize */
	{
		case ksymbol: iconsize = 
		    CMPT * icontotext + CMPT * charwidth(graph.font); break;
		case ktype: iconsize = 
		    CMPT * icontotext + CMPT * keylinewidth; 
		    LinTyp = TRUE; break;
		case kboth: iconsize = 
		    CMPT * icontotext + CMPT * keylinewidth + 
			2.0 * CMPT * charwidth(graph.font); break;
	}

	   /* first adjust keyspacing if histogram */
	LocalKeyMul = keySpacingMul;
	while ((curves[c] != nil) && ((curves[c])->validcurve))
	{
	   if (
		    ((curves[c])->interp == xhistogram)||
		    ((curves[c])->interp == yhistogram)
	      )
	   {
		   if ((CMPT * charheight(graph.keyfont)) <	
				((curves[c])->thick * DefBarThickMul))
		   {
		   	dtmp = keySpacingMul *
				((curves[c])->thick * DefBarThickMul) /
				(CMPT * charheight(graph.keyfont));
		   }
		   if (dtmp > LocalKeyMul) LocalKeyMul = dtmp;
	   }

	   c++;
	}
	
	KeySeqStart(); 
		/* send signal that keys are coming */
		/* This is needed to reset screen constants */
	if (graph.includekey)
	c = 0;
	while ((curves[c] != nil) && ((curves[c])->validcurve))
	{
	 if (*(curves[c])->label&&((curves[c])->include))
	 {
	   switch (graph.key)
	   {
	   case ksymbol:
		/* enter first symbol */
		EnterSymbol(c,k);
		break;
	   case ktype:
		/* enter line */
		EnterLine(c,k);
		break;
	   case kboth:
		/* enter first symbol  */
		EnterSymbol(c,k);
		/* enter line */
		EnterLine(c,k);

		/* enter second symbol */
		InitObjSymbol(obj[curobj], c);
		(obj[curobj])->from[xpt] = keypos[xpt];
		(obj[curobj])->from[ypt] = keypos[ypt];
		scaleobj(obj[curobj]);
		/* now slide it relative to keybox */
		(obj[curobj])->scale = FALSE;
		(obj[curobj])->from[xpt] += 
		     CMPT * keylinewidth + 2.0 * CMPT * charwidth(graph.font);
		(obj[curobj])->from[ypt] += 
		     0 - k * LocalKeyMul * CMPT * charheight(graph.keyfont);
		GetNewObjcurobj(); 
		break;
	   default: printf("Error in entering key, funny keytype \n");
	   }/* end switch */

	   /* enter text */
	   EnterText(c,k);
	   k++;
	 }
	 c++;
	}
}

/* to white out the fill bars */
enterdummy(c,k)
int c,k;
{
	  (obj[curobj])->name = objline;
	  (obj[curobj])->gray = 1.0;/*white*/
	  (obj[curobj])->un.line.thick = (curves[c])->thick;
	  (obj[curobj])->un.line.line = (curves[c])->type;
	  (obj[curobj])->un.line.interp = (curves[c])->interp;
	  (obj[curobj])->scale = TRUE;
	  (obj[curobj])->from[xpt] = keypos[xpt];
  	  (obj[curobj])->from[ypt] = keypos[ypt];
	  (obj[curobj])->un.line.to[xpt] = dummy;
		/* to disable scaleobj errors about neg values */
	  (obj[curobj])->un.line.to[ypt] = dummy;
	  scaleobj(obj[curobj]);
	  (obj[curobj])->scale = FALSE;

	  /* now slide it relative to keybox */
	  (obj[curobj])->from[xpt] += LinTyp ?
		0.0 : (1.0 * CMPT * charwidth(graph.font));
	  (obj[curobj])->from[ypt] -= 
		(k+1) * LocalKeyMul * CMPT * charheight(graph.keyfont) ;
		/* k+1 because this is not actually a new key line */
 	  (obj[curobj])->un.line.to[xpt] = 
		(obj[curobj])->from[xpt] + CMPT * keylinewidth;
	  (obj[curobj])->un.line.to[ypt] = (obj[curobj])->from[ypt];

	  /*slide previous and current lines up a little
	    so that text is centered on gray rectangle */
/*		  (obj[curobj-1])->from[ypt] += 
		LocalKeyMul * CMPT * charheight(graph.keyfont)/2.0;
	  (obj[curobj-1])->un.line.to[ypt] += 
		LocalKeyMul * CMPT * charheight(graph.keyfont)/2.0;
	  (obj[curobj])->from[ypt] += 
		LocalKeyMul * CMPT * charheight(graph.keyfont)/2.0;
	  (obj[curobj])->un.line.to[ypt] += 
		LocalKeyMul * CMPT * charheight(graph.keyfont)/2.0;
*/
	  GetNewObjcurobj(); 
}

EnterLine(c,k)
int c,k;
/*c is curve number*/
/* k is key element number*/
{
pointType *ptPtr;/* current point */
		ptPtr = (curves[c])->fstPtr;
		LinSt(ptPtr->pt[xpt], ptPtr->pt[ypt], (curves[c])->gray, 
			(curves[c])->interp, (curves[c])->type, c);
		/* send start curve sequence, include first pt.*/

		(obj[curobj])->name = objline;
		(obj[curobj])->gray = (curves[c])->gray;
		(obj[curobj])->un.line.thick = (curves[c])->thick;
		(obj[curobj])->un.line.line = (curves[c])->type;
		(obj[curobj])->un.line.interp = (curves[c])->interp;
		(obj[curobj])->scale = TRUE;
		(obj[curobj])->from[xpt] = keypos[xpt];
		(obj[curobj])->from[ypt] = keypos[ypt];
		(obj[curobj])->un.line.to[xpt] = dummy;
			/* to disable scaleobj errors about neg values */
		(obj[curobj])->un.line.to[ypt] = dummy;
		scaleobj(obj[curobj]);
		(obj[curobj])->scale = FALSE;

		/* now slide it relative to keybox */
		/* do not slide if only line type */
		(obj[curobj])->from[xpt] += LinTyp ?
			0.0 : (1.0 * CMPT * charwidth(graph.font));
		(obj[curobj])->from[ypt] -= 
			k * LocalKeyMul * CMPT * charheight(graph.keyfont) ;
		(obj[curobj])->un.line.to[xpt] = 
			(obj[curobj])->from[xpt] + CMPT * keylinewidth;
		(obj[curobj])->un.line.to[ypt] = (obj[curobj])->from[ypt];

		/* adjust thick if it is histogram type */
		if (
		    ((curves[c])->interp == xhistogram)||
		    ((curves[c])->interp == yhistogram)
		   ) (obj[curobj])->un.line.thick = 
		 	(curves[c])->thick * DefBarThickMul;

		GetNewObjcurobj(); 

		/* now enter a dummy line if type is fill, so that lowermost
		   gray box does not extend to X-axis */
		if ((curves[c])->type == fill)
			enterdummy(c,k);
}

EnterSymbol(c,k)
int c,k;
/*c is curve number*/
/* k is key element number*/
{
		InitObjSymbol(obj[curobj], c);
		(obj[curobj])->from[xpt] = keypos[xpt];
		(obj[curobj])->from[ypt] = keypos[ypt];
 		scaleobj(obj[curobj]);
		/* now slide it relative to keybox */
		(obj[curobj])->scale = FALSE;
		(obj[curobj])->from[ypt] -= 
			k * LocalKeyMul * CMPT * charheight(graph.keyfont) ;

		GetNewObjcurobj(); 

}


EnterText(c,k)
int c,k;
/*c is curve number*/
/* k is key element number*/
{
	   (obj[curobj])->name = objtext;
	   (obj[curobj])->un.text.fontsize = FFsize(graph.keyfont);
	   (obj[curobj])->un.text.font = graph.keyfont;
	   (obj[curobj])->un.text.FF = FF(graph.keyfont);
	   (obj[curobj])->from[xpt] = keypos[xpt];
	   (obj[curobj])->from[ypt] = dummy;
	   (obj[curobj])->scale = TRUE;
	   scaleobj(obj[curobj]);
	   /* now slide it relative to its last symbol in previous obj */
	   (obj[curobj])->scale = FALSE;
	   (obj[curobj])->un.text.StrPtr = (curves[c])->label;
	   (obj[curobj])->from[xpt] += iconsize ;
	   (obj[curobj])->from[ypt] = 
		(obj[curobj-1])->from[ypt] - CMPT * textBelowIcon;

	   /* if fill type then slide text up */
	   /* if ktype, another line has come below */
	   /* if kboth, symbol is still above */
	   if ((curves[c])->type == fill)
		if (graph.key == ktype)
		    (obj[curobj])->from[ypt] +=
			LocalKeyMul * CMPT * charheight(graph.keyfont)/2.0;
		else if (graph.key == kboth)
		    (obj[curobj])->from[ypt] -=
			LocalKeyMul * CMPT * charheight(graph.keyfont)/2.0;

	   (obj[curobj])->un.text.angle = getdegrees(1.0,0.0);/* hor */
	   (obj[curobj])->un.text.align = left;	
	   GetNewObjcurobj();
}

KeySeqStart()
{
	(obj[curobj])->name = objflagkey;
	(obj[curobj])->scale = FALSE;
	GetNewObjcurobj();
}
