//
// Created by vlad on 23.03.23.
//

#include "Camera.h"
#include "Window.h"

#include <glm/ext.hpp>

using namespace glm;

Camera::Camera(vec3 position, float fov) : position(position), fov(fov), rotation(1.0f) {
    updateVectors();
}

void Camera::updateVectors(){
    front = vec3(rotation * vec4(0,0,-1,1));
    right = vec3(rotation * vec4(1,0,0,1));
    up = vec3(rotation * vec4(0,1,0,1));
    dir = vec3(rotation * vec4(0,0,-1,1));
    dir.y = 0;
    float len = length(dir);
    if (len > 0.0f){
        dir.x /= len;
        dir.z /= len;
    }
}

void Camera::rotate(float x, float y, float z){
    rotation = glm::rotate(rotation, z, vec3(0,0,1));
    rotation = glm::rotate(rotation, y, vec3(0,1,0));
    rotation = glm::rotate(rotation, x, vec3(1,0,0));

    updateVectors();
}

mat4 Camera::getProjection(){
    float as = this->aspect;
    if (as == 0.0f){
        as = (float)Window::width / (float)Window::height;
    }
    if (perspective)
        return glm::perspective(fov, as, 0.05f, 1500.0f);
    else
    if (flipped)
        return glm::ortho(0.0f, fov * as, fov, 0.0f);
    else
        return glm::ortho(0.0f, fov * as, 0.0f, fov);
}

mat4 Camera::getView(){
    if (perspective)
        return glm::lookAt(position, position+front, up);
    else
        return glm::translate(glm::mat4(1.0f), position);
}

