# include "Ximage.h"

/*** this function uses only private colormaps.  it should try the standard colormap
     first to get better control over the smooth greyscales ***/

int SetColormap (char *name) {

  int i;
  Graphic *graphic;

  graphic = GetGraphic();

  /* greyscale */
  if ((!strcmp (name, "grayscale")) || (!strcmp (name, "greyscale"))) {
    for (i = 0; i < graphic[0].Npixels; i++) {  
      graphic[0].cmap[i].red = 256*(255 - 255*i/graphic[0].Npixels);
      graphic[0].cmap[i].green = 256*(255 - 255*i/graphic[0].Npixels);
      graphic[0].cmap[i].blue = 256*(255 - 255*i/graphic[0].Npixels);
      graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
    }
    goto store_colors;
  }
  /* heat */
  if (!strcmp (name, "Puns")) {
    for (i = 0; i < (int)(0.25*graphic[0].Npixels); i++) {  
      graphic[0].cmap[i].green = 0;
      graphic[0].cmap[i].blue = 0;
      graphic[0].cmap[i].red = MIN (256*255, 256*255*2*i/(1.0*graphic[0].Npixels));  
      graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
    }
    for (i = (int)(0.25*graphic[0].Npixels); i < (int)(0.50*graphic[0].Npixels); i++) {  
      graphic[0].cmap[i].red = MIN (256*255, 256*255*2*i/(1.0*graphic[0].Npixels));
      graphic[0].cmap[i].green = MIN (256*255, 256*255*2*(i/(1.0*graphic[0].Npixels) - 0.25));
      graphic[0].cmap[i].blue = 0;
      graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
    }
    for (i = (int)(0.50*graphic[0].Npixels); i < (int)(0.75*graphic[0].Npixels); i++) {  
      graphic[0].cmap[i].red = 256*255;
      graphic[0].cmap[i].green = MIN (256*255, 256*255*2*(i/(1.0*graphic[0].Npixels) - 0.25));
      graphic[0].cmap[i].blue = MIN (256*255, 256*255*2*(i/(1.0*graphic[0].Npixels) - 0.50));
      graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
    }
    for (i = (int)(0.75*graphic[0].Npixels); i < graphic[0].Npixels; i++) {  
      graphic[0].cmap[i].red = 256*255;
      graphic[0].cmap[i].green = 256*255;
      graphic[0].cmap[i].blue = MIN (256*255, 256*255*2*(i/(1.0*graphic[0].Npixels) - 0.50));
      graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
    }
    goto store_colors;
  }
  /* -grayscale */
  if ((!strcmp (name, "-grayscale")) || (!strcmp (name, "-greyscale"))) {
    for (i = 0; i < graphic[0].Npixels; i++) {  
      graphic[0].cmap[i].red = 256*(255*i/graphic[0].Npixels);
      graphic[0].cmap[i].green = 256*(255*i/graphic[0].Npixels);
      graphic[0].cmap[i].blue = 256*(255*i/graphic[0].Npixels);
      graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
    }
    goto store_colors;
  }
  /* rainbow */
  if (!strcmp (name, "Rainbow")) {
    for (i = 0; i < (int)(0.25*graphic[0].Npixels); i++) {  
      graphic[0].cmap[i].red = 0;
      graphic[0].cmap[i].green = 0;
      graphic[0].cmap[i].blue = 256*(255*4*(i/(1.0*graphic[0].Npixels)));  
      graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
    }
    for (i = (int)(0.25*graphic[0].Npixels); i < (int)(0.50*graphic[0].Npixels); i++) {  
      graphic[0].cmap[i].red = 256*(255*4*((i/(1.0*graphic[0].Npixels)) - 0.25));
      graphic[0].cmap[i].green = 0;
      graphic[0].cmap[i].blue = 256*(255*4*(0.50 - (i/(1.0*graphic[0].Npixels))));
      graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
    }
    for (i = (int)(0.50*graphic[0].Npixels); i < (int)(0.75*graphic[0].Npixels); i++) {  
      graphic[0].cmap[i].red = 256*255;
      graphic[0].cmap[i].green = 256*(255*4*((i/(1.0*graphic[0].Npixels)) - 0.50));
      graphic[0].cmap[i].blue = 0;
      graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
    }
    for (i = (int)(0.75*graphic[0].Npixels); i < graphic[0].Npixels; i++) {  
      graphic[0].cmap[i].red = 256*255;
      graphic[0].cmap[i].green = 256*255;
      graphic[0].cmap[i].blue = 256*(255*4*((i/(1.0*graphic[0].Npixels)) - 0.75));
      graphic[0].cmap[i].flags = DoRed | DoGreen | DoBlue;
    }
    goto store_colors;
  }
  return (FALSE);

 store_colors:
  if (!USE_XWINDOW) return (TRUE);
  if (graphic[0].visualclass) {
    XStoreColors(graphic[0].display, graphic[0].colormap, graphic[0].cmap, graphic[0].Npixels);
  } else {
    for (i = 0; i < graphic[0].Npixels; i++) {
      if (XAllocColor (graphic[0].display, graphic[0].colormap, &graphic[0].cmap[i]) == 0) {
	fprintf (stderr, "error on %d\n", i);
      }
    }
  }
  return (TRUE);
}

