#ifndef MISC_INCLUDED
#define MISC_INCLUDED

#include <common/aabb.hpp>
#include <common/node.hpp>
#include <common/objectbase.hpp>
#include <rofi/connector.hpp>
#include <utils/math.hpp>

#include <cmath>
#include <vector>

bool check_grid_alignment(node_ptr node);
node_ptr find_node_with_rofi_object(const std::vector<node_ptr> &nodes, objectbase_ptr object);

/* Returns a quat so that the connector's negative z-axis always faces away from the first connected voxel */
glm::quat get_connector_face_rotation(glm::vec3 local_direction);
/* Returns a quat that rotates a voxel's negative z-axis away from the shared connector  */
glm::quat get_shared_voxel_face_rotation(glm::vec3 local_direction);
/* Returns true when two nodes face each other on a given orthonormal axis ( first axis = -second axis ) */
bool face_each_other(node_ptr fst_node, node_ptr snd_node, glm::vec3 axis); 

bool AABB_intersect(const AABB &fst_aabb, const AABB &snd_aabb, const node_ptr &fst_node, const node_ptr &snd_node);

std::pair<std::size_t, std::size_t> get_pad_width_height_from_connector_count(const std::vector<connector_ptr> &connectors);

const glm::mat4 get_magic_matrix();

glm::vec3 convert_to_rofi_coordinates(const glm::vec3 &position);
glm::mat4 convert_to_rofi_coordinates(const glm::mat4 &matrix);

glm::vec3 convert_to_rofi_export_coordinates(const glm::vec3 &position, const glm::vec3 &to_voxel_center);
glm::mat4 convert_to_rofi_export_coordinates(const glm::mat4 &editor_matrix);

glm::vec3 convert_to_editor_coordinates(const glm::vec3 &rofi_position);
glm::mat4 convert_to_editor_import_coordinates(const glm::mat4 &rofi_matrix);

#endif