#pragma once

#include "glm/gtc/quaternion.hpp"
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/quaternion_float.hpp>
#include <glm/ext/quaternion_trigonometric.hpp>
#include <glm/mat4x4.hpp>
#include <glm/trigonometric.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>

namespace kuiper
{

namespace maths
{

    struct transform_quat {
        glm::vec3 position = {0.0f, 0.0f, 0.0f};
        glm::quat rotation = {1.0f, 0.0f, 0.0f, 0.0f};
        glm::vec3 scale    = {1.0f, 1.0f, 1.0f};

        glm::mat4 to_mat4() const noexcept {
            static constexpr glm::mat4 identity_mat = glm::mat4(1.0f);

            const glm::mat4 tm = glm::translate(identity_mat, position);
            const glm::mat4 rm = glm::mat4_cast(rotation);
            const glm::mat4 sm = glm::scale(identity_mat, scale);

            return tm * rm * sm;
        }
    };

    struct transform_euler {
        glm::vec3 position = {0.0f, 0.0f, 0.0f};
        glm::vec3 rotation = {0.0f, 0.0f, 0.0f};
        glm::vec3 scale    = {1.0f, 1.0f, 1.0f};

        glm::mat4 to_mat4() const noexcept {
            static constexpr glm::mat4 identity_mat = glm::mat4(1.0f);

            const glm::mat4 tm = glm::translate(identity_mat, position);
            const glm::mat4 rm = glm::mat4_cast(glm::quat(rotation));
            const glm::mat4 sm = glm::scale(identity_mat, scale);

            return tm * rm * sm;
        }
    };

} // namespace maths

} // namespace kuiper
