#include "Camera.hpp"

#include <glm/gtc/matrix_transform.hpp>
#include "../render/Window.hpp"
#include "core/geometry/math.hpp"

std::pair<world::cell_pos, world::offset_pos> Camera::Split(const world::world_pos& p) {
	constexpr auto MOD = glm::uvec3(glm::IDX_LENGTH2);
	const auto offset = glm::divide(p, MOD);
	return {offset, p - (world::world_pos)offset};
}

Camera::Camera(const world::world_pos* absolute, const Controllable* origin, const Camera::options& opt) {
	setOrigin(absolute, origin);
	setOptions(opt);
}
Camera::~Camera() { }

void Camera::updateProjection() {
	ProjectionMatrix = glm::perspective(o.fov, Window::RATIO, o.near_dist, o.far_dist);
}

void Camera::update() {
	const auto &offset = Split(*absolute).second;
	// FIXME: up inverted after backflip
	const auto axis = origin->getAxis();
	// Camera matrix
	ViewMatrix = glm::lookAt(
		offset,			         // Camera is here
		offset + axis.direction, // and looks here : at the same position, plus "direction"
		axis.up					 // Head is up (set to 0,-1,0 to look upside-down)
	);
}