#include "aliases.h"
#include "ppm.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct {
  u64 x;
  u64 y;
  u64 z;
  u64 w;
} XORShiftBasic;

u64 xor_shift_basic_generate(XORShiftBasic *state);

int main(int argc, char *argv[]) {
  struct timespec ts = {0};
  clock_gettime(CLOCK_MONOTONIC_RAW, &ts);

  srand48(ts.tv_nsec);

  XORShiftBasic state = {
      .x = lrand48(),
      .y = lrand48(),
      .z = lrand48(),
      .w = lrand48(),
  };

  u64 w = 1024;
  u64 h = 1024;
  u64 length = w * h;

  Pixel data[length];
  for (u64 y = 0; y < h; ++y) {
    for (u64 x = 0; x < w; ++x) {
      u64 i = y * w + x;

      u8 pixel = xor_shift_basic_generate(&state) % UINT8_MAX;
      data[i] = (Pixel){
          .r = pixel,
          .g = pixel,
          .b = pixel,
      };
    }
  }

  write_p6_ppm("./outputs/xorshift.ppm", w, h, data);

  return EXIT_SUCCESS;
}

u64 xor_shift_basic_generate(XORShiftBasic *state) {
  u64 t = state->x ^ (state->x << 11);

  state->x = state->y;
  state->y = state->z;
  state->z = state->w;
  state->w = (state->w ^ (state->w >> 19)) ^ (t ^ (t >> 8));

  return state->w;
}