cmake_minimum_required(VERSION 3.20)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)

if(APPLE AND NOT CMAKE_OSX_DEPLOYMENT_TARGET)
    # 10.15 because of our use of supportsFamily()
    set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum macOS deployment target")
endif()

project(plume)

if(APPLE)
    enable_language(OBJC OBJCXX)
endif()


# Project options
include(CMakeDependentOption)
# [rexglue vendored change] also available on Apple: the Cocoa window path
# needs plume_apple.mm, which this trim drops, so SDL creates the surface.
cmake_dependent_option(PLUME_SDL_VULKAN_ENABLED "Enable SDL Vulkan integration" OFF "NOT WIN32" OFF)
cmake_dependent_option(PLUME_D3D12_AGILITY_SDK_ENABLED "Enable D3D12 Agility SDK" OFF WIN32 OFF)
cmake_dependent_option(PLUME_APPLE_RETINA_ENABLED "Enable Apple Retina display support" ON APPLE ON)
option(PLUME_BUILD_EXAMPLES "Build example applications" OFF)

# The Metal backend needs both of these; VENDOR.md lists what the trim drops.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/plume_metal.cpp" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/plume_apple.mm")
    set(_plume_metal 1)
else()
    set(_plume_metal 0)
endif()

# Windows-specific definitions
if(WIN32)
    add_compile_definitions(NOMINMAX)
endif()

# Enable SDL Vulkan support


# Enable D3D12 Agility SDK support
if(PLUME_D3D12_AGILITY_SDK_ENABLED)
    find_package(directx-headers CONFIG REQUIRED)
    find_package(directx12-agility CONFIG REQUIRED)
endif()

# Print status messages
message(STATUS "Plume - Building with backends: Vulkan=1 Metal=${_plume_metal} D3D12=${WIN32}")
message(STATUS "Plume - SDL Vulkan integration: ${PLUME_SDL_VULKAN_ENABLED}")
message(STATUS "Plume - D3D12 Agility SDK: ${PLUME_D3D12_AGILITY_SDK_ENABLED}")
message(STATUS "Plume - Building examples: ${PLUME_BUILD_EXAMPLES}")

# Vulkan is the non-Windows backend; Windows builds use plume_d3d12.cpp only, and
# the Vulkan translation unit does not compile against the Store headers.
set(PLUME_SOURCES)
if(NOT WIN32)
    list(APPEND PLUME_SOURCES
        plume_vulkan.cpp
        plume_vulkan.h
    )
endif()

# Platform-specific files. The Metal sources are vendored out (see VENDOR.md).
if(APPLE)
    if(NOT _plume_metal AND NOT PLUME_SDL_VULKAN_ENABLED)
        # Without the Metal path, SDL is the only way to make a Metal surface,
        # and the alternative needs plume_apple.mm to link.
        message(FATAL_ERROR "plume on Apple needs PLUME_SDL_VULKAN_ENABLED when the Metal sources are absent")
    endif()
    if(_plume_metal)
        list(APPEND PLUME_SOURCES
            plume_metal.cpp
            plume_metal.h
            plume_apple.mm
            plume_apple.h
        )
    endif()
elseif(WIN32)
    list(APPEND PLUME_SOURCES
        plume_d3d12.cpp
        plume_d3d12.h
        ${CMAKE_CURRENT_SOURCE_DIR}/contrib/D3D12MemoryAllocator/src/D3D12MemAlloc.cpp
    )
endif()

# Create target
add_library(plume STATIC ${PLUME_SOURCES})

# Include directories
target_include_directories(plume PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/volk
    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/Vulkan-Headers/include
    ${CMAKE_CURRENT_SOURCE_DIR}/contrib/VulkanMemoryAllocator/include
)

if(WIN32)
    target_include_directories(plume PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}/contrib/D3D12MemoryAllocator/include
    )
endif()

# [rexglue vendored change] upstream leaves the D3D12 system libs to the
# consuming app; link them here so any consumer of the target just works.
if(WIN32)
    target_link_libraries(plume PUBLIC d3d12 dxgi)
endif()

# [rexglue vendored change] SDL3: the consumer provides SDL3::Headers.
if(PLUME_SDL_VULKAN_ENABLED)
    target_compile_definitions(plume PUBLIC PLUME_SDL_VULKAN_ENABLED)
    target_link_libraries(plume PUBLIC SDL3::Headers)
endif()

if(PLUME_D3D12_AGILITY_SDK_ENABLED)
    target_compile_definitions(plume PUBLIC PLUME_D3D12_AGILITY_SDK_ENABLED)
    target_compile_definitions(plume PRIVATE D3D12MA_USING_DIRECTX_HEADERS)
    target_link_libraries(plume PRIVATE Microsoft::DirectX-Headers Microsoft::DirectX-Guids Microsoft::DirectX12-Agility)
endif()

# Platform-specific includes and shader compilation
if(APPLE)
    if(PLUME_APPLE_RETINA_ENABLED)
        target_compile_definitions(plume PRIVATE PLUME_APPLE_RETINA_ENABLED)
    endif()

    target_include_directories(plume PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/contrib/metal-cpp
    )
endif()

# Add examples if requested
if(PLUME_BUILD_EXAMPLES)
    add_subdirectory(examples)
endif()
