cmake_minimum_required(VERSION 3.21)
project(TSVDAG LANGUAGES CXX)

option(ENABLE_VULKAN_MEMORY_ALLOCATOR "Allocate GPU memory using VMA instead of calling cudaMalloc (faster)" TRUE)
option(ENABLE_TRACY "Enable traces for tracy profiler" FALSE)

option(ENABLE_CUDA "Enable CUDA support" ON)
option(ENABLE_TESTS "Enable CUDA support" ON)
option(ENABLE_WARNINGS_AS_ERRORS "Enable warnings as errors" TRUE)
option(ENABLE_ADDRESS_SANITIZER "Enable address sanitizer" FALSE)
option(ENABLE_MEMORY_SANITIZER "Enable memory sanitizer" FALSE)
option(ENABLE_THREAD_SANITIZER "Enable thread sanitizer" FALSE)
option(ENABLE_UNDEFINED_BEHAVIOR_SANITIZER "Enable undefined behavior sanitizer" FALSE)
option(ENABLE_GIT_COMMIT_IN_STATS "Store git commit hash in the stats output file" FALSE)
set(OPTIX_DIR "" CACHE PATH "Enable OptiX ray tracing")

add_library(project_options INTERFACE)
target_compile_features(project_options INTERFACE cxx_std_20)
if (ENABLE_CUDA)
    enable_language(CUDA)
    target_compile_features(project_options INTERFACE cuda_std_20)
    target_compile_options(project_options INTERFACE "$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:CUDA>>:-G>")
    target_compile_options(project_options INTERFACE "$<$<AND:$<CONFIG:RelWithDebInfo>,$<COMPILE_LANGUAGE:CUDA>>:-lineinfo>")
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CUDA>:--expt-relaxed-constexpr>")
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CUDA>:--extended-lambda>")
endif()

if (ENABLE_ADDRESS_SANITIZER)
    list(APPEND SANITIZERS "address")
endif()
if (ENABLE_MEMORY_SANITIZER)
    list(APPEND SANITIZERS "memory")
endif()
if (ENABLE_UNDEFINED_BEHAVIOR_SANITIZER)
    list(APPEND SANITIZERS "undefined")
endif()
if (ENABLE_THREAD_SANITIZER)
    list(APPEND SANITIZERS "thread")
endif()
if (SANITIZERS)
    list(JOIN SANITIZERS "," FSANITIZE)
    if (WIN32)
        target_compile_options(project_options INTERFACE "/fsanitize=${FSANITIZE}")
    else()
        target_compile_options(project_options INTERFACE "-fsanitize=${FSANITIZE}")
    endif()
endif()

if (WIN32)
	target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:/permissive->")
	target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:/W4>")
	target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-D_CRT_SECURE_NO_WARNINGS=1>")
	target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:/wd4996>")
    if (ENABLE_WARNINGS_AS_ERRORS)
        target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:/WX>")
    endif()
else()
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-Wall>")
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-Wextra>")
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-Wconversion>")
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-Wundef>")
    if (ENABLE_WARNINGS_AS_ERRORS)
        target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-Werror>")
    endif()
    #target_compile_options(project_options INTERFACE "$<$<CONFIG:Debug>:-march=native -g>")
    #target_compile_options(project_options INTERFACE "$<NOT:<$<CONFIG:Debug>>:-march=native -g -O3 -ffast-math>")

    # Ignore some warnings that add a lot of spam and aren't that critical:
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-Wno-unused-variable>")
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-Wno-unused-parameter>")
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-Wno-parentheses>")
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-Wno-terminate>")
    target_compile_options(project_options INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-msse4.1>")
endif()

find_path(LIBMORTON_INCLUDE_DIRS "libmorton/morton.h")
add_library(libmorton INTERFACE)
target_include_directories(libmorton INTERFACE ${LIBMORTON_INCLUDE_DIRS})
add_library(libmorton::libmorton ALIAS libmorton)

find_package(absl CONFIG REQUIRED)
find_package(assimp CONFIG REQUIRED)
find_package(CLI11 CONFIG REQUIRED)
find_package(date CONFIG REQUIRED)
find_package(EASTL CONFIG REQUIRED)
find_package(Eigen3 CONFIG REQUIRED)
find_package(fmt CONFIG REQUIRED)
find_package(freeimage CONFIG REQUIRED)
find_package(glm CONFIG REQUIRED)
find_package(GLEW REQUIRED)
find_package(glfw3 CONFIG REQUIRED)
find_package(imgui CONFIG REQUIRED)
find_package(magic_enum CONFIG REQUIRED)
find_package(mio CONFIG REQUIRED)
find_package(unofficial-nativefiledialog CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
find_package(OpenGL REQUIRED)
find_package(OpenMP REQUIRED)
find_package(robin_hood CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)
find_package(TBB CONFIG REQUIRED)
if (ENABLE_TRACY)
    find_package(Tracy CONFIG REQUIRED)
endif()
if (ENABLE_CUDA)
	find_package(CUDAToolkit REQUIRED)
	find_package(Thrust REQUIRED CONFIG)
	thrust_create_target(Thrust)
endif()
if (OPTIX_DIR)
  add_library(Optix INTERFACE)
  target_include_directories(Optix INTERFACE "${OPTIX_DIR}/include")
endif()

if (ENABLE_TESTS)
	enable_testing()
	find_package(Catch2 CONFIG REQUIRED)
	include(CTest)
	include(Catch)
endif()

if (ENABLE_GIT_COMMIT_IN_STATS)
    include(FetchContent)
    FetchContent_Declare(cmake_git_version_tracking                   
      GIT_REPOSITORY https://github.com/andrew-hardin/cmake-git-version-tracking.git
      GIT_TAG 904dbda1336ba4b9a1415a68d5f203f576b696bb
    )
    FetchContent_MakeAvailable(cmake_git_version_tracking)
endif()

add_subdirectory("tools")
add_subdirectory("renderer")
