#pragma once



//#define WINDOWS_IGNORE_PACKING_MISMATCH
//#include <windows.h>
//
//#include "glew.h"
//#include "GL/gl.h"
//#include "glext.h"
//#include "wglext.h"


#include <bit>

#include "engine/definitions.h"

#include <algorithm>

#include <optional>
#include "nlohmann/json.hpp"

#include "SIMDString.h"
#include <variant>

#include <map>
#include <vector>
#include <unordered_map>


#include <stdio.h>
#include <initializer_list>
#include <string>
#include <regex>
#include <fstream>
#include <cstdint>
#include <filesystem>
#include <mutex>

#include <cmath>

// #include <embree4/rtcore.h>

#include "util/WArray.h"

#include <iostream>
#include <Jolt/Jolt.h>
#include "Jolt/Physics/Collision/ShapeCast.h"
#include "Jolt/Physics/Collision/CastResult.h"
#include "Jolt/Physics/Collision/CollisionCollectorImpl.h"
#include "Jolt/Physics/Collision/RayCast.h"
#include <Jolt/RegisterTypes.h>
#include <Jolt/Core/Memory.h>
#include <Jolt/Core/Factory.h>
#include <Jolt/Core/TempAllocator.h>
#include <Jolt/Core/JobSystemThreadPool.h>
#include <Jolt/Physics/Collision/EstimateCollisionResponse.h>
#include <Jolt/Physics/PhysicsSettings.h>
#include <Jolt/Physics/PhysicsSystem.h>
#include <Jolt/Physics/Collision/Shape/BoxShape.h>
#include <Jolt/Physics/Body/BodyActivationListener.h>
#include "Jolt/Physics/Body/BodyCreationSettings.h"
#include <Jolt/Core/TempAllocator.h>
#include <Jolt/Core/JobSystemThreadPool.h>
#include <Jolt/Physics/PhysicsSystem.h>
#include "Jolt/Physics/Collision/Shape/MeshShape.h"
#include "Jolt/Physics/Collision/Shape/ConvexHullShape.h"
#include "Jolt/Physics/Collision/Shape/ScaledShape.h"


// #include <Jolt/RegisterTypes.h>
// #include <Jolt/Core/Factory.h>
// #include <Jolt/Physics/PhysicsSettings.h>
// #include <Jolt/Physics/Collision/Shape/SphereShape.h>
// #include <Jolt/Physics/Body/BodyCreationSettings.h>
// #include <Jolt/Physics/Body/BodyActivationListener.h>
#include "Jolt/Physics/Collision/Shape/CapsuleShape.h"
#include "Jolt/Physics/Collision/Shape/SphereShape.h"

#include "imgui.h"
#include "backends/imgui_impl_opengl3.h"
#include "backends/imgui_impl_win32.h"
#include <imgui_internal.h>


#include "Tracy.hpp"
#include "TracyOpenGL.hpp"

#include "stb_image.h"


#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>



#include "assimp/cimport.h"

#include <vlc/vlc.h>
// #include <vlc/libvlc.h>
// #include <vlc/libvlc_media.h>
// #include <vlc/libvlc_media_player.h>

#include "include/gif_lib.h"


#include "util/smallvec.h"


#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/vec3.hpp> // glm::vec3
#include <glm/vec4.hpp> // glm::vec4
#include <glm/mat4x4.hpp> // glm::mat4
#include <glm/ext/matrix_transform.hpp> // glm::translate, glm::rotate, glm::scale
#include <glm/ext/matrix_clip_space.hpp> // glm::perspective
#include <glm/ext/scalar_constants.hpp> // glm::pi

inline glm::mat3 get_rot_mat(int axis, float radians) {
	glm::mat3 r = glm::mat3(
		1,0,0,
		0,1,0,
		0,0,1
	);

	float r1 = cos(radians);
	float r2 = -sin(radians);
	float r3 = -r2;

	float* a = &r[0][0];
	if (axis == 0) {
		a[3 * 1 + 1] *= r1;
		a[3 * 1 + 2] = r2;
		a[3 * 2 + 1] = r3;
		a[3 * 2 + 2] = r1;
	} else if (axis == 1) {
		a[3 * 0 + 0] = r1;
		a[3 * 0 + 2] = -r2;
		a[3 * 2 + 0] = -r3;
		a[3 * 2 + 2] = r1;
	} else if (axis == 2) {
		a[3 * 0 + 0] = r1;
		a[3 * 0 + 1] = r2;
		a[3 * 1 + 0] = r3;
		a[3 * 1 + 1] = r1;
	}
	return r;
}

namespace glm {
	inline glm::vec3 from_jph(JPH::Vec3 p){return glm::vec3(p.GetX(), p.GetY(), p.GetZ());}
	inline JPH::Vec3 to_jph(glm::vec3 p){return JPH::Vec3(p.x, p.y, p.z);}
	inline glm::quat from_jph(JPH::Quat q) {
		JPH::Vec4 p = q.GetXYZW();
		return glm::quat(p.GetW(),p.GetX(), p.GetY(), p.GetZ());
	}
	inline JPH::Quat to_jph(glm::quat p){return JPH::Quat(p.x, p.y, p.z, p.w);}
	inline glm::mat2 rot_mat(float a) {
		return glm::mat2(
			glm::cos(a), -glm::sin(a),
			glm::sin(a), glm::cos(a)
		);
	}



	// class vec3 {
	// 	public:
	// 	// Existing vec3 members and functions here
	//
	// 	// New member function: lerp_to
	// 	vec3 lerp_to(const vec3& end, float t) const {
	// 		return *this + t * (end - *this);
	// 	}
	// };
}


#include "FileWatch.hpp"

#include "Math.h"

#include <miniaudio.h>
#include <phonon.h>

#include <dbghelp.h>
#include "spdlog/spdlog.h"
#include "spdlog/common.h"
#include "engine/WLog.h"


#include "util/WArray.h"
#include "engine/WAlloc.h"
#include "WDumbMap.h"

#include "engine/sequencer/ImSequencer.h"
#include "engine/sequencer/ImCurveEdit.h"



