# The macOS frontend: AppKit, no toolkit dependencies beyond the system
# frameworks.
#
# Written on Linux and never compiled on a Mac -- .github/workflows/macos.yml
# is the first thing that will actually try it, and a failure there is real
# signal about this code, not necessarily about the workflow.

if(NOT APPLE)
  message(STATUS "macos frontend: not a macOS build -- skipping")
  return()
endif()

enable_language(OBJC)

# The .icns has to be added as a SOURCE with MACOSX_PACKAGE_LOCATION so CMake
# copies it into the bundle, and MACOSX_BUNDLE_ICON_FILE names it for
# Info.plist.in's ${MACOSX_BUNDLE_ICON_FILE}. Neither alone is enough, and
# without both the bundle builds cleanly with no icon at all -- GNOME and KDE
# find theirs by desktop-entry id and Windows embeds app.ico, so nothing else
# in this project would have caught it (PORTING.md 4.4).
set(COLECO_ICNS "${CMAKE_SOURCE_DIR}/data/icons/fujinet-go-coleco.icns")

add_executable(fujinet-go-coleco-macos MACOSX_BUNDLE
  main.m
  AppDelegate.m
  DisplayView.m
  ColecoKeyForward.m
  keypad/KeypadWindow.m
  debugger/DebuggerWindow.m
  "${COLECO_ICNS}"
)
set_source_files_properties("${COLECO_ICNS}" PROPERTIES
  MACOSX_PACKAGE_LOCATION "Resources")

set_target_properties(fujinet-go-coleco-macos PROPERTIES
  # The bundle is named for the product, not the target: this is what makes
  # it "FujiNet Go ColecoVision.app" rather than the target name, and the
  # packaging workflow refers to it by that path. It also has to agree with
  # MACOSX_BUNDLE_EXECUTABLE_NAME below, which names the binary inside.
  OUTPUT_NAME "FujiNet Go ColecoVision"
  MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in"
  MACOSX_BUNDLE_EXECUTABLE_NAME "FujiNet Go ColecoVision"
  MACOSX_BUNDLE_ICON_FILE "fujinet-go-coleco.icns"
  MACOSX_BUNDLE_BUNDLE_NAME "FujiNet Go ColecoVision"
  MACOSX_BUNDLE_GUI_IDENTIFIER "online.fujinet.go.coleco.macos"
  MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}"
  MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}")

target_include_directories(fujinet-go-coleco-macos PRIVATE
  ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(fujinet-go-coleco-macos PRIVATE coleco_session
  "-framework Cocoa"
  "-framework CoreVideo"    # CVDisplayLink: this platform's frame clock
  "-framework CoreGraphics"
  "-framework QuartzCore"   # kCAFilterNearest: the debugger's pixel views,
                            # which must NOT be smoothed -- they are pattern
                            # tables and sprite cells
  "-framework Carbon")      # kVK_* virtual key codes
target_compile_options(fujinet-go-coleco-macos PRIVATE -Wall -Wextra
  -fobjc-arc)

install(TARGETS fujinet-go-coleco-macos BUNDLE DESTINATION .)

# Pack the FujiNet runtime into the bundle so the .app is self-contained.
# Everything goes BESIDE THE EXECUTABLE in Contents/MacOS, not into the
# Frameworks/Resources layout a Mac app would normally use, because that is
# where core/src/paths.c actually looks: resolve_lib_dir() probes exe_dir()
# for libfujinet.dylib and then takes the asset tree from that same directory
# or its "fujinet" subdir. A Frameworks/Resources layout builds and signs
# perfectly and then fails at run time with "libfujinet not found", which is
# the kind of break no compiler catches. add_dependencies rather than a bare
# POST_BUILD so the ordering against the runtime target is real.
if(TARGET fujinet-runtime)
  add_dependencies(fujinet-go-coleco-macos fujinet-runtime)
  set(_exedir "$<TARGET_FILE_DIR:fujinet-go-coleco-macos>")
  add_custom_command(TARGET fujinet-go-coleco-macos POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
            "${FUJINET_LIB}" "${_exedir}/"
    COMMAND ${CMAKE_COMMAND} -E copy_directory
            "${FUJINET_OUT}/data" "${_exedir}/fujinet/data"
    COMMAND ${CMAKE_COMMAND} -E copy_directory
            "${FUJINET_OUT}/SD" "${_exedir}/fujinet/SD"
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
            "${FUJINET_OUT}/fnconfig.ini" "${_exedir}/fujinet/"
    COMMENT "Packing the FujiNet runtime into the bundle"
    VERBATIM)
endif()
