/* This file contains the PostScript device dependent subroutines for */
/* use with plplot. */

#include "plplot.h"
#include <stdio.h>

#define LINELENGTH      70
#define COPIES          1
#define XSIZE           540
#define YSIZE           720
#define XPSSIZE         3000
#define YPSSIZE         2250
#define XOFFSET         576
#define YOFFSET         36
#define XSCALE          100
#define YSCALE          100
#define LINESCALE       100
#define ANGLE           90
#define PSX             XPSSIZE-1
#define PSY             YPSSIZE-1

char *getdate();
static int numpages = 0;
static int linepos = 0;

static FILE *OutFile;
static PLINT orient;
static PLINT select=0;
static char FileName[80];

void pssetup(xdpi, ydpi, xwid, ywid)
PLINT xwid, ywid;
PLFLT xdpi, ydpi;
{
}

void psselect(ori, name)
PLINT ori;
char *name;
{
   orient = ori;
   strncpy(FileName,name,sizeof(FileName)-1);
   FileName[sizeof(FileName)-1] = '\0';
   select = 1;
}


/* Open file.  Set up for graphics. */
void psinit()
{
      char line[80];

      if(!select) {
         printf("Landscape or portrait orientation? (0 or 1) ");
         fgets(line,sizeof(line),stdin);
         if(sscanf(line,"%d",&orient) != 1)
            orient = 0;
      }

   /* setpxl() sets the dots/mm in the x and y directions */
      setpxl(11.81,11.81);         /* 300 dpi */

   /* setphy() sets the device coordinates. These are integer */
   /* values. Set up for landscape orientation (long axis of page in the */
   /* x direction). Origin is in the lower left hand corner. */
      if(!orient)
         setphy(0,PSX,0,PSY);
      else
         setphy(0,PSY,0,PSX);

   /* Set default pen color using scol(color). */
   /* Any default pen color can be used but a black pen is probably best. */
      scol(1);

   /* Set default pen width using swid(width) */
      swid(1);

   /* Set device interaction mode using smod(mode). Set mode to 0 for */
   /* a noninteractive device, Unless you are writing your */
   /* own Amiga screen driver mode should be 0. */
      smod(0);

   /* Well that's all the information plplot needs. Let's prompt for a */
   /* graphics file name. */
      for(;;) {
         if(!select) {
            printf("Enter PostScript graphics file name. ");
            fgets(line,sizeof(line),stdin);
            if(sscanf(line,"%s",FileName)!=1)
               continue;
         }

         if (!(OutFile = fopen(FileName,"w"))) {
            fprintf(stderr,"Can't open %s.\n",FileName);
            select = 0;
         }
         else
            break;
      }
      select = 0;

  /* Header comments into PostScript file */

      fprintf(OutFile,"%%!PS-Adobe-2.0 EPSF-2.0\n");
      fprintf(OutFile,"%%%%BoundingBox: 36 36 540 720\n");
      fprintf(OutFile,"%%%%Title: %s\n", FileName);
      fprintf(OutFile,"%%%%Creator: PLPLOT Version 2.0\n");
      fprintf(OutFile,"%%%%CreationDate: %s\n", getdate());
      fprintf(OutFile,"%%%%Pages: (atend)\n");
      fprintf(OutFile,"%%%%EndComments\n\n");

  /* Definitions */

      fprintf(OutFile, "/PSSave save def\n");      /* save VM state */
      fprintf(OutFile, "/PSDict 200 dict def\n");  /* define a dictionary */
      fprintf(OutFile, "PSDict begin\n");          /* start using it */
      fprintf(OutFile, "/@restore /restore load def\n");
      fprintf(OutFile, "/restore\n");
      fprintf(OutFile, "   {vmstatus pop\n");
      fprintf(OutFile, "    dup @VMused lt {pop @VMused} if\n");
      fprintf(OutFile, "    exch pop exch @restore /@VMused exch def\n");
      fprintf(OutFile, "   } def\n");
      fprintf(OutFile, "/@pri\n");
      fprintf(OutFile, "   {\n");
      fprintf(OutFile, "    ( ) print\n");
      fprintf(OutFile, "    (                                       ) cvs print\n");
      fprintf(OutFile, "   } def\n");
      fprintf(OutFile, "/@copies\n");   /* n @copies - */
      fprintf(OutFile, "   {\n");
      fprintf(OutFile, "    /#copies exch def\n");
      fprintf(OutFile, "   } def\n");
      fprintf(OutFile, "/@start\n");    /* - @start -  -- start everything */
      fprintf(OutFile, "   {\n");
      fprintf(OutFile, "    vmstatus pop /@VMused exch def pop\n");
      fprintf(OutFile, "   } def\n");
      fprintf(OutFile, "/@end\n");      /* - @end -  -- finished */
      fprintf(OutFile, "   {(VM Used: ) print @VMused @pri\n");
      fprintf(OutFile, "    (. Unused: ) print vmstatus @VMused sub @pri pop pop\n");
      fprintf(OutFile, "    (\\n) print flush\n");
      fprintf(OutFile, "    end\n");
      fprintf(OutFile, "    PSSave restore\n");
      fprintf(OutFile, "   } def\n");
      fprintf(OutFile, "/bop\n");       /* bop -  -- begin a new page */
      fprintf(OutFile, "   {\n");
      fprintf(OutFile, "    /SaveImage save def\n");
      fprintf(OutFile, "   } def\n");
      fprintf(OutFile, "/eop\n");       /* - eop -  -- end a page */
      fprintf(OutFile, "   {\n");
      fprintf(OutFile, "    showpage\n");
      fprintf(OutFile, "    SaveImage restore\n");
      fprintf(OutFile, "   } def\n");
      fprintf(OutFile, "/@line\n");     /* set line parameters */
      fprintf(OutFile, "   {0 setlinecap\n");
      fprintf(OutFile, "    0 setlinejoin\n");
      fprintf(OutFile, "    1 setmiterlimit\n");
      fprintf(OutFile, "   } def\n");
                        /* d @hsize -  horizontal clipping dimension */
      fprintf(OutFile, "/@hsize   {/hs exch def} def\n");
      fprintf(OutFile, "/@vsize   {/vs exch def} def\n");
                        /* d @hoffset - shift for the plots */
      fprintf(OutFile, "/@hoffset {/ho exch def} def\n");
      fprintf(OutFile, "/@voffset {/vo exch def} def\n");
                        /* s @hscale - scale factors */
      fprintf(OutFile, "/@hscale  {100 div /hsc exch def} def\n");
      fprintf(OutFile, "/@vscale  {100 div /vsc exch def} def\n");
                        /* s @lscale - linewidth scale factor */
      fprintf(OutFile, "/@lscale  {100 div /lin exch def} def\n");
                        /* a @angle - rotation angle */
      fprintf(OutFile, "/@angle   {/ang exch def} def\n");
      fprintf(OutFile, "/@SetPlot\n");  /* setup user specified offsets, */
      fprintf(OutFile, "   {\n");       /* scales, sizes for clipping    */
      fprintf(OutFile, "    ho vo translate\n");
      fprintf(OutFile, "    XScale YScale scale\n");
      fprintf(OutFile, "    ang rotate\n");
      fprintf(OutFile, "    lin lw mul setlinewidth\n");
      fprintf(OutFile, "   } def\n");
      fprintf(OutFile, "/XScale\n");    /* setup x scale */
      fprintf(OutFile, "   {hsc hs mul %d div} def\n", YPSSIZE);
      fprintf(OutFile, "/YScale\n");    /* setup y scale */
      fprintf(OutFile, "   {vsc vs mul %d div} def\n", XPSSIZE);
      fprintf(OutFile, "/lw 3 def\n");  /* default line width */
      fprintf(OutFile, "/M {moveto} def\n");
      fprintf(OutFile, "/D {lineto} def\n");
      fprintf(OutFile, "/S {stroke} def\n");
      fprintf(OutFile, "/Z {stroke newpath} def\n");
      fprintf(OutFile, "end\n\n");      /* end of dictionary definition */

  /* Set up the plots */

      fprintf(OutFile, "PSDict begin\n");
      fprintf(OutFile, "@start\n");
      fprintf(OutFile, "%d @copies\n", COPIES);
      fprintf(OutFile, "@line\n");
      fprintf(OutFile, "%d @hsize\n", XSIZE);
      fprintf(OutFile, "%d @vsize\n", YSIZE);
      fprintf(OutFile, "%d @hoffset\n", XOFFSET);
      fprintf(OutFile, "%d @voffset\n", YOFFSET);
      fprintf(OutFile, "%d @hscale\n", XSCALE);
      fprintf(OutFile, "%d @vscale\n", YSCALE);
      fprintf(OutFile, "%d @lscale\n", LINESCALE);
      fprintf(OutFile, "%d @angle\n", ANGLE);
      fprintf(OutFile, "@SetPlot\n\n");
      fprintf(OutFile, "bop\n");
      fprintf(OutFile, "%%%%Page: %d %d\n", numpages+1, numpages+1);
}

/* Sets the printer to text mode */
void pstext()
{
}

/* Sets the printer to graphics mode */
void psgraph()
{
}

/* Form feed */
void psclear()
{
     fprintf(OutFile," S\neop\nbop\n");
}

static PLINT xlast, ylast;

void pspage()
{
     numpages++;
     fprintf(OutFile, "%%%%Page: %d %d\n", numpages+1, numpages+1);
     linepos = 0;
     xlast = -100000; ylast = -100000;
}

/* May put something here someday */
void pscolor(colour)
int colour;
{
}

/* I don't know what to put here - Tony */
void pswidth()
{
}

void psline(x1,y1,x2,y2)
PLINT x1,y1,x2,y2;
{
      if (linepos + 21 > LINELENGTH) {
          putc('\n', OutFile);
          linepos = 0;
      } else
          putc(' ', OutFile);

      if(!orient) {
         if(x1 == xlast && y1 == ylast)
            fprintf(OutFile, "%ld %ld D", x2, y2);
         else
            fprintf(OutFile, "Z %ld %ld M %ld %ld D", x1, y1, x2, y2);
      }
      else {
         if(x1 == xlast && y1 == ylast)
            fprintf(OutFile, "%ld %ld D", PSX-y2, x2);
         else
            fprintf(OutFile, "Z %ld %ld M %ld %ld D", PSX-y1,x1,PSX-y2,x2);
      }

      xlast = x2;
      ylast = y2;
      linepos += 21;
}

/* Close graphics file */
void pstidy()
{
      fprintf(OutFile," S\neop\n");
      numpages++;
      fprintf(OutFile, "@end\n\n");
      fprintf(OutFile, "%%%%Trailer\n");
      fprintf(OutFile, "%%%%Pages: %d\n", numpages);
      fclose(OutFile);
      numpages = 0;
      linepos = 0;
}

/* Get the date and time */
static char *getdate()
{
        int len;
        long t, time();
        char *p, *ctime();

        t = time((long *) 0);
        p = ctime(&t);
        len = strlen(p);
        *(p + len - 1) = '\0';  /* zap the newline character */
        return p;
}
