#include "camera.h"
#include "render.h"
#include <glm/gtc/matrix_transform.hpp>

namespace render
{

Camera::Camera() noexcept
{
    this->screenSize = vec2f{960, 544};
    this->scale = vec3f(1);
}

void Camera::Bind() noexcept
{
    this->Math();
    render::BindCamera(this);
}

const float *Camera::GetProj() const noexcept
{
    return &this->proj[0][0];
}

const float *Camera::GetView() const noexcept
{
    return &this->view[0][0];
}

const float *Camera::GetProjView() const noexcept
{
    return &this->projView[0][0];
}

void Camera::Math() noexcept
{
    vec2f size = screenSize, off = offset;
    vec2f ssize{960, 544};
    if (size.x == 0)
        size.x = ssize.x;
    if (size.y == 0)
        size.y = ssize.y;

    if (screenSize.x == -1 || screenSize.y == -1) {
        if (size.x == -1) {
            size.x = size.y * (ssize.x / ssize.y);
        } else if (size.y == -1) {
            size.y = size.x * (ssize.y / ssize.x);
        }
    }

    if (offset.x == -1 && offset.y == -1) {
        off = size * -1;
    }

    this->proj = glm::ortho(off.x, size.x, size.y, off.y);
    this->proj = glm::scale(this->proj, glm::vec3(scale.x, scale.y, scale.z));

    this->view = glm::mat4(1);

    this->view = glm::rotate(this->view, (float)(rotation.x * DTOR), glm::vec3(1, 0, 0));
    this->view = glm::rotate(this->view, (float)(rotation.y * DTOR), glm::vec3(0, 1, 0));
    this->view = glm::rotate(this->view, (float)(rotation.z * DTOR), glm::vec3(0, 0, 1));

    this->view = glm::translate(this->view, glm::vec3(position.x, position.y, 0));

    this->projView = glm::transpose(this->proj * this->view);
}

} // namespace render
