shader_type canvas_item;
uniform int num_colors: hint_range(2,32) = 8;
uniform sampler2D PALETTE_TEXTURE: hint_default_black;
uniform sampler2D PALETTE_TEXTURE_LOW: hint_default_black;

uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;

uniform int u_dither_size = 4;

vec3 palette_limiter (in vec3 albedo, in vec2 uv){
	float estimation_cutoff = 0.001;
	vec3 closest_color;
	float min_dist = 2.0;
	float n = float(num_colors);
	
	bool palette_low = (int(uv.y)) % 2 == 0;
	
	for (int i=0; i<num_colors; i++ ){
		float index = 1.000/(2.000*n)+float(i)/n;
		vec3 index_color = texture(PALETTE_TEXTURE, vec2(index,0.5)).rgb;
		float dist = length(index_color - albedo);
		if (dist < min_dist) {
			min_dist = dist;
			if(palette_low){
				closest_color = texture(PALETTE_TEXTURE_LOW, vec2(index,0.5)).rgb;
			}else{
				closest_color = index_color;
			}
			if (min_dist < estimation_cutoff){
				return closest_color;
			}
		}
	}

	return closest_color;
}

void fragment() {
	vec2 screen_size = vec2(textureSize(SCREEN_TEXTURE, 0)) / float(u_dither_size);
	vec2 uv_cord = floor(UV * screen_size);
	vec2 screen_sample_uv = uv_cord / screen_size;
	vec3 current_color = texture(SCREEN_TEXTURE, screen_sample_uv).rgb;
	
	COLOR.rgb = palette_limiter(current_color, uv_cord);
}