cmake_minimum_required(VERSION 3.24)
project(LukasXEngine VERSION 1.7.0 LANGUAGES C CXX)
set(CMAKE_CXX_EXTENSIONS OFF)
if(PROJECT_IS_TOP_LEVEL AND NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
  set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>)
endif()
option(LUKASX_BUILD_DEMO "Build the Distrito 07 desktop demo" ${PROJECT_IS_TOP_LEVEL})
option(LUKASX_BUILD_RENDERER "Build the OpenGL renderer library" ${LUKASX_BUILD_DEMO})
option(LUKASX_BUILD_TESTS "Build the LukasX regression tests" ${PROJECT_IS_TOP_LEVEL})
if(LUKASX_BUILD_DEMO AND NOT LUKASX_BUILD_RENDERER)
  message(FATAL_ERROR "LUKASX_BUILD_DEMO requires LUKASX_BUILD_RENDERER")
endif()
include(FetchContent)
if(TARGET glm::glm)
  set(lukasx_glm_target glm::glm)
else()
  # GLM is header-only here. Populate the pinned archive without running its build.
  FetchContent_Declare(lukasx_glm_headers URL "${CMAKE_CURRENT_SOURCE_DIR}/vendor/glm-1.0.1.zip"
    URL_HASH SHA256=4ec6f4ce5d9c032f5cffdb92826301d5a7cab842d49c7171bffc1ae0542b7e74
    SOURCE_SUBDIR lukasx-no-cmake)
  FetchContent_MakeAvailable(lukasx_glm_headers)
  add_library(lukasx_glm INTERFACE)
  target_include_directories(lukasx_glm SYSTEM INTERFACE "${lukasx_glm_headers_SOURCE_DIR}")
  set(lukasx_glm_target lukasx_glm)
endif()
configure_file(cmake/version.hpp.in generated/lukasx/version.hpp @ONLY)
add_library(lukasx_core STATIC src/sim.cpp src/gameplay.cpp src/vehicles.cpp src/chassis.cpp src/traffic.cpp src/glass.cpp src/water.cpp src/damage.cpp src/npc.cpp src/ragdoll.cpp src/jobs.cpp
    src/dynamics.cpp src/rigid.cpp src/police.cpp src/revenge.cpp
    src/wrecks.cpp src/health.cpp src/arrest.cpp src/guns.cpp
    src/terrain.cpp src/forest.cpp)
find_package(Threads REQUIRED)
add_library(LukasX::Core ALIAS lukasx_core)
target_include_directories(lukasx_core PUBLIC include src "${CMAKE_CURRENT_BINARY_DIR}/generated")
target_compile_features(lukasx_core PUBLIC cxx_std_17)
target_link_libraries(lukasx_core PUBLIC ${lukasx_glm_target} Threads::Threads)
if(MSVC)
  target_compile_options(lukasx_core PRIVATE /W4 /utf-8)
endif()
if(LUKASX_BUILD_RENDERER)
  add_library(lukasx_gl STATIC vendor/glad/src/gl.c)
  target_include_directories(lukasx_gl PUBLIC vendor/glad/include)
  add_library(lukasx_renderer STATIC src/render.cpp)
  add_library(LukasX::Renderer ALIAS lukasx_renderer)
  target_link_libraries(lukasx_renderer PUBLIC LukasX::Core lukasx_gl)
  if(MSVC)
    target_compile_options(lukasx_renderer PRIVATE /W4 /utf-8)
  endif()
endif()
if(LUKASX_BUILD_DEMO)
  if(NOT TARGET glfw)
    set(GLFW_BUILD_DOCS OFF)
    set(GLFW_BUILD_TESTS OFF)
    set(GLFW_BUILD_EXAMPLES OFF)
    set(GLFW_INSTALL OFF)
    FetchContent_Declare(glfw URL "${CMAKE_CURRENT_SOURCE_DIR}/vendor/glfw-3.4.zip"
      URL_HASH SHA256=ebbe1d85add414513750e6cbf67b7cb5cd47ad0896aaa2cb8c8883d92f6fb170)
    FetchContent_MakeAvailable(glfw)
  endif()
  add_executable(LukasXEngine src/main.cpp src/audio.cpp)
  target_compile_definitions(LukasXEngine PRIVATE GLFW_INCLUDE_NONE NOMINMAX WIN32_LEAN_AND_MEAN)
  target_link_libraries(LukasXEngine PRIVATE LukasX::Renderer glfw)
  if(WIN32)
    target_link_libraries(LukasXEngine PRIVATE winmm psapi)
  endif()
  if(MSVC)
    target_compile_options(LukasXEngine PRIVATE /W4 /utf-8)
  endif()
  add_custom_target(lukasx_assets COMMAND ${CMAKE_COMMAND} -E copy_directory
      "${CMAKE_CURRENT_SOURCE_DIR}/assets" "$<TARGET_FILE_DIR:LukasXEngine>/assets"
      VERBATIM)
  add_dependencies(LukasXEngine lukasx_assets)
endif()
# Track project headers explicitly for NMake/MSVC installations that localize /showIncludes.
file(GLOB LUKASX_HEADERS CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.hpp")
file(GLOB LUKASX_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
set_property(SOURCE ${LUKASX_SOURCES} APPEND PROPERTY OBJECT_DEPENDS "${LUKASX_HEADERS}")
if(LUKASX_BUILD_TESTS)
  enable_testing()
  add_executable(sim_tests src/tests.cpp)
  target_link_libraries(sim_tests PRIVATE LukasX::Core)
  add_test(NAME simulation COMMAND sim_tests)
  foreach(t ragdoll npc rollover traffic chassis water dynamics props wanted boat revenge mayhem armed island sdk)
    add_executable(${t}_tests src/${t}_tests.cpp)
    target_link_libraries(${t}_tests PRIVATE LukasX::Core)
    add_test(NAME ${t} COMMAND ${t}_tests)
  endforeach()
  add_executable(round4_tests src/round4_tests.cpp)
  target_link_libraries(round4_tests PRIVATE LukasX::Core)
  foreach(t unflip limits sink drown police trees terrain)
    add_test(NAME v4_${t} COMMAND round4_tests ${t})
  endforeach()
endif()
