#include <SDL2/SDL.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <stdint.h>

uint32_t xorshift32(uint32_t *state) {
        uint32_t x = *state;
        x ^= x << 13;
        x ^= x >> 17;
        x ^= x << 5;
        return *state = x;
}

main() {
	SDL_Window *window = NULL;
	SDL_Renderer *renderer = NULL;

	int width, height, x, y, i, j, r1, g1, b1;
	int running = 1;
	uint8_t r, g, b;
	uint32_t rand, start_time, frame_time;
	double fps;

	int steps = 10000;

	uint32_t state = (uint32_t)time(NULL);
	if (state == 0) {
		state = 1;
	}

	SDL_Event event;

	if (SDL_Init(SDL_INIT_VIDEO) != 0) {
		printf("Init error: ");
		printf("%s \n", SDL_GetError());
		return 1;
	}

	window = SDL_CreateWindow(
		"whitenoise",
		SDL_WINDOWPOS_CENTERED,
		SDL_WINDOWPOS_CENTERED,
		0,
		0,
		SDL_WINDOW_FULLSCREEN_DESKTOP	
	);

	if (window == NULL) {
		printf("Window creation error: ");
		printf("%s \n", SDL_GetError());
		SDL_Quit();
		return 1;
	}

	SDL_GetWindowSize(window, &width, &height);

	renderer = SDL_CreateRenderer(
		window,
		-1,
		SDL_RENDERER_SOFTWARE
	);

	if (renderer == NULL) {
		printf("Renderer creation error: ");
		printf("%s \n", SDL_GetError());
		SDL_DestroyWindow(window);
		SDL_Quit();
		return 1;
	}

	SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
	SDL_RenderClear(renderer);
	SDL_RenderPresent(renderer);

	x = width / 2;
	y = height / 2;

	r = r1 = 245;
       	g = g1 = 169;
	b = b1 = 184;

	j = steps;

	SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);


	start_time = SDL_GetTicks(); 

	while (running) {
		while (SDL_PollEvent(&event)) {
			if (event.type == SDL_QUIT) {
				running = 0;
			}
		}

		rand = xorshift32(&state);
		r1 += ((rand >> 24) % 5) - 2;
		g1 += ((rand >> 16) % 5) - 2;
		b1 += ((rand >>  8) % 5) - 2;

		if (r1 < 0)
			r1 = 0;
		if (r1 > 255)
			r1 = 255;
		if (g1 < 0)
			g1 = 0;
		if (g1 > 255)
			g1 = 255;
		if (b1 < 0)
			b1 = 0;
		if (b1 > 255)
			b1 = 255;

		r = r1;
		g = g1;
		b = b1;

		i  = rand & 7;

		switch (i) {
			case 0:
				x --;
				y --;
				break;
			case 1:
				y --;
				break;
			case 2:
				x ++;
				y --;
				break;
			case 3:
				x --;
				break;
			case 4:
				x ++;
				break;
			case 5:
				x --;
				y ++;
				break;
			case 6:
				y ++;
				break;
			case 7:
				x ++;
				y ++;
				break;
		}

		if (x < 0)
			x = width + x;
		if (x >= width)
			x -= width;
		if (y < 0)
			y = height + y;
		if (y >= height)
			y -= height;

		SDL_SetRenderDrawColor(renderer, r, g, b, 255);
		SDL_RenderDrawPoint(renderer, x, y);	

		if (j == steps) {
			SDL_RenderPresent(renderer);
			SDL_SetRenderDrawColor(renderer, 0, 0, 0, 1);
			SDL_RenderFillRect(renderer, NULL);
			frame_time = SDL_GetTicks()-start_time;
			fps = (frame_time > 0) ? 1000 / frame_time : 0;
			printf("FPS: %f", fps);
		}
		j --;
		if (j < 0)
			j = steps;
			start_time = SDL_GetTicks(); 
	}	

	SDL_DestroyRenderer(renderer);
	SDL_DestroyWindow(window);
	SDL_Quit();

	return 0;
}
