#pragma once

using namespace glm;

#include "FastNoiseLite.h"

struct Rng{
	uint32_t seed;
	


	Rng(uint32_t _seed = 1251234u);

	uint32_t hash_u();
	glm::uvec2 hash_u2();
	glm::uvec3 hash_u3();
	glm::uvec4 hash_u4();

	float hash_f();
	glm::vec2 hash_v2();
	glm::vec3 hash_v3();
	glm::vec4 hash_v4();
	

	static float hash_f_seeded(uint32_t seed);
	static glm::vec2 hash_v2_seeded(uint32_t seed);
	static glm::vec3 hash_v3_seeded(uint32_t seed);
	static glm::vec4 hash_v4_seeded(uint32_t seed);
	
	static uint32_t hash_u_seeded(uint32_t _a);
	static glm::uvec2 hash_u2_seeded(uint32_t _a);
	static glm::uvec3 hash_u3_seeded(uint32_t _a);
	static glm::uvec4 hash_u4_seeded(uint32_t _a);
	
	// glm::uvec2 Rng::hash_u2() {return glm::uvec2(hash_u(), hash_u()); }
	// glm::uvec3 Rng::hash_u3() {return glm::uvec3(hash_u(), hash_u(), hash_u()); }
	// glm::uvec4 Rng::hash_u4() { return glm::uvec4(hash_u(), hash_u(), hash_u(), hash_u()); }

	float hash11(float p);
	float hash12(vec2 p);
	float hash13(vec3 p3);
	float hash14(vec4 p4);
	vec2 hash21(float p);
	vec2 hash22(vec2 p);
	vec2 hash23(vec3 p3);
	vec3 hash31(float p);
	vec3 hash32(vec2 p);
	vec3 hash33(vec3 p3);
	vec4 hash41(float p);
	vec4 hash42(vec2 p);
	vec4 hash43(vec3 p);
	vec4 hash44(vec4 p4);
};




namespace Noise {
	enum class Type{
		Perlin,
		Simplex,
		Voronoi,
		Value
	};
	struct NoiseDesc{
		Type type = Type::Value;
		int octaves = 1;
		float lacunarity = 1.0f;
		int seed = 1245124;
	};
	float get_noise_2d(glm::vec2 p, NoiseDesc desc);

	float get_noise_3d(glm::vec3 p, NoiseDesc desc);
};
