#include "scaler.h"
#include "error.h"
#include "framebuffer.h"
#include "gl.h"
#include "shader.h"
#include "shaders.h"

void sw_scaler_apply(
    i32 scaler, struct sw_vec2i in_size, struct sw_vec2i out_size
) {
	(void)in_size;
	(void)out_size;
	f32 scalex, scaley, scale, xoff, yoff;

	switch(scaler) {
	case SW_SCALE_STRETCH:
		sw_shaderprogram_use(sw_shaders_copy);
		break;
	case SW_SCALE_ASPECT:
		sw_shaderprogram_use(sw_shaders_scale);
		scalex = (f32)out_size.x / (f32)in_size.x;
		scaley = (f32)out_size.y / (f32)in_size.y;
		scale = f32_min(scalex, scaley);

		xoff = (out_size.x - in_size.x * scale) / 2 / out_size.x;
		yoff = (out_size.y - in_size.y * scale) / 2 / out_size.y;
		glUniform2f(
		    glGetUniformLocation(sw_shaders_scale._program, "offset"),
		    xoff,
		    yoff
		);
		glUniform2f(
		    glGetUniformLocation(sw_shaders_scale._program, "size_ratio"),
		    (f32)out_size.x / (f32)in_size.x / scale,
		    (f32)out_size.y / (f32)in_size.y / scale
		);
		break;
	case SW_SCALE_INTEGER:
		sw_shaderprogram_use(sw_shaders_scale);
		scalex = (f32)out_size.x / (f32)in_size.x;
		scaley = (f32)out_size.y / (f32)in_size.y;
		scale = f32_min(scalex, scaley);
		scale = i32_max(1, (i32)scale);

		xoff = (out_size.x - in_size.x * scale) / 2 / out_size.x;
		yoff = (out_size.y - in_size.y * scale) / 2 / out_size.y;
		glUniform2f(
		    glGetUniformLocation(sw_shaders_scale._program, "offset"),
		    xoff,
		    yoff
		);
		glUniform2f(
		    glGetUniformLocation(sw_shaders_scale._program, "size_ratio"),
		    (f32)out_size.x / (f32)in_size.x / scale,
		    (f32)out_size.y / (f32)in_size.y / scale
		);
		break;
	default:
		sw_error("unknown scaler %i", scaler);
	}
	sw_framebuffer_render(0);
}
