cmake_minimum_required(VERSION 3.25)
project(aurora LANGUAGES C CXX)
if (APPLE)
    enable_language(OBJC)
endif()
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

option(AURORA_ENABLE_GX "Enable GX implementation and WebGPU renderer" ON)
option(AURORA_ENABLE_DVD "Enable DVD implementation backed by nod" ON)
option(AURORA_ENABLE_CARD "Enable CARD implementation based on kabufuda" ON)
option(AURORA_ENABLE_THP "Enable THP decoder" ON)
option(AURORA_ENABLE_RMLUI "Enable HTML/CSS Based UI Library for use in end-user UI development." OFF)
option(AURORA_CACHE_USE_ZSTD "Compress WebGPU cache entries with zstd" ON)

include(CMakeDependentOption)
cmake_dependent_option(AURORA_ENABLE_EXAMPLES "Enable examples" ON "CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR" OFF)
cmake_dependent_option(AURORA_ENABLE_TESTS "Enable tests" ON "NOT CMAKE_CROSSCOMPILING" OFF)

# Dependency versions
include(cmake/AuroraDependencyVersions.cmake)

# Platform-specific defaults
set(_default_provider "auto")
if (WIN32)
  set(_default_linkage "shared")
else ()
  set(_default_linkage "static")
endif ()

# Dawn/WebGPU (if AURORA_ENABLE_GX)
set(AURORA_DAWN_PROVIDER "${_default_provider}" CACHE STRING
  "How to provide Dawn: auto, vendor (build from source), system (find_package/imported), package (download prebuilt)")
set_property(CACHE AURORA_DAWN_PROVIDER PROPERTY STRINGS auto vendor system package)
set(AURORA_DAWN_LINKAGE "${_default_linkage}" CACHE STRING "Dawn linkage type preference")
set_property(CACHE AURORA_DAWN_LINKAGE PROPERTY STRINGS shared static)

# SDL3
set(AURORA_SDL3_PROVIDER "${_default_provider}" CACHE STRING
  "How to provide SDL3: auto, vendor (build from source), system (find_package/imported), or package (download prebuilt)")
set_property(CACHE AURORA_SDL3_PROVIDER PROPERTY STRINGS auto vendor system package)
set(AURORA_SDL3_LINKAGE "${_default_linkage}" CACHE STRING "SDL3 linkage type preference")
set_property(CACHE AURORA_SDL3_LINKAGE PROPERTY STRINGS shared static)

# nod (if AURORA_ENABLE_DVD)
set(AURORA_NOD_PROVIDER "${_default_provider}" CACHE STRING
  "How to provide nod: auto, vendor (build from source), system (find_package/imported), package (download prebuilt)")
set_property(CACHE AURORA_NOD_PROVIDER PROPERTY STRINGS auto vendor system package)
set(AURORA_NOD_LINKAGE "${_default_linkage}" CACHE STRING "nod linkage type preference")
set_property(CACHE AURORA_NOD_LINKAGE PROPERTY STRINGS shared static)

add_subdirectory(extern)

include(cmake/aurora_core.cmake)
include(cmake/aurora_os.cmake)
if (AURORA_ENABLE_GX)
  include(cmake/aurora_gx.cmake)
  include(cmake/aurora_gd.cmake)
  # PrimedGun: every FIFO subcommand in GXAurora.h needs an ID of its own. handle_aurora's if-chain
  # takes the first match, so a duplicate compiles and then hands one command's payload to the other's
  # handler, which misreads the FIFO (upstream 2bb921da; PrimedGun's merges of 2026-10-07 and
  # 2026-10-08). This scan takes every GX_AURORA_*/GX2_* #define with a hex value, also the ones the
  # static_assert in lib/gx/command_processor.cpp doesn't list yet, and re-runs whenever the header
  # changes.
  block ()
    set(gx_aurora_h "${CMAKE_CURRENT_SOURCE_DIR}/include/dolphin/gx/GXAurora.h")
    set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${gx_aurora_h}")
    file(STRINGS "${gx_aurora_h}" gx_aurora_defines
         REGEX "^#define[ \t]+(GX_AURORA|GX2)_[A-Z0-9_]+[ \t]+0x[0-9A-Fa-f]+")
    foreach (line IN LISTS gx_aurora_defines)
      string(REGEX MATCH "^#define[ \t]+([A-Z0-9_]+)[ \t]+(0x[0-9A-Fa-f]+)" match "${line}")
      set(name "${CMAKE_MATCH_1}")
      set(hex "${CMAKE_MATCH_2}")
      math(EXPR id "${hex}")
      # GX_AURORA_LOAD_ARRAYBASE (0x0010) carries a vertex attribute in its low four bits.
      if (id GREATER 16 AND id LESS 32)
        message(FATAL_ERROR "GXAurora.h: ${name} (${hex}) is inside GX_AURORA_LOAD_ARRAYBASE's 0x0010-0x001F")
      endif ()
      if (DEFINED seen_id_${id})
        message(FATAL_ERROR "GXAurora.h: ${name} and ${seen_id_${id}} share FIFO subcommand ID ${hex}")
      endif ()
      set(seen_id_${id} "${name}")
    endforeach ()
  endblock ()
endif ()
include(cmake/aurora_pad.cmake)
include(cmake/aurora_ms.cmake)
include(cmake/aurora_si.cmake)
include(cmake/aurora_main.cmake)
include(cmake/aurora_mtx.cmake)
include(cmake/aurora_vi.cmake)
if (AURORA_ENABLE_THP)
  include(cmake/aurora_thp.cmake)
endif ()
if(AURORA_ENABLE_CARD)
  include(cmake/aurora_card.cmake)
endif()
if (AURORA_ENABLE_DVD)
  include(cmake/aurora_dvd.cmake)
endif ()

if (AURORA_ENABLE_EXAMPLES)
  add_subdirectory(examples)
endif ()

if (AURORA_ENABLE_TESTS)
  enable_testing()
  add_subdirectory(tests)
endif ()
