# include "Ximage.h"
/* Notice: we are using a fixed border size of 10 pt */
void ConvertPixmap8  (Layout *layout, FILE *f);
void ConvertPixmap16 (Layout *layout, FILE *f);
void ConvertPixmap24 (Layout *layout, FILE *f);
void ConvertPixmap32 (Layout *layout, FILE *f);

int PSit (Graphic *graphic, Layout *layout, int Raw) {
  
  FILE *f;
  int i;
  double scale;
  char filename[1024];
  int Nbytes, status;

  /* expect a line telling the number of bytes and a filename */
  status = read (layout[0].Ximage, filename, 16);
  filename[16] = 0;
  sscanf (filename, "%*s %d", &Nbytes);
  status = read (layout[0].Ximage, filename, Nbytes);
  filename[status] = 0; /* make the string easy to parse */

  f = fopen (filename, "w");
  if (f == (FILE *) NULL) {
    fprintf (stderr, "failed to open %s for output\n", filename);
    return (TRUE);
  }
  
  scale = MIN ((500.0/(double)layout[0].picture.dx), (700.0/(double)layout[0].picture.dy));
  if (!Raw) {
    fprintf (f, "%%!PS-Adobe-2.0 EPSF-2.0\n");
    fprintf (f, "%%%%Title: %s\n", layout[0].file);
    fprintf (f, "%%%%Creator: Ki'i (0.95)\n");
    fprintf (f, "%%%%BoundingBox: 10 40 %d %d \n", (int)(scale*layout[0].picture.dx + 30), (int)(scale*layout[0].picture.dy + 60));
    fprintf (f, "%%%%Pages: 1\n");
    fprintf (f, "%%%%DocumentFonts:\n");
    fprintf (f, "%%%%EndComments\n");
    fprintf (f, "%%%%EndProlog\n");
    fprintf (f, "%%%%Page: 1 1\n\n");

  }

  fprintf (f, "gsave %% encloses picture\n");
  fprintf (f, "%% local abbreviations\n");
  fprintf (f, "/Times-Roman findfont 18 scalefont setfont\n");
  fprintf (f, "/T {moveto show stroke} def\n");
  fprintf (f, "/B { newpath moveto dup 0 exch rlineto exch dup 0 rlineto exch -1 mul\n");
  fprintf (f, " 0 exch rlineto -1 mul 0 rlineto closepath stroke } def\n");
  fprintf (f, "/C {0 360 arc stroke} def\n");
  fprintf (f, "/L {newpath moveto lineto stroke} def\n\n");

  if (!Raw) {
    fprintf (f, " 20 50 translate\n");
    fprintf (f, "  %f  %f scale\n", scale, scale);
  }

  fprintf (f, " newpath 0 0 moveto %d 0 lineto %d %d lineto 0 %d lineto closepath clip\n\n", 
	   layout[0].picture.dx, layout[0].picture.dx, layout[0].picture.dy, layout[0].picture.dy);
  fprintf (f, "gsave %% encloses image\n");
  fprintf (f, "%d %d 8\n", layout[0].picture.dx, layout[0].picture.dy);
  fprintf (f, "[1 0 0 1 0 0]\n");
  fprintf (f, "{currentfile %d string readhexstring pop} image\n\n", layout[0].picture.dx);

  /******** First we draw the picture itself ********/
  switch (graphic[0].Nbits) {
  case 8:
    ConvertPixmap8 (layout, f);
    break;
  case 16:
    ConvertPixmap16 (layout, f);
    break;
  case 24:
    ConvertPixmap24 (layout, f);
    break;
  case 32:
    ConvertPixmap32 (layout, f);
    break;
  }

  fprintf (f, "grestore %% end of image\n");
  fprintf (f, "stroke\n");
  fprintf (f, "%% plot overlay objects\n");
  fprintf (f, "1 setgray\n");

  for (i = 0; i < NOVERLAYS; i++) {
    if (OVERLAY[i]) {
      fprintf (f, "%% overlay %d\n", i);
      DrawOverlay (graphic, layout, i, f, 0);
    }
  }
  fprintf (f, "0 setgray\n");
  for (i = 0; i < NOVERLAYS; i++) {
    if (OVERLAY[i]) {
      fprintf (f, "%% overlay %d\n", i);
      DrawOverlay (graphic, layout, i, f, 1);
    }
  }
  
  fprintf (f, "grestore %% end of picture\n");

  if (!Raw) fprintf (f, "showpage\n");

  fclose (f);

  return (TRUE);

}

void ConvertPixmap8 (Layout *layout, FILE *f) {

  int i, k, m, val;
  double Nchar, Npix, start, slope, frac;
  char *buff;

  Nchar = 255.0;
  Npix = layout[0].Npixels;
  frac = Nchar / Npix;
  /* start at the last line, print lines in decending order */
  buff = (unsigned char *)layout[0].picture.data + layout[0].picture.dx*(layout[0].picture.dy - 1);
  slope = layout[0].slope;
  start = layout[0].start;

  for (i = 0; i < layout[0].picture.dy; i++) {
    for (k = 0; k < layout[0].picture.dx; k++, buff++) {
      if (*buff == layout[0].white) 
	val = Nchar;
      else {
	for (m = 0; (layout[0].cmap[m].pixel != *buff) && (m < Npix); m++);
	val = Nchar - frac * MIN (MAX (start + m * slope, 0), Npix);
      }
      fprintf (f, "%02x", val);
      if (!((k+1) % 40)) fprintf (f, "\n"); 
    }
    fprintf (f, "\n");
    buff -= 2*layout[0].picture.dx;
  }
  return;
}

void ConvertPixmap16 (Layout *layout, FILE *f) {

  int i, k, m, val;
  double Nchar, Npix, start, slope, frac;
  unsigned short *buff;

  Nchar = 255.0;
  Npix = layout[0].Npixels;
  frac = Nchar / Npix;
  /* start at the last line, print lines in decending order */
  buff = (unsigned short *)layout[0].picture.data + layout[0].picture.dx*(layout[0].picture.dy - 1);
  slope = layout[0].slope;
  start = layout[0].start;

  for (i = 0; i < layout[0].picture.dy; i++) {
    for (k = 0; k < layout[0].picture.dx; k++, buff++) {
      if (*buff == layout[0].white) 
	val = Nchar;
      else {
	for (m = 0; (layout[0].cmap[m].pixel != *buff) && (m < Npix); m++);
	val = Nchar - frac * MIN (MAX (start + m * slope, 0), Npix);
      }
      fprintf (f, "%02x", val);
      if (!((k+1) % 40)) fprintf (f, "\n"); 
    }
    fprintf (f, "\n");
    buff -= 2*layout[0].picture.dx;
  }
  return;
}

void ConvertPixmap24 (Layout *layout, FILE *f) {

  int i, k, m, dx, dy, val, extra;
  unsigned char *buff;
  unsigned long color, byte;
  double Nchar, Npix, start, slope, frac;

  Nchar = 255.0;
  Npix = layout[0].Npixels;
  frac = Nchar / Npix;
  dx = layout[0].picture.dx;
  dy = layout[0].picture.dy;
  extra = 4 - (dx * 3) % 4;
  /* start at the last line, print lines in decending order */
  buff = &layout[0].picture.data[(dy - 1)*(3*dx + extra)];
  slope = layout[0].slope;
  start = layout[0].start;

  for (i = 0; i < dy; i++) {
    for (k = 0; k < dx; k++, buff+=3) {
      color = 0;
      byte = buff[2];
      color = (byte << 16);
      byte = buff[1];
      color |= (byte << 8);
      byte = buff[0];
      color |= byte;
      for (m = 0; (layout[0].cmap[m].pixel != color) && (m < Npix); m++);
      val = Nchar - frac * MIN (MAX (start + m * slope, 0), Npix);
      fprintf (f, "%02x", val);
      if (!((k+1) % 40)) fprintf (f, "\n"); 
    }
    fprintf (f, "\n");
    buff -= 2*3*dx + extra;
  }
  return;
}

void ConvertPixmap32 (Layout *layout, FILE *f) {

  int i, k, m, val;
  double Nchar, Npix, start, slope, frac;
  unsigned int *buff;

  Nchar = 255.0;
  Npix = layout[0].Npixels;
  frac = Nchar / Npix;
  /* start at the last line, print lines in decending order */
  buff = (unsigned int *)layout[0].picture.data + layout[0].picture.dx*(layout[0].picture.dy - 1);
  slope = layout[0].slope;
  start = layout[0].start;

  for (i = 0; i < layout[0].picture.dy; i++) {
    for (k = 0; k < layout[0].picture.dx; k++, buff++) {
      if (*buff == layout[0].white) 
	val = Nchar;
      else {
	for (m = 0; (layout[0].cmap[m].pixel != *buff) && (m < Npix); m++);
	val = Nchar - frac * MIN (MAX (start + m * slope, 0), Npix);
      }
      fprintf (f, "%02x", val);
      if (!((k+1) % 40)) fprintf (f, "\n"); 
    }
    fprintf (f, "\n");
    buff -= 2*layout[0].picture.dx;
  }
  return;
}
