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

void hsv2rgb(double h, double s, double v, int *red, int *grn, int *blu) {
  double i, f, p, q, t, r, g, b;
  int ii;
  if (s == 0.0) { r = g = b = v; } else {
    h = 6 * (h - floor(h));
    ii = i = floor(h);
    f = h - i;
    p = v * (1 - s);
    q = v * (1 - (s * f));
    t = v * (1 - (s * (1 - f)));
    switch(ii) {
      case 0: r = v; g = t; b = p; break;
      case 1: r = q; g = v; b = p; break;
      case 2: r = p; g = v; b = t; break;
      case 3: r = p; g = q; b = v; break;
      case 4: r = t; g = p; b = v; break;
      default:r = v; g = p; b = q; break;
    }
  }
  *red = fmin(fmax(255 * r + 0.5, 0), 255);
  *grn = fmin(fmax(255 * g + 0.5, 0), 255);
  *blu = fmin(fmax(255 * b + 0.5, 0), 255);
}

int main() {
  int palette = 1024;
  unsigned char *ppm = malloc(3 * palette);
  for (int i = 0; i < palette; ++i) {
    double dim = 2 * (i + 0.5) / palette;
    double hue = dim < 1
      ? -1.0/12.0 * (1 - dim) +  dim      *  1.0/ 6.0
      :  1.0/ 6.0 * (2 - dim) + (dim - 1) * 11.0/12.0;
    double sat = dim / 2;
    double val = 0 <= dim && dim <= 2;
    int red, grn, blu;
    hsv2rgb(hue, sat, val, &red, &grn, &blu);
    ppm[3 * i + 0] = red;
    ppm[3 * i + 1] = grn;
    ppm[3 * i + 2] = blu;
  }
  int keys = 8;
  int keysize = palette / keys;
  for (int key = 0; key < keys; ++key) {
    char filename[100];
    snprintf(filename, 100, "j-dim-key-%d.ppm", key);
    FILE *f = fopen(filename, "wb");
    fprintf(f, "P6\n%d 32\n255\n", keysize);
    for (int j = 0; j < 32; ++j) {
      fwrite(ppm + 3 * keysize * key, 3 * keysize, 1, f);
    }
    fclose(f);
  }
  free(ppm);
  return 0;
}
