#include "renderer.h"

static void _renderer_viewport_window_set(Renderer* self);

/* Sets the renderer's viewport to the window. */
static void
_renderer_viewport_window_set(Renderer* self)
{
	ivec4 viewport;

	window_ivec4_get(self->window, viewport);

	glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
}

/* Initializes renderer. */
void
renderer_init(Renderer* self, Window* window, CameraType type, const vec2 size)
{
	memset(self, '\0', sizeof(Renderer));

	self->window = window;

	self->glContext = SDL_GL_CreateContext(self->window->sdl);

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	glew_init();

	vao_init(&self->vao);
	vbo_init(&self->vbo, GL_ARRAY_BUFFER, true);
	vbo_init(&self->ebo, GL_ELEMENT_ARRAY_BUFFER, true);
	
	glm_vec2_copy((f32*)size, self->size);

	switch (type)
	{
		case CAMERA_ORTHOGRAPHIC:
			camera_orthographic_init(&self->camera, self->size);
			break;
		default:
			break;
	}
}

/* Frees renderer. */
void
renderer_free(Renderer* self)
{
	memset(self, '\0', sizeof(Renderer));
	SDL_GL_DeleteContext(self->glContext);
}

/* Uses a specified shader. */
void
renderer_shader_use(Renderer* self, Shader* shader)
{
	shader_use(shader);
}

/* Sets the renderer clear color. */
void
renderer_clear_color_set(Renderer* self, vec4 color)
{
	glClearColor(color[0], color[1], color[2], color[3]);
}

/* Clears the renderer. */
void
renderer_clear(Renderer* self)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

/* Presents renderer. */
void
renderer_present(Renderer* self)
{
	SDL_GL_SwapWindow(self->window->sdl);
}

/* Updates renderer. */
void
renderer_update(Renderer* self)
{
	_renderer_viewport_window_set(self);
}

/* Window coords -> renderer coords. */
void
renderer_world_position_from_window_position
(
	Renderer* self, 
	vec2 windowPosition, 
	vec2 rendererPosition
)
{
	ivec2 windowSize;

	window_size_get(self->window, windowSize);

	rendererPosition[0] = (windowPosition[0] / windowSize[0]) * self->size[0];
	rendererPosition[1] = (windowPosition[1] / windowSize[1]) * self->size[1];
}
