#include <graphics/display.h>
#include <libraries/dosextens.h>
#include <libraries/diskfont.h>
#include <exec/exec.h>
#include <intuition/intuitionbase.h>
#include <graphics/regions.h>
#include <devices/keymap.h>
#include <stdio.h>
#include <workbench/startup.h>
#include <graphics/gfxmacros.h>
#include <graphics/gfxbase.h>
#include <math.h>

#include "diskicon.h"
#include "struct.h"
#include "plotlim.h"

extern int MAXVERT;

extern int GetDat();
extern void plot();
extern struct Screen *screen;
extern struct NewScreen newscreen;
extern struct NewWindow newwindow;
extern struct Window *window;
extern int XMINP;      /* LMARGIN */
extern int YMAXP;   /* MAXVERT - TMARGIN */
extern int YMINP;    /* BMARGIN */



#define QUIT 0
#define GO 1
extern int QuitFlag;

extern long IconBase;

extern FFP xtic[MAXTICS],ytic[MAXTICS];
extern short xticp[MAXTICS],yticp[MAXTICS];
extern char filename[150];
extern struct RastPort *p;
extern struct ViewPort *vp;

#define P_XREG 10000
#define P_YREG 10000
#define P_X_TIC_SIZE X_TIC_SIZE*(P_YREG/MAXVERT)
#define P_Y_TIC_SIZE Y_TIC_SIZE*(P_XREG/MAXHORIZ)
#define P_CH_WID 75
#define P_CH_HEI 150
#define P_LMARGIN P_CH_WID*8
#define P_BMARGIN P_CH_HEI*2
#define P_TMARGIN 0
#define P_RMARGIN 0

static FFP XScale, YScale, XOffset, YOffset;

void fWrtFFP(fp, ffpval)
FILE *fp;
FFP ffpval;
{
   fprintf(fp, "%d", (int)ffpval);
}


void WrtAxes(fp, Tics, Grid)
FILE *fp;
struct Tics *Tics;
short Grid;
{
   short n, tmpx, tmpy, i;
   FFP *x, *y;
   char tmpstr[20];

   /*** DRAW BORDER ***/
   fprintf(fp,"SP1;PU%d %d;",P_LMARGIN,P_BMARGIN);
   fprintf(fp,"PD%d %d %d %d %d %d %d %d;\n",P_XREG,P_BMARGIN,P_XREG,P_YREG,
   P_LMARGIN,P_YREG,P_LMARGIN,P_BMARGIN);

   /*** DRAW TICS/GRID ***/
   fprintf(fp,"SP2;");
   x=Tics->x; y=Tics->y;
   for (i=1; i < Tics->NX; i++) {
      if (Grid) {
         fprintf(fp,"PU"); fWrtFFP(fp,(XScale * (XOffset + x[i])));
         fprintf(fp," %d;PD",P_BMARGIN);
         fWrtFFP(fp,(XScale * (XOffset + x[i])));
         fprintf(fp," %d;\n",P_YREG);
      }
      else {
         fprintf(fp,"PU"); fWrtFFP(fp,(XScale * (XOffset + x[i])));
         fprintf(fp," %d;PD",P_BMARGIN);
         fWrtFFP(fp,(XScale * (XOffset + x[i])));
         fprintf(fp," %d;",P_BMARGIN + P_X_TIC_SIZE);
         fprintf(fp,"PU"); fWrtFFP(fp,(XScale * (XOffset + x[i])));
         fprintf(fp," %d;PD",P_YREG);
         fWrtFFP(fp,(XScale * (XOffset + x[i])));
         fprintf(fp," %d;\n",P_YREG - P_X_TIC_SIZE);
      }
   }
   for (i=1; i < Tics->NY; i++) {
      if (Grid) {
         fprintf(fp,"PU%d ",P_LMARGIN);
         fWrtFFP(fp,(YScale * (YOffset + y[i])));
         fprintf(fp,"PD%d ",P_XREG);
         fWrtFFP(fp,(YScale * (YOffset + y[i])));
         fprintf(fp,";\n");
      }
      else {
         fprintf(fp,"PU%d ",P_LMARGIN);
         fWrtFFP(fp,(YScale * (YOffset + y[i])));
         fprintf(fp,";PD%d ", P_LMARGIN + P_Y_TIC_SIZE);
         fWrtFFP(fp,(YScale * (YOffset + y[i])));
         fprintf(fp,";");
         fprintf(fp,"PU%d ",P_XREG);
         fWrtFFP(fp,(YScale * (YOffset + y[i])));
         fprintf(fp,";PD%d ", P_XREG - P_Y_TIC_SIZE);
         fWrtFFP(fp,(YScale * (YOffset + y[i])));
         fprintf(fp,";\n");
      }
   }

   /*** PRINT TIC VALUES ***/
   fprintf(fp,"SP1;");
   for (i=0; i < Tics->NX; i++) {
      n = sprintf(tmpstr, "%-.4f", Tics->x[i]);
      n = min(n, 7);
      while (tmpstr[n-1] == '0') n--;
      tmpstr[n]=0;
      tmpx = (short)((XScale * (XOffset + Tics->x[i])));
      tmpx -= (((n+1)/2)-.5) * P_CH_WID;
      fprintf(fp, "PU%d 1;", tmpx);
      fprintf(fp,"LB%s\003", tmpstr);
   }
   for (i=0; i < Tics->NY; i++) {
      n = sprintf(tmpstr, "%-.4f", Tics->y[i]);
      n = min(n, 7);
      while (tmpstr[n-1] == '0') n--;
      tmpstr[n]=0;
      tmpy = (short)((YScale * (YOffset + Tics->y[i])));
      tmpy -= .5 * P_CH_WID;
      fprintf(fp, "PU1 %d;", tmpy);
      fprintf(fp,"LB%s\003", tmpstr);
   }
}

extern USHORT chip WaitSprite[];
extern char *stpchr();

WrtPlt(Pict,Dest)
USHORT Dest;
struct Pict *Pict;
{
   struct Process  *OurTask;
   struct Window   *old_pr_WindowPtr;
   FILE *fp;
   short i;
   struct Plot *Plot;
   FFP *x, *y, *e;
   short xptsiz, yptsiz;
   static char plotname[150], def_drive[150]="PLT:", def_path[100], def_node[30],def_extn[20];
   static char PlotNum = 0;

   if (Dest)
      {
          strcpy(plotname,filename);
          strsfn(plotname,def_drive,def_path,def_node,def_extn);
          strcat(def_drive,def_path);
          strcat(def_node,".plt");
          strcat(def_node,PlotNum);

          OurTask = (struct Process *)FindTask(0L);
          old_pr_WindowPtr = (struct Window *)OurTask->pr_WindowPtr;
          OurTask->pr_WindowPtr = (APTR)window;
          if (get_fname(window,screen,"Save File As...",def_node,def_drive)==NULL)
               {
                  OurTask->pr_WindowPtr = (APTR)old_pr_WindowPtr;
                  return(TRUE);
                }

           OurTask->pr_WindowPtr = (APTR)old_pr_WindowPtr;
           strmfp(plotname,def_drive,def_node);
           PutDiskObject(plotname,&IconDiskObject);
       }
   else
       {
          if (!(fp = fopen("l:plt-handler","r") ))
             {
                Message("Printing needs the PLT: Device"); return(FALSE);
             }
          fclose(fp);
          Execute("c:mount plt:",0,0);
          strcpy(plotname,"PLT:");
       }

   if (!(fp = fopen(plotname,"w") ))
      {Message("     Can't open file        "); return(FALSE);}

   SetPointer(window,WaitSprite,26,14,-4,-4);

   fprintf(fp,"IN;SC 0 %d 0 %d;\n", P_XREG+100, P_YREG+100);
   fprintf(fp,"VS 20.0;\n");  /* VELOCITY cm/s */
   fprintf(fp,"\033.N;19:\033.I81;;17:\n"); /* XON/XOFF */
   XScale = (FFP)(P_XREG - P_LMARGIN - P_RMARGIN) /
            (Pict->CurrReg->XMax - Pict->CurrReg->XMin);
   YScale = (FFP)(P_YREG - P_BMARGIN - P_TMARGIN) /
            (Pict->CurrReg->YMax - Pict->CurrReg->YMin);
   XOffset = (FFP)(P_LMARGIN) / XScale - Pict->CurrReg->XMin;
   YOffset = (FFP)(P_BMARGIN) / YScale - Pict->CurrReg->YMin;

   Plot = Pict->Plot;
   while (Plot) {
      if (Plot->Enabled) {
         fprintf(fp,"PU;SP%d;\n", 1+Plot->Color-PLOTCOLORBASE);

         /* PLOT LINES */
         if (Plot->PointSize <= 0) {
            x=Plot->x; y=Plot->y;
            fprintf(fp, "PU"); fWrtFFP(fp,(XScale * (XOffset + *x)));
            fprintf(fp," ");
            fWrtFFP(fp,(YScale * (YOffset + *y))); fprintf(fp,";");
            x++; y++;
            fprintf(fp, "PD");
            for (i=1; i<Plot->NPts; i++, x++, y++) {
               if (i>1) fprintf(fp, " ");
               fWrtFFP(fp,(XScale * (XOffset + *x)));
               fprintf(fp," ");
               fWrtFFP(fp,(YScale * (YOffset + *y)));
            }
            fprintf(fp,";\n");
         }

         /* PLOT POINTS */
         if (Plot->PointSize != 0) {
            xptsiz = abs(Plot->PointSize) * (P_XREG / 1100);
            yptsiz = abs(Plot->PointSize) * (P_YREG / 850);
            x=Plot->x; y=Plot->y;
            for (i=0; i<Plot->NPts; i++, x++, y++) {
               fprintf(fp,"PU");
               fWrtFFP(fp,(XScale * (XOffset + *x)));
               fprintf(fp," ");
               fWrtFFP(fp,(YScale * (YOffset + *y)));
               fprintf(fp,";");
               fprintf(fp,"PR%d %d;", -xptsiz/2, -yptsiz/2);
               fprintf(fp,"PD%d 0 0 %d %d 0 0 %d;PA;\n",
                     xptsiz, yptsiz, -xptsiz, -yptsiz);
            }
         }

         /* PLOT ERROR BARS */
         if (Pict->ShowErr) {
            x=Plot->x; y=Plot->y; e=Plot->e;
            for (i=0; i<Plot->NPts; i++, x++, y++, e++) {
               fprintf(fp,"PU");
               fWrtFFP(fp,(XScale * (XOffset + *x)));
               fprintf(fp," ");
               fWrtFFP(fp,(YScale * (YOffset + (*y - *e))));
               fprintf(fp,";PD");
               fWrtFFP(fp,(XScale * (XOffset + *x)));
               fprintf(fp," ");
               fWrtFFP(fp,(YScale * (YOffset + (*y + *e))));
               fprintf(fp,";\n");
            }
         }
      }
      Plot = Plot->NextPlot;
   }

   fprintf(fp,"SR%f %f;\n",
         (float)(100*P_CH_WID) / (P_XREG - P_LMARGIN - P_RMARGIN),
         (float)(100*P_CH_HEI) / (P_YREG - P_BMARGIN - P_TMARGIN));
   WrtAxes(fp, Pict->Tics, Pict->Grid);

   fprintf(fp, "SP;");
   (void) fclose(fp);
   PlotNum++;
   ClearPointer(window);
   return(TRUE);
}




void header(n, c, t, fp)
int n, c, t;
FILE *fp;
{
   UBYTE bdummy;
   bdummy = n;
   fwrite((char *)&bdummy, 1, 1, fp);
   bdummy = c;
   fwrite((char *)&bdummy, 1, 1, fp);
   bdummy = 0;
   fwrite((char *)&bdummy, 1, 1, fp); /* LineType */
   bdummy = t;
   fwrite((char *)&bdummy, 1, 1, fp);
   bdummy = 0;
   fwrite((char *)&bdummy, 1, 1, fp); /* padding for future use */
   fwrite((char *)&bdummy, 1, 1, fp);
}

To_mCAD(Pict,Dest)
struct Pict *Pict;
USHORT Dest;
{

   struct Process  *OurTask;
   struct Window   *old_pr_WindowPtr;

   FILE *fp;
   short i;
   struct Plot *Plot;
   FFP *x, *y, *e, xtmp, ytmp, xtmp1, ytmp1;
   FFP xptsiz, yptsiz, XReg, YReg, XScale, XOffset;
   char plotname[150], def_drive[150], def_path[100], def_node[30],def_extn[20];
   static char mPlotNum = 0;

  if (Dest)
    {
     strcpy(plotname,filename);
     strsfn(plotname,def_drive,def_path,def_node,def_extn);
     strcat(def_drive,def_path);
     strcat(def_node,".txt");
     strcat(def_node,mPlotNum);

           OurTask = (struct Process *)FindTask(0L);
           old_pr_WindowPtr = (struct Window *)OurTask->pr_WindowPtr;
           OurTask->pr_WindowPtr = (APTR)window;
           if (get_fname(window,screen,"Save File As...",def_node,def_drive)==NULL)
               {
                  OurTask->pr_WindowPtr = (APTR)old_pr_WindowPtr;
                  return(TRUE);
                }

     OurTask->pr_WindowPtr = (APTR)old_pr_WindowPtr;
     strmfp(plotname,def_drive,def_node);
     PutDiskObject(plotname,&IconDiskObject);
    }
   else
       {
          if (!(fp = fopen("T:tempfile","w") ))
             {
                Message("Save needs the T: Device"); return(FALSE);
             }
          fclose(fp);
          strcpy(plotname,"T:tempfile");
       }

   if (!(fp = fopen(plotname,"w") ))
      {Message("     Can't open file        "); return(FALSE);}

   XReg = Pict->CurrReg->XMax - Pict->CurrReg->XMin;
   YReg = Pict->CurrReg->YMax - Pict->CurrReg->YMin;
   XScale = YReg/XReg * 1.4434; XOffset = Pict->CurrReg->XMin;

   Plot = Pict->Plot;
   while (Plot) {
      if (Plot->Enabled) {

         /* PLOT LINES */
         if (Plot->PointSize <= 0) {
            x=Plot->x; y=Plot->y;
 /*--->>*/  for (i=0; i<Plot->NPts; i++, x++, y++) {
               xtmp = XScale * (*x - XOffset);
               fprintf(fp, "%f %f\n", xtmp, *y);
            }
            fprintf(fp,"*>\n*C %d\n\n", 1+Plot->Color-PLOTCOLORBASE);
         }

         /* PLOT POINTS */
         if (Plot->PointSize != 0) {
            xptsiz = abs(Plot->PointSize) * (XReg / 582.);
            xptsiz = XScale * xptsiz;
            yptsiz = abs(Plot->PointSize) * (YReg / 360.);
            x=Plot->x; y=Plot->y;
            for (i=0; i<Plot->NPts; i++, x++, y++) {
               xtmp = XScale * (*x - XOffset);
               xtmp -= xptsiz/2;
               ytmp = *y - yptsiz/2;
               fprintf(fp,"%f %f\n", xtmp, ytmp); xtmp += xptsiz;
               fprintf(fp,"%f %f\n", xtmp, ytmp); ytmp += yptsiz;
               fprintf(fp,"%f %f\n", xtmp, ytmp); xtmp -= xptsiz;
               fprintf(fp,"%f %f\n", xtmp, ytmp); ytmp -= yptsiz;
               fprintf(fp,"%f %f\n", xtmp, ytmp);
               fprintf(fp,"*>\n*C %d\n\n", 1+Plot->Color-PLOTCOLORBASE);
            }
         }

         /* PLOT ERROR BARS */
         if (Pict->ShowErr) {
            x=Plot->x; y=Plot->y; e=Plot->e;
            for (i=0; i<Plot->NPts; i++, x++, y++, e++) {
               xtmp = XScale * (*x - XOffset);
               ytmp = *y - *e;
               fprintf(fp,"%f %f\n", xtmp, ytmp);
               ytmp = *y + *e;
               fprintf(fp,"%f %f\n", xtmp, ytmp);
               fprintf(fp,"*>\n*C %d\n\n", 1+Plot->Color-PLOTCOLORBASE);
            }
         }
      }
      Plot = Plot->NextPlot;
   }

   /*** DRAW TICS/GRID ***/
   x = Pict->Tics->x; y = Pict->Tics->y;
   for (i=1; i < Pict->Tics->NX; i++) {
      xtmp = XScale * (x[i] - XOffset);
      if (Pict->Grid) {
         PToU(Pict, 0, YMINP, &xtmp, &ytmp);
         PToU(Pict, 0, YMAXP, &xtmp1, &ytmp1);
         fprintf(fp,"%f %f\n%f %f\n*>\n*C 2\n\n", xtmp, ytmp, xtmp, ytmp1);
      }
      else {
         PToU(Pict, 0, YMINP, &xtmp1, &ytmp);
         fprintf(fp,"%f %f\n", xtmp, ytmp);
         PToU(Pict, 0, YMINP+X_TIC_SIZE, &xtmp1, &ytmp1);
         fprintf(fp,"%f %f\n*>\n*C 3\n\n", xtmp, ytmp1);
         PToU(Pict, 0, YMAXP, &xtmp1, &ytmp);
         fprintf(fp,"%f %f\n", xtmp, ytmp);
         PToU(Pict, 0, YMAXP-X_TIC_SIZE, &xtmp1, &ytmp1);
         fprintf(fp,"%f %f\n*>\n*C 3\n\n", xtmp, ytmp1);
      }
   }
   for (i=1; i < Pict->Tics->NY; i++) {
      if (Pict->Grid) {
         PToU(Pict, XMINP, YMINP, &xtmp, &ytmp);
         xtmp = XScale * (xtmp - XOffset);
         PToU(Pict, XMAXP, YMAXP, &xtmp1, &ytmp1);
         xtmp1 = XScale * (xtmp1 - XOffset);
         fprintf(fp,"%f %f\n%f %f\n*>\n*C 2\n\n", xtmp, y[i], xtmp1, y[i]);
      }
      else {
         PToU(Pict, XMINP, 0, &xtmp, &ytmp);
         xtmp = XScale * (xtmp - XOffset);
         fprintf(fp,"%f %f\n", xtmp, y[i]);
         PToU(Pict, XMINP+Y_TIC_SIZE, 0, &xtmp1, &ytmp1);
         xtmp1 = XScale * (xtmp1 - XOffset);
         fprintf(fp,"%f %f\n*>\n*C 3\n\n", xtmp1, y[i]);
         PToU(Pict, XMAXP, 0, &xtmp, &ytmp);
         xtmp = XScale * (xtmp - XOffset);
         fprintf(fp,"%f %f\n", xtmp, y[i]);
         PToU(Pict, XMAXP-Y_TIC_SIZE, 0, &xtmp1, &ytmp1);
         xtmp1 = XScale * (xtmp1 - XOffset);
         fprintf(fp,"%f %f\n*>\n*C 3\n\n", xtmp1, y[i]);
      }
   }

   /*** PRINT TIC VALUES ***/
/*
*   for (i=0; i < Pict->Tics->NX; i++) {
*      n = sprintf(tmpstr, "%-.4f", Pict->Tics->x[i]);
*      n = min(n, 7);
*      while (tmpstr[n-1] == '0') n--;
*      tmpstr[n]=0;
*   }
*   for (i=0; i < Pict->Tics->NY; i++) {
*      n = sprintf(tmpstr, "%-.4f", Pict->Tics->y[i]);
*      n = min(n, 7);
*      while (tmpstr[n-1] == '0') n--;
*      tmpstr[n]=0;
*   }
*/

   /*** DRAW AXES ***/
   PToU(Pict, XMINP, YMINP, &xtmp, &ytmp);
   xtmp = XScale * (xtmp - XOffset);
   PToU(Pict, XMAXP, YMAXP, &xtmp1, &ytmp1);
   xtmp1 = XScale * (xtmp1 - XOffset);
   fprintf(fp, "%f %f\n", xtmp, ytmp);
   fprintf(fp, "%f %f\n", xtmp1, ytmp);
   fprintf(fp, "%f %f\n", xtmp1, ytmp1);
   fprintf(fp, "%f %f\n", xtmp, ytmp1);
   fprintf(fp, "%f %f\n", xtmp, ytmp);
   fprintf(fp,"*C 1\n\n");

   (void) fclose(fp);
   mPlotNum++;
   return(TRUE);
}
