/*
 $Id: mgenvir.c,v 1.1.1.1 1996/11/04 12:05:46 roitzsch Exp $
 (C)opyright 1996 by Konrad-Zuse-Center, Berlin
 All rights reserved.
 Part of the common environment

$Log: mgenvir.c,v $
Revision 1.1.1.1  1996/11/04 12:05:46  roitzsch
minigraph module

*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "minigraph.h"
#define sign(x) ((x<0)?-1.0:1.0)

FILE *miniErrorFile=nil;

static void SetGenDef(GRAPHIC *graph)
  {
    graph->minX = 0.0;
    graph->minY = 0.0;
    graph->maxX = 1.0;
    graph->maxY = 1.0;
    graph->slMinX = 0.0;
    graph->slMinY = 0.0;
    graph->slMaxX = 1.0;
    graph->slMaxY = 1.0;
    graph->ready = false;
    graph->newScal = true;
    graph->prec = SINGLE;
    graph->scalFit = 1;
    graph->line_count = 0;
    graph->page_count = 1;

    return;
  }
 
GRAPHIC *NewGraph(int type)
  {
    GRAPHIC * newG;

	CHECK_FILE;
	newG = (GRAPHIC*)malloc(sizeof(GRAPHIC));
	if (newG==nil) return nil;
	SetGenDef(newG);
	switch (type)
	{
	  case PS:
	  case PS_QUER:
	  case PS_TEX:
	    if (!PSInit(newG, type))
		  { free(newG); newG = nil; return nil; }
		break;
	  case MAC:
#if MACOSAVAIL == 1
	  case -1:
	  case SCREEN:
	    if (!MacInit(newG))
		  { free(newG); newG = nil; return nil; }
		break;
#else
	    fprintf(miniErrorFile,"MiniGraphic - zibwop :  Quickdraw driver only on Mac II\n");
		free(newG);
		newG = nil;
		return nil;
#endif
	  case X11:
#if X11AVAIL == 1
	  case -1:
	  case SCREEN:
	    if (!XInit(newG))
	     { free(newG); newG = nil; return nil; }
	    break;
#else
	    fprintf(miniErrorFile,"MiniGraphic - zibwop :  Open X11 driver failed\n");
	    free(newG);
	    newG = nil;
	    return nil;
#endif	  
	  default:
	    fprintf(miniErrorFile,"MiniGraphic - zibwop :  Unknown driver type: %d !\n",type);
		free(newG);
		newG = nil;
		return nil;
	}
	newG->next = (firstGraph==nil)?nil:firstGraph;
	firstGraph = newG;
	return newG;
  }


void ReturnGraph(GRAPHIC *graph)
  {
    GRAPHIC *last=nil, *next, *g=firstGraph;
    while(g!=nil)
      {
        next = g->next;
	    if (g==graph)
 	      {
 	        if (last==nil) firstGraph = next;
 	        else last->next = next;
      		free(graph);
 	      }
 	    else last = g;
 	    g = next;
 	  }
    return;
  }




int ComputeScaling(GRAPHIC *graph)
  {
    real top, left, bottom, right, width, height,
         xmin, xmax, ymin, ymax, dx, dy,
		 xscal, yscal, xtrans, ytrans;

    if (!graph->ready)
      (graph->OpenPort)(graph);

    top = graph->wdOrgY+graph->wdHght;
	left = graph->wdOrgX;
	bottom = graph->wdOrgY;
	right = graph->wdOrgX+graph->wdWdth;
	width = right-left;
	height = top-bottom;

	xmin = graph->slMinX;
	xmax = graph->slMaxX;
	ymin = graph->slMinY;
	ymax = graph->slMaxY;
	dx = xmax-xmin;
	dy = ymax-ymin;
/*
fprintf(miniErrorFile,"User rectangle: (%e,%e,%e,%e)\n",graph->minX,graph->minY,graph->maxX,graph->maxY);
fprintf(miniErrorFile,"User selected rectangle: (%e,%e,%e,%e)\n",xmin,ymin,xmax,ymax);
fprintf(miniErrorFile,"Target rectangle: (%e,%e,%e,%e)\n",graph->left,graph->bottom,graph->right,graph->top);
fprintf(miniErrorFile,"Target selected rectangle: (%e,%e,%e,%e)\n",left,bottom,right,top);
*/
    xscal = width/dx;
    yscal = height/dy;
   
   	switch (graph->scalFit)
   	{
	  case 0:
	    xtrans = -xmin*xscal;
		ytrans = -ymin*yscal;
		break;
	  case 1:
		if (fabs(xscal)>fabs(yscal))
		  {
		    xscal = sign(xscal)*fabs(yscal);
		    xtrans = (width-dx*xscal)*0.5-xmin*xscal;
			ytrans = -ymin*yscal;
		  }
		else
		  {
			yscal = sign(yscal)*fabs(xscal);
			xtrans = -xmin*xscal;
			ytrans = (height-dy*yscal)*0.5-ymin*yscal;
		  }
		break;
	  case 2:
		if (fabs(xscal)>fabs(yscal))
		  {
		    xscal = sign(xscal)*fabs(yscal);
		    xtrans = -xmin*xscal;
			ytrans = -ymin*yscal;
		  }
		else
		  {
			yscal = sign(yscal)*fabs(xscal);
			xtrans = -xmin*xscal;
			ytrans = -ymin*yscal;
		  }
		break;
	  default:
	    fprintf(miniErrorFile,"MiniGraphic :  Unknown scaling rule %d\n",graph->scalFit);
	    break;
   	}
/*
fprintf(miniErrorFile,"xscal=%e, yscal=%e, xtrans=%e, ytrans=%e\n",xscal,yscal,xtrans,ytrans);
*/
	graph->xScal = xscal;
	graph->yScal = yscal;
	graph->xTrans = xtrans;
	graph->yTrans = ytrans;
	graph->uXdr = fabs(xscal);
	graph->uYdr = fabs(yscal);
	graph->uXcm = (graph->drXcm)/xscal;
	graph->uYcm = (graph->drYcm)/yscal;
	graph->uRes = (graph->drRes)/xscal;
	graph->uPenSz = (graph->drPenSz)/xscal;
	graph->uFntSz = (graph->drFntSz)/xscal;
	graph->xRes = fabs(1/xscal);
	graph->yRes = fabs(1/yscal);
	
    graph->newScal = false;
	return true;
  }



int PrintGraph(GRAPHIC *graph)
  {
    fprintf(miniErrorFile,"U: (%8.3f,%8.3f,%8.3f,%8.3f)-(%8.3f,%8.3f,%8.3f,%8.3f)\n",
			graph->minX, graph->minY, graph->maxX, graph->maxY,
			graph->slMinX, graph->slMinY,
			graph->slMaxX, graph->slMaxY);
    fprintf(miniErrorFile,"D: (%8.3f,%8.3f,%8.3f,%8.3f)-(%8d,%8d),(%8d,%8d)\n",
			graph->left, graph->bottom, graph->right, graph->top,
			graph->wdOrgX,graph->wdOrgY,
			graph->wdWdth,graph->wdHght);
	fprintf(miniErrorFile,"1cm = (%8.3f,%8.3f)u, (%8.3f,%8.3f)d\n",
			graph->uXcm, graph->uYcm,
			graph->drXcm, graph->drYcm);
	fprintf(miniErrorFile,"Resolution = %8.3fu, %8.3fd\n",
			graph->uRes, graph->drRes);
	fprintf(miniErrorFile,"Pensize    = %8.3fu, %8dd\n",
			graph->uPenSz, graph->drPenSz);
	fprintf(miniErrorFile,"Fontsize   = %8.3fu, %8dd\n",
			graph->uFntSz, graph->drFntSz);
	fprintf(miniErrorFile,"id=%d, wdNo=%d %s, prec=%s precission\n",
			graph->id, graph->wdNo,
			(graph->ready)?"is ready":"is not ready",
			(graph->prec==SINGLE)?"Single":"Double");
	if ((graph->caption)!=nil)
	  fprintf(miniErrorFile,"Caption = '%s'\n", graph->caption);
	if ((graph->fontName)!=nil)
	  fprintf(miniErrorFile,"Font = '%s'\n", graph->fontName);
	if ((graph->fileName)!=nil)
	  fprintf(miniErrorFile,"File = '%s'\n", graph->fileName);
	fprintf(miniErrorFile,"Scaling:(%e,%e), Translating:(%e,%e)\n",
			graph->xScal, graph->yScal,
			graph->xTrans, graph->yTrans);
	return true;
  }


syntax highlighted by Code2HTML, v. 0.9.1