#pragma once

#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>
#include <iostream>

#include "mesh.h"

namespace kek {

template<typename ...Args>
using generic_function_t = void(*)(Args... args);

template<typename ...Args>
struct generic_callable_t {
	generic_function_t<Args..., void *> function;
	void *data;

	generic_callable_t(generic_function_t<Args..., void *> function, void *data): function(function), data(data) {}

	void operator()(Args... args) {
		function(args..., data);
	}
};

typedef generic_callable_t<> callable_t;

float clampCyclic(float value, float min, float max);

float clamp(float value, float min, float max);

float clampCyclic(int value, int min, int max);

float clamp(int value, int min, int max);

enum class CubeFace {
	FRONT, BACK, UP, DOWN, LEFT, RIGHT
};

glm::vec3 faceNormal(CubeFace face);

void genCubeVertices(float w, float h, float d, bool texCoords, float **outVerts, size_t *outSize, size_t *vertexCount);

std::vector<Vertex> genCubeVertices(float w, float h, float d, bool texCoords);

std::string toString(glm::vec3 vector);

}
