# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT

cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)

# Directories
set(DUSK_ROOT_DIR "${CMAKE_SOURCE_DIR}")
set(DUSK_SOURCES_DIR "${DUSK_ROOT_DIR}/src")
set(DUSK_ASSETS_DIR "${DUSK_ROOT_DIR}/assets")
set(DUSK_BUILT_ASSETS_DIR "${CMAKE_BINARY_DIR}/assets")
set(DUSK_GENERATED_HEADERS_DIR "${CMAKE_BINARY_DIR}/generated")
file(MAKE_DIRECTORY ${DUSK_GENERATED_HEADERS_DIR})

project(DuskCore VERSION 1.0.0 LANGUAGES C)

# Work out the target platform unless one was given explicitly.
include(${DUSK_ROOT_DIR}/cmake/determineplatform.cmake)

# Platform defaults and definitions (sets DUSK_DEFAULT_* and
# DUSK_PLATFORM_DIRS / DUSK_PLATFORM_DEFINITIONS).
set(DUSK_TARGET_FILE
  "${DUSK_ROOT_DIR}/cmake/${DUSK_TARGET_SYSTEM}/target.cmake"
)
if(NOT EXISTS "${DUSK_TARGET_FILE}")
  message(FATAL_ERROR "Unknown DUSK_TARGET_SYSTEM: ${DUSK_TARGET_SYSTEM}")
endif()
include("${DUSK_TARGET_FILE}")

# All options and their defaults.
include(${DUSK_ROOT_DIR}/cmake/option.cmake)

# Targets. Tests split the code into a library plus the binary, otherwise all
# code is compiled straight into the binary.
set(DUSK_BINARY_TARGET_NAME "Dusk")
add_executable(${DUSK_BINARY_TARGET_NAME})

if(DUSK_BUILD_TESTS)
  set(DUSK_LIBRARY_TARGET_NAME "DuskCore")
  add_library(${DUSK_LIBRARY_TARGET_NAME} STATIC)
  target_link_libraries(${DUSK_BINARY_TARGET_NAME} PUBLIC
    ${DUSK_LIBRARY_TARGET_NAME}
  )
else()
  set(DUSK_LIBRARY_TARGET_NAME "${DUSK_BINARY_TARGET_NAME}")
endif()

target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
  DUSK_TARGET_SYSTEM="${DUSK_TARGET_SYSTEM}"
  DUSK_GAME_NAME="${DUSK_GAME_NAME}"
  DUSK_GAME_AUTHOR="${DUSK_GAME_AUTHOR}"
  DUSK_VERSION="${DUSK_VERSION}"
)

target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
  ${DUSK_PLATFORM_DEFINITIONS}
)
foreach(OPT ASSERTIONS_FAKED BACKTRACE TRACK_MEMORY NETWORK)
  if(DUSK_${OPT})
    target_compile_definitions(${DUSK_LIBRARY_TARGET_NAME} PUBLIC DUSK_${OPT})
  endif()
endforeach()

if(DUSK_BACKTRACE)
  target_link_options(${DUSK_LIBRARY_TARGET_NAME} PUBLIC -rdynamic)
endif()

# Tools (run during the build to generate headers)
add_subdirectory(tools)
target_include_directories(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
  ${DUSK_GENERATED_HEADERS_DIR}
)

# Core engine code
add_subdirectory(${DUSK_SOURCES_DIR}/dusk)

# Assets, copied into <build>/assets
include(${DUSK_ROOT_DIR}/cmake/asset/asset.cmake)
# Separate binary dir, so <build>/assets only contains built assets.
add_subdirectory(${DUSK_ROOT_DIR}/assets ${CMAKE_BINARY_DIR}/assets_cmake)
dusk_assets_finalize(DuskAssets)
add_dependencies(${DUSK_LIBRARY_TARGET_NAME} DuskAssets)

# Game code
add_subdirectory(${DUSK_SOURCES_DIR}/${DUSK_GAME})

# Platform code
foreach(DIR ${DUSK_PLATFORM_DIRS})
  add_subdirectory(${DUSK_SOURCES_DIR}/${DIR})
endforeach()

if(DUSK_BUILD_TESTS)
  enable_testing()
endif()
