cmake_minimum_required(VERSION 3.1...3.15)

if(${CMAKE_VERSION} VERSION_LESS 3.12)
        cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()

# Refuse in-source builds so generated Makefiles/CMakeFiles never land in the
# tree.  Build out-of-source, e.g.  cmake -B build && cmake --build build
if(CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR)
    message(FATAL_ERROR
        "In-source builds are disabled. Run: cmake -B build && cmake --build build")
endif()

# macOS deployment floor.  Set before project()/the first target so it gates
# compilation (and feeds LSMinimumSystemVersion in the .app's Info.plist).
# Override on the command line, e.g. -DCMAKE_OSX_DEPLOYMENT_TARGET=12.0.
# (APPLE isn't set until project() runs, so key off the host here.)
if(CMAKE_HOST_APPLE AND NOT CMAKE_OSX_DEPLOYMENT_TARGET)
    set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "Minimum macOS version")
endif()

project(kat5200 VERSION 1.0.0
    DESCRIPTION "An emulator for the Atari 5200 and 8-bit computers")

# Default to a debug build, but let packagers override (e.g. the Flatpak
# passes -DCMAKE_BUILD_TYPE=Release).
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Debug)
endif()
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -O0")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0")

include(GNUInstallDirs)

# Directory holding the system-wide seed config + profiles used to populate
# a fresh ~/.config/kat5200 on first run (Linux only).  Single source of
# truth: it is both compiled into the binary and used as the install dest.
# These are read-only, package-provided defaults, so per the FHS they live
# under the (prefix-relative) data dir -- e.g. /usr/local/share/kat5200, or
# /usr/share/kat5200 with -DCMAKE_INSTALL_PREFIX=/usr.  Override for
# relocatable packaging, e.g. a Flatpak:
#   cmake -DKAT_DATADIR=/app/share/kat5200 ..
set(KAT_DATADIR "${CMAKE_INSTALL_FULL_DATADIR}/kat5200" CACHE PATH
    "System dir holding seed config/profiles (Linux)")

unset(KAT_MANUAL_PDF_NAME CACHE)
set(KAT_MANUAL_PDF_NAME "kat5200-user-guide.pdf")
set(KAT_COMMITTED_MANUAL_PDF
    "${CMAKE_SOURCE_DIR}/doc/${KAT_MANUAL_PDF_NAME}")
set(KAT_GENERATED_MANUAL_PDF
    "${CMAKE_SOURCE_DIR}/doc/guide/site/pdf/kat5200-user-guide.pdf")
set(KAT_MANUAL_PDF "" CACHE FILEPATH
    "Optional manual PDF to package instead of the committed/generated manual")
option(KAT_PACKAGE_BUILD_MANUAL
    "Build guide-pdf automatically for package targets when KAT_MANUAL_PDF is unset"
    OFF)
if(KAT_MANUAL_PDF)
    get_filename_component(KAT_PACKAGE_MANUAL_PDF
        "${KAT_MANUAL_PDF}" ABSOLUTE)
elseif(KAT_PACKAGE_BUILD_MANUAL)
    set(KAT_PACKAGE_MANUAL_PDF "${KAT_GENERATED_MANUAL_PDF}")
elseif(EXISTS "${KAT_COMMITTED_MANUAL_PDF}")
    set(KAT_PACKAGE_MANUAL_PDF "${KAT_COMMITTED_MANUAL_PDF}")
else()
    set(KAT_PACKAGE_MANUAL_PDF "${KAT_GENERATED_MANUAL_PDF}")
endif()

set(KAT_SHADER_BUNDLE_MANIFEST
    "${CMAKE_SOURCE_DIR}/resources/shaders/distributed_bundles.txt")
set(KAT_SHADER_BUNDLE_SOURCE_ROOT
    "${CMAKE_SOURCE_DIR}/resources/shaders/bundles")
file(STRINGS "${KAT_SHADER_BUNDLE_MANIFEST}" _kat_shader_bundle_lines)
set(KAT_DISTRIBUTED_SHADER_BUNDLES "")
set(KAT_DISTRIBUTED_SHADER_BUNDLE_DIRS "")
set(KAT_NON_DISTRIBUTED_SHADER_BUNDLES
    stock
    lut-alias-test
    history-test
    feedback-test
    float-test)
foreach(_kat_shader_bundle IN LISTS _kat_shader_bundle_lines)
    string(REGEX REPLACE "#.*$" "" _kat_shader_bundle "${_kat_shader_bundle}")
    string(STRIP "${_kat_shader_bundle}" _kat_shader_bundle)
    if("${_kat_shader_bundle}" STREQUAL "")
        continue()
    endif()

    set(_kat_shader_bundle_dir
        "${KAT_SHADER_BUNDLE_SOURCE_ROOT}/${_kat_shader_bundle}")
    if(NOT EXISTS "${_kat_shader_bundle_dir}/bundle.toml")
        message(FATAL_ERROR
            "Distributed shader bundle '${_kat_shader_bundle}' is missing bundle.toml")
    endif()
    list(APPEND KAT_DISTRIBUTED_SHADER_BUNDLES "${_kat_shader_bundle}")
    list(APPEND KAT_DISTRIBUTED_SHADER_BUNDLE_DIRS "${_kat_shader_bundle_dir}")
endforeach()

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/")
message( ${CMAKE_MODULE_PATH} )
message( ${CMAKE_SOURCE_DIR} )

find_package(ZLIB REQUIRED)
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3)
find_package(SDL3_image REQUIRED CONFIG)
#find_package(SDL3_TTF REQUIRED)
#find_package(SDL3_NET REQUIRED)
# Shaders now render through SDL_GPU bundles; the desktop OpenGL shader system
# was removed, so the build no longer links desktop GL.  Android still renders
# through GLES (linked directly in interface/CMakeLists.txt).
# ROM-set download backend.  Windows uses WinHTTP (a system component that
# validates against the OS certificate store), so the portable package ships
# no libcurl/OpenSSL/etc. DLLs and no CA bundle.  Every other platform uses
# libcurl when it's available.  HAVE_ROM_DOWNLOAD gates the feature itself;
# HAVE_CURL selects the libcurl backend (see src/gui/menu_setup.c).
if(WIN32)
    add_compile_definitions(HAVE_ROM_DOWNLOAD)
elseif(ANDROID)
    # Android downloads via a JNI/Java HttpURLConnection backend (see
    # KatDownloader.java + the __ANDROID__ branch of dl_download_to_file), which
    # uses the system TLS trust store -- no libcurl/OpenSSL needed.
    add_compile_definitions(HAVE_ROM_DOWNLOAD)
else()
    find_package(CURL)
    if(CURL_FOUND)
        add_compile_definitions(HAVE_ROM_DOWNLOAD HAVE_CURL)
    endif()
endif()

#if (WIN32)
#    include_directories(AFTER SYSTEM src/win32)
#    include_directories(AFTER SYSTEM E:/Documents/projects/libs/SDL2_ttf-2.20.1/include)
#endif (WIN32)

add_subdirectory(src)
# Man pages / desktop docs are not part of the Android app package.
if(NOT ANDROID)
    add_subdirectory(doc)
endif()

# Tests link the kat_core/kat_interface/kat_minizip libraries built under src/,
# so src/ must be processed first (above).

option(BUILD_TESTING "Build tests" OFF)
if(BUILD_TESTING)
    enable_testing()
    add_subdirectory(tests)
endif()

option(KAT_BUILD_SHADER_SPIKES "Build opt-in SDL GPU shader spike tools" OFF)
option(KAT_REBUILD_SHADER_BUNDLES "Enable opt-in shader bundle rebuild tooling" OFF)
if(KAT_BUILD_SHADER_SPIKES OR KAT_REBUILD_SHADER_BUNDLES)
    add_subdirectory(tools)
endif()

# Convenience targets to build the Linux Flatpak without memorizing the
# flatpak-builder invocation. Builder ships as the org.flatpak.Builder
# Flatpak app (no native flatpak-builder binary here), so we drive it via
# `flatpak run`. Scratch output stays under flatpak/.
#
# These are developer-convenience targets, NOT part of `all`; the normal
# `make -j4` never triggers them. They also do not replace the native
# build: `cmake -B build` must still configure successfully (it needs the
# native SDL3/SDL3_image/zlib found above), since the targets are
# defined after those find_package() calls.
find_program(FLATPAK_EXECUTABLE flatpak)
set(_fp_dir ${CMAKE_SOURCE_DIR}/flatpak)
set(_fp_manifest io.github.madjacket.kat5200.yml)
set(_fp_manual_cmd
    COMMAND ${CMAKE_COMMAND}
            -D "MANUAL_PDF=${KAT_PACKAGE_MANUAL_PDF}"
            -D "MANUAL_PDF_NAME=${KAT_MANUAL_PDF_NAME}"
            -D "DEST_DIR=${CMAKE_SOURCE_DIR}/doc/guide/site/pdf"
            -D REQUIRE_MANUAL=1
            -P ${CMAKE_SOURCE_DIR}/cmake/stage_manual.cmake)

if(FLATPAK_EXECUTABLE)
    set(_fp_install_cmd
        ${_fp_manual_cmd}
        COMMAND ${FLATPAK_EXECUTABLE} run org.flatpak.Builder
                --user --install --force-clean build-flatpak ${_fp_manifest})
    set(_fp_bundle_cmd
        ${_fp_manual_cmd}
        COMMAND ${FLATPAK_EXECUTABLE} run org.flatpak.Builder
                --repo=repo --force-clean build-flatpak ${_fp_manifest}
        COMMAND ${FLATPAK_EXECUTABLE} build-bundle repo
                kat5200.flatpak io.github.madjacket.kat5200)
else()
    set(_fp_msg [=[flatpak not found on PATH. Install flatpak and `flatpak install flathub org.flatpak.Builder`, then re-run.]=])
    set(_fp_install_cmd COMMAND ${CMAKE_COMMAND} -E echo ${_fp_msg}
        COMMAND ${CMAKE_COMMAND} -E false)
    set(_fp_bundle_cmd  COMMAND ${CMAKE_COMMAND} -E echo ${_fp_msg}
        COMMAND ${CMAKE_COMMAND} -E false)
endif()

# Build + install into the user's Flatpak installation; afterwards runnable
# via `flatpak run io.github.madjacket.kat5200`.
add_custom_target(flatpak-install ${_fp_install_cmd}
    WORKING_DIRECTORY ${_fp_dir} VERBATIM
    COMMENT "Building and installing the kat5200 Flatpak (user)")

# Build into a local OSTree repo and export a shareable single-file bundle:
# flatpak/kat5200.flatpak.
add_custom_target(flatpak-bundle ${_fp_bundle_cmd}
    WORKING_DIRECTORY ${_fp_dir} VERBATIM
    COMMENT "Building shareable kat5200.flatpak bundle")

if(KAT_PACKAGE_BUILD_MANUAL AND NOT KAT_MANUAL_PDF AND TARGET guide-pdf)
    foreach(_kat_manual_pkg_target
            kat5200-macos-dmg
            kat5200-portable-package
            flatpak-install
            flatpak-bundle)
        if(TARGET ${_kat_manual_pkg_target})
            add_dependencies(${_kat_manual_pkg_target} guide-pdf)
        endif()
    endforeach()
endif()
