if(NOT DEFINED GLDOZE_REPO_ROOT)
  get_filename_component(GLDOZE_REPO_ROOT "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE)
endif()

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

find_package(ZLIB REQUIRED)
# SQLite3: optional for cross-compile targets (e.g. zig-windows) where vcpkg
# may not supply a pre-built package for the custom triplet.
find_package(SQLite3)
if(SQLite3_FOUND)
  set(GLDOZE_SQLITE3_TARGET SQLite::SQLite3)
endif()

file(GLOB GLDOZE_PUBLIC_HEADERS CONFIGURE_DEPENDS
  "${GLDOZE_REPO_ROOT}/*.h"
)
list(FILTER GLDOZE_PUBLIC_HEADERS EXCLUDE REGEX ".*/gldoze_internal\\.h$")
list(FILTER GLDOZE_PUBLIC_HEADERS EXCLUDE REGEX ".*/gldoze_snap_internal\\.h$")
list(FILTER GLDOZE_PUBLIC_HEADERS EXCLUDE REGEX ".*/gldoze_panel_internal\\.h$")
list(FILTER GLDOZE_PUBLIC_HEADERS EXCLUDE REGEX ".*/gldoze_statusbar_internal\\.h$")
list(FILTER GLDOZE_PUBLIC_HEADERS EXCLUDE REGEX ".*/glbimporter_internal\\.h$")
list(FILTER GLDOZE_PUBLIC_HEADERS EXCLUDE REGEX ".*/recorder_encoder_internal\\.h$")
list(FILTER GLDOZE_PUBLIC_HEADERS EXCLUDE REGEX ".*/audio_codec_internal\\.h$")
list(FILTER GLDOZE_PUBLIC_HEADERS EXCLUDE REGEX ".*/audio_cd_ripper_internal\\.h$")
list(FILTER GLDOZE_PUBLIC_HEADERS EXCLUDE REGEX ".*/audio_cd_ripper_service_internal\\.h$")

set(GLDOZE_FOUNDATION_SOURCES
  ${GLDOZE_REPO_ROOT}/app_paths.cpp
	${GLDOZE_REPO_ROOT}/asset_library.cpp
	${GLDOZE_REPO_ROOT}/audio_codec_internal.cpp
	${GLDOZE_REPO_ROOT}/audio_cd_ripper_service_internal.cpp
  ${GLDOZE_REPO_ROOT}/airsim.cpp
  ${GLDOZE_REPO_ROOT}/airsim_debug.cpp
  ${GLDOZE_REPO_ROOT}/aircraftflightcontroller.cpp
  ${GLDOZE_REPO_ROOT}/audiocdripperwindow.cpp
  ${GLDOZE_REPO_ROOT}/amd_gpu_monitor.cpp
  ${GLDOZE_REPO_ROOT}/runtime_platform.cpp
	${GLDOZE_REPO_ROOT}/s3oanimation.cpp
  ${GLDOZE_REPO_ROOT}/bezier.cpp
	${GLDOZE_REPO_ROOT}/debugdraw.cpp
	${GLDOZE_REPO_ROOT}/flamethrower.cpp
  ${GLDOZE_REPO_ROOT}/glcolor.cpp
  ${GLDOZE_REPO_ROOT}/render_backend.cpp
  ${GLDOZE_REPO_ROOT}/render_api_impl.cpp
  ${GLDOZE_REPO_ROOT}/ring_sound.cpp
  ${GLDOZE_REPO_ROOT}/immediate_batch.cpp
  ${GLDOZE_REPO_ROOT}/gltheme.cpp
  ${GLDOZE_REPO_ROOT}/gpu_readback_queue.cpp
	${GLDOZE_REPO_ROOT}/recorder_cursor.cpp
  ${GLDOZE_REPO_ROOT}/gpu_monitor.cpp
  ${GLDOZE_REPO_ROOT}/gl_compat_windows.cpp
  ${GLDOZE_REPO_ROOT}/nvml_gpu_monitor.cpp
  ${GLDOZE_REPO_ROOT}/cpu_power_rapl.cpp
  ${GLDOZE_REPO_ROOT}/systemstatssampler.cpp
  ${GLDOZE_REPO_ROOT}/grid.cpp
  ${GLDOZE_REPO_ROOT}/image_decode.cpp
	${GLDOZE_REPO_ROOT}/jetexhaust.cpp
  ${GLDOZE_REPO_ROOT}/input_actions.cpp
  ${GLDOZE_REPO_ROOT}/json_file_utils.cpp
  ${GLDOZE_REPO_ROOT}/jobsystem.cpp
  ${GLDOZE_REPO_ROOT}/log.cpp
  ${GLDOZE_REPO_ROOT}/path.cpp
  ${GLDOZE_REPO_ROOT}/plant.cpp
  ${GLDOZE_REPO_ROOT}/plant_backup.cpp
	${GLDOZE_REPO_ROOT}/photo_metadata.cpp
  ${GLDOZE_REPO_ROOT}/point.cpp
  ${GLDOZE_REPO_ROOT}/quadrix.cpp
  ${GLDOZE_REPO_ROOT}/quat.cpp
  ${GLDOZE_REPO_ROOT}/timer.cpp
  ${GLDOZE_REPO_ROOT}/springmap_archive.cpp
  ${GLDOZE_REPO_ROOT}/springmap_loader.cpp
  ${GLDOZE_REPO_ROOT}/vector.cpp
	${GLDOZE_REPO_ROOT}/window_events.cpp
	# Shared by the foundation GPU profiler and standalone SDL/EGL tools.
	${GLDOZE_REPO_ROOT}/gl_proc_loader.cpp
	${GLDOZE_REPO_ROOT}/gpu_profiler.cpp
	)
if(SQLite3_FOUND)
  list(APPEND GLDOZE_FOUNDATION_SOURCES ${GLDOZE_REPO_ROOT}/plant_database.cpp)
endif()

set(GLDOZE_WIDGET_SOURCES
  ${GLDOZE_REPO_ROOT}/glaudiocontrolpanel.cpp
  ${GLDOZE_REPO_ROOT}/glassetgrid.cpp
  ${GLDOZE_REPO_ROOT}/aircraftflightwindow.cpp
  ${GLDOZE_REPO_ROOT}/glbarchart.cpp
  ${GLDOZE_REPO_ROOT}/glbarchart_view.cpp
  ${GLDOZE_REPO_ROOT}/glbreadcrumbbar.cpp
  ${GLDOZE_REPO_ROOT}/glbimporter.cpp
  ${GLDOZE_REPO_ROOT}/glbimporter_load.cpp
  ${GLDOZE_REPO_ROOT}/glbimporter_parse.cpp
  ${GLDOZE_REPO_ROOT}/asset_lod.cpp
  ${GLDOZE_REPO_ROOT}/glbrenderer.cpp
  ${GLDOZE_REPO_ROOT}/glbutton.cpp
  ${GLDOZE_REPO_ROOT}/glbuttonmatrix.cpp
  ${GLDOZE_REPO_ROOT}/glcameraview.cpp
  ${GLDOZE_REPO_ROOT}/glchildwindow.cpp
  ${GLDOZE_REPO_ROOT}/glchildwindow_tree.cpp
  ${GLDOZE_REPO_ROOT}/glcolorpicker.cpp
  ${GLDOZE_REPO_ROOT}/glclipcontrolpanel.cpp
  ${GLDOZE_REPO_ROOT}/glclipcontrolpanel_actions.cpp
  ${GLDOZE_REPO_ROOT}/glcommandpalette.cpp
  ${GLDOZE_REPO_ROOT}/glcommanderlistview.cpp
  ${GLDOZE_REPO_ROOT}/glcommandermounts.cpp
  ${GLDOZE_REPO_ROOT}/glcommanderops.cpp
  ${GLDOZE_REPO_ROOT}/glcommanderremote.cpp
  ${GLDOZE_REPO_ROOT}/glcontextmenu.cpp
  ${GLDOZE_REPO_ROOT}/glcurveeditor.cpp
  ${GLDOZE_REPO_ROOT}/glcommanderpane.cpp
  ${GLDOZE_REPO_ROOT}/glcommanderpanel.cpp
  ${GLDOZE_REPO_ROOT}/glcommanderpanel_actions.cpp
  ${GLDOZE_REPO_ROOT}/glcommanderpanel_input.cpp
  ${GLDOZE_REPO_ROOT}/glcommanderpanel_ui.cpp
  ${GLDOZE_REPO_ROOT}/glcommanderprompt.cpp
  ${GLDOZE_REPO_ROOT}/glcommandertransfer.cpp
  ${GLDOZE_REPO_ROOT}/debug_console_window.cpp
  ${GLDOZE_REPO_ROOT}/debugdraw_window.cpp
  ${GLDOZE_REPO_ROOT}/gldeckpanel.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_stale_report_panel.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_audio_waveform_cache.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_equalizer_panel.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_icon_button.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_seekbar.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_spectrum_analyzer.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_volume_slider.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_radio.cpp
  ${GLDOZE_REPO_ROOT}/gldeckwindow.cpp
	${GLDOZE_REPO_ROOT}/gldatepicker.cpp
  ${GLDOZE_REPO_ROOT}/gldropdown.cpp
  ${GLDOZE_REPO_ROOT}/gldropdown_view.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_audio_player.cpp
  ${GLDOZE_REPO_ROOT}/glfiledialogpanel.cpp
  ${GLDOZE_REPO_ROOT}/glfiledialogpanel_ops.cpp
  ${GLDOZE_REPO_ROOT}/glfilterbar.cpp
  ${GLDOZE_REPO_ROOT}/glfilesystembrowser.cpp
  ${GLDOZE_REPO_ROOT}/glfilesystembrowser_ops.cpp
  ${GLDOZE_REPO_ROOT}/glimage.cpp
  ${GLDOZE_REPO_ROOT}/glimage_view.cpp
  ${GLDOZE_REPO_ROOT}/glinspectorvector.cpp
  ${GLDOZE_REPO_ROOT}/gljobspanel.cpp
  ${GLDOZE_REPO_ROOT}/glkeycaptureinput.cpp
  ${GLDOZE_REPO_ROOT}/keybind_editor_window.cpp
  ${GLDOZE_REPO_ROOT}/gllabel.cpp
  ${GLDOZE_REPO_ROOT}/gllinechart.cpp
  ${GLDOZE_REPO_ROOT}/gllinechart_view.cpp
  ${GLDOZE_REPO_ROOT}/gllistbox.cpp
  ${GLDOZE_REPO_ROOT}/glmediabinpanel.cpp
  ${GLDOZE_REPO_ROOT}/glmediabinpanel_assets.cpp
  ${GLDOZE_REPO_ROOT}/glmediacontrols.cpp
  ${GLDOZE_REPO_ROOT}/glmenubar.cpp
  ${GLDOZE_REPO_ROOT}/glmenubar_view.cpp
  ${GLDOZE_REPO_ROOT}/glminimap.cpp
  ${GLDOZE_REPO_ROOT}/glmultitogglebutton.cpp
  ${GLDOZE_REPO_ROOT}/glpanel.cpp
  ${GLDOZE_REPO_ROOT}/glpanel_view.cpp
  ${GLDOZE_REPO_ROOT}/glpiechart.cpp
  ${GLDOZE_REPO_ROOT}/glpiechart_view.cpp
  ${GLDOZE_REPO_ROOT}/glprogressbar.cpp
  ${GLDOZE_REPO_ROOT}/glprogressor_widget.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorcometdial.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorgearpulse.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorarc.cpp
  ${GLDOZE_REPO_ROOT}/glprogressordna.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorgear.cpp
  ${GLDOZE_REPO_ROOT}/glcannabisleafwidget.cpp
  ${GLDOZE_REPO_ROOT}/glflame.cpp
	${GLDOZE_REPO_ROOT}/glsmoke.cpp
	${GLDOZE_REPO_ROOT}/glgrass.cpp
	${GLDOZE_REPO_ROOT}/glrainbow.cpp
	${GLDOZE_REPO_ROOT}/glsvg.cpp
  ${GLDOZE_REPO_ROOT}/gllightningbeam.cpp
  ${GLDOZE_REPO_ROOT}/glsunstar.cpp
  ${GLDOZE_REPO_ROOT}/glwatertorrent.cpp
  ${GLDOZE_REPO_ROOT}/glatom.cpp
	${GLDOZE_REPO_ROOT}/vehicleunit.cpp
	${GLDOZE_REPO_ROOT}/mpris_media_controls.cpp
  ${GLDOZE_REPO_ROOT}/glfireworks.cpp
  ${GLDOZE_REPO_ROOT}/glcosmos.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorhex.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorhexscanner.cpp
  ${GLDOZE_REPO_ROOT}/glprogressormultigear.cpp
  ${GLDOZE_REPO_ROOT}/glprogressororbitals.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorpulse.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorradar.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorring.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorshardloader.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorspiral.cpp
  ${GLDOZE_REPO_ROOT}/glprogressortrirotor.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorspanel.cpp
  ${GLDOZE_REPO_ROOT}/glprogressorwave.cpp
  ${GLDOZE_REPO_ROOT}/glpreviewtilingwindow.cpp
  ${GLDOZE_REPO_ROOT}/glpropertygrid.cpp
  ${GLDOZE_REPO_ROOT}/glpropertysection.cpp
  ${GLDOZE_REPO_ROOT}/glaccordion.cpp
  ${GLDOZE_REPO_ROOT}/glnotificationcenter.cpp
  ${GLDOZE_REPO_ROOT}/glrangeslider.cpp
  ${GLDOZE_REPO_ROOT}/glsearchbox.cpp
  ${GLDOZE_REPO_ROOT}/glscrollbarh.cpp
  ${GLDOZE_REPO_ROOT}/glscrollbarv.cpp
  ${GLDOZE_REPO_ROOT}/glsplitbutton.cpp
  ${GLDOZE_REPO_ROOT}/glslider.cpp
  ${GLDOZE_REPO_ROOT}/glspinbox.cpp
  ${GLDOZE_REPO_ROOT}/glspinbox_view.cpp
  ${GLDOZE_REPO_ROOT}/glsplitter.cpp
  ${GLDOZE_REPO_ROOT}/glsplitviewcompare.cpp
  ${GLDOZE_REPO_ROOT}/glstreampreview.cpp
  ${GLDOZE_REPO_ROOT}/glstreamwindow.cpp
  ${GLDOZE_REPO_ROOT}/glstatusbadge.cpp
    ${GLDOZE_REPO_ROOT}/gltable.cpp
    ${GLDOZE_REPO_ROOT}/gltable_input.cpp
    ${GLDOZE_REPO_ROOT}/gltable_model.cpp
    ${GLDOZE_REPO_ROOT}/gltable_view.cpp
    ${GLDOZE_REPO_ROOT}/gltabs.cpp
    ${GLDOZE_REPO_ROOT}/gltext.cpp
    ${GLDOZE_REPO_ROOT}/gltext_text.cpp
    ${GLDOZE_REPO_ROOT}/gltext_view.cpp
  ${GLDOZE_REPO_ROOT}/gltextarea.cpp
  ${GLDOZE_REPO_ROOT}/gltextarea_text.cpp
  ${GLDOZE_REPO_ROOT}/gltextarea_view.cpp
  ${GLDOZE_REPO_ROOT}/gltextinput.cpp
  ${GLDOZE_REPO_ROOT}/gltextinput_view.cpp
  ${GLDOZE_REPO_ROOT}/gltageditor.cpp
  ${GLDOZE_REPO_ROOT}/glthumbnailstrip.cpp
  ${GLDOZE_REPO_ROOT}/gltimelinerangeeditor.cpp
  ${GLDOZE_REPO_ROOT}/gltimelinetrackview.cpp
  ${GLDOZE_REPO_ROOT}/gltimecontrol.cpp
  ${GLDOZE_REPO_ROOT}/gltimecontrol_state.cpp
  ${GLDOZE_REPO_ROOT}/gltimecontrol_view.cpp
  ${GLDOZE_REPO_ROOT}/gltoast.cpp
  ${GLDOZE_REPO_ROOT}/gltogglebutton.cpp
  ${GLDOZE_REPO_ROOT}/gltoolstrip.cpp
  ${GLDOZE_REPO_ROOT}/gltooltip.cpp
  ${GLDOZE_REPO_ROOT}/glterminalwindow.cpp
  ${GLDOZE_REPO_ROOT}/desktop_clipboard.cpp
  ${GLDOZE_REPO_ROOT}/terminal_layout_math.cpp
  ${GLDOZE_REPO_ROOT}/gltopwindow.cpp
  ${GLDOZE_REPO_ROOT}/gltreeview.cpp
  ${GLDOZE_REPO_ROOT}/gltreeview_model.cpp
  ${GLDOZE_REPO_ROOT}/gltreeview_view.cpp
  ${GLDOZE_REPO_ROOT}/glv4lcontrolpanel.cpp
  ${GLDOZE_REPO_ROOT}/glvideo.cpp
  ${GLDOZE_REPO_ROOT}/glvideowindow.cpp
  ${GLDOZE_REPO_ROOT}/glvideocache.cpp
  ${GLDOZE_REPO_ROOT}/glvideocache_io.cpp
  ${GLDOZE_REPO_ROOT}/glvideopane.cpp
  ${GLDOZE_REPO_ROOT}/glvideoplayback.cpp
  ${GLDOZE_REPO_ROOT}/glvideoplayback_decode.cpp
  ${GLDOZE_REPO_ROOT}/glvideorecorder.cpp
  ${GLDOZE_REPO_ROOT}/glvideorecorder_worker.cpp
  ${GLDOZE_REPO_ROOT}/glvideorecorder_session.cpp
  ${GLDOZE_REPO_ROOT}/glviewport.cpp
  ${GLDOZE_REPO_ROOT}/glviewport_nav.cpp
  ${GLDOZE_REPO_ROOT}/glviewport_view.cpp
  ${GLDOZE_REPO_ROOT}/glviewportnav.cpp
  ${GLDOZE_REPO_ROOT}/glwaveedit.cpp
  ${GLDOZE_REPO_ROOT}/glwaveedit_view.cpp
  ${GLDOZE_REPO_ROOT}/gpumonitorwindow.cpp
  ${GLDOZE_REPO_ROOT}/glwindow_input.cpp
  ${GLDOZE_REPO_ROOT}/glwindow.cpp
  ${GLDOZE_REPO_ROOT}/glwindow_render.cpp
  ${GLDOZE_REPO_ROOT}/contentsyncmanager.cpp
  ${GLDOZE_REPO_ROOT}/enginelauncher.cpp
  ${GLDOZE_REPO_ROOT}/lobbyclient.cpp
  ${GLDOZE_REPO_ROOT}/lobbyprotocol.cpp
  ${GLDOZE_REPO_ROOT}/localcontentscanner.cpp
  ${GLDOZE_REPO_ROOT}/objimporter.cpp
  ${GLDOZE_REPO_ROOT}/objrenderer.cpp
  ${GLDOZE_REPO_ROOT}/core_mesh_renderer.cpp
  ${GLDOZE_REPO_ROOT}/pipewire_player.cpp
  ${GLDOZE_REPO_ROOT}/recorder.cpp
  ${GLDOZE_REPO_ROOT}/recorder_audio.cpp
  ${GLDOZE_REPO_ROOT}/recorder_encoder.cpp
  ${GLDOZE_REPO_ROOT}/recorder_encoder_session.cpp
  ${GLDOZE_REPO_ROOT}/recorder_encoder_worker.cpp
  ${GLDOZE_REPO_ROOT}/rtc_media_source.cpp
  ${GLDOZE_REPO_ROOT}/rtc_session.cpp
  ${GLDOZE_REPO_ROOT}/rtc_signaling_client.cpp
  ${GLDOZE_REPO_ROOT}/rtc_signaling_server.cpp
  ${GLDOZE_REPO_ROOT}/rtc_stream_log.cpp
  ${GLDOZE_REPO_ROOT}/rtc_types.cpp
  ${GLDOZE_REPO_ROOT}/rtc_video_bridge.cpp
  ${GLDOZE_REPO_ROOT}/springlobby_models.cpp
  ${GLDOZE_REPO_ROOT}/springlobby_settings.cpp
	${GLDOZE_REPO_ROOT}/techlobby_ring_audio.cpp
  ${GLDOZE_REPO_ROOT}/springlobbywindow.cpp
  ${GLDOZE_REPO_ROOT}/springmap_renderer.cpp
  ${GLDOZE_REPO_ROOT}/s3oviewerwindow.cpp
  ${GLDOZE_REPO_ROOT}/ttf.cpp
  ${GLDOZE_REPO_ROOT}/v4l2_capture.cpp
  ${GLDOZE_REPO_ROOT}/v4l2_capture_device.cpp
  ${GLDOZE_REPO_ROOT}/v4l2_capture_recording.cpp
  ${GLDOZE_REPO_ROOT}/v4l2_capture_stream.cpp
)

set(GLDOZE_RUNTIME_SOURCES
  ${GLDOZE_REPO_ROOT}/coresdl.cpp
  ${GLDOZE_REPO_ROOT}/joystick.cpp
  ${GLDOZE_REPO_ROOT}/keyboard_actions.cpp
  ${GLDOZE_REPO_ROOT}/keyboard_top_level.cpp
  ${GLDOZE_REPO_ROOT}/keyboard.cpp
  ${GLDOZE_REPO_ROOT}/mouse.cpp
	${GLDOZE_REPO_ROOT}/gldoze_wheel_input.cpp
)

list(FILTER GLDOZE_PUBLIC_HEADERS EXCLUDE REGEX ".*/keyboard_internal\\.h$")

set(GLDOZE_SHELL_SOURCES
	${GLDOZE_REPO_ROOT}/talonfightersmode.cpp
	${GLDOZE_REPO_ROOT}/battletanksmode.cpp
	${GLDOZE_REPO_ROOT}/thunderstormmode.cpp
  ${GLDOZE_REPO_ROOT}/gldoze.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_console.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_focus.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_help.cpp
	${GLDOZE_REPO_ROOT}/gldoze_input.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_keybinds.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_notifications.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_panel.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_panel_cpu.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_panel_input.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_snap.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_state.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_statusbar.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_statusbar_fields.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_window_processing.cpp
  ${GLDOZE_REPO_ROOT}/gldoze_window_events.cpp
)

set(GLDOZE_ENGINE_SOURCES
  ${GLDOZE_REPO_ROOT}/core.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_ogg_encoder.cpp
  ${GLDOZE_REPO_ROOT}/gpu_profiler.cpp
  ${GLDOZE_REPO_ROOT}/rend.cpp
  ${GLDOZE_REPO_ROOT}/rend_capture.cpp
  ${GLDOZE_REPO_ROOT}/screenshot_png_writer.cpp
)

if(GLDOZE_MINIMAL_TECHLOBBY)
  list(REMOVE_ITEM GLDOZE_FOUNDATION_SOURCES
    ${GLDOZE_REPO_ROOT}/audiocdripperwindow.cpp
    ${GLDOZE_REPO_ROOT}/nvml_gpu_monitor.cpp
    ${GLDOZE_REPO_ROOT}/systemstatssampler.cpp
  )
  list(REMOVE_ITEM GLDOZE_ENGINE_SOURCES
	${GLDOZE_REPO_ROOT}/gldeck_ogg_encoder.cpp
    ${GLDOZE_REPO_ROOT}/rend_capture.cpp
  )
  list(REMOVE_ITEM GLDOZE_WIDGET_SOURCES
    ${GLDOZE_REPO_ROOT}/gldeckpanel.cpp
    ${GLDOZE_REPO_ROOT}/gldeck_stale_report_panel.cpp
    ${GLDOZE_REPO_ROOT}/gldeck_audio_waveform_cache.cpp
    ${GLDOZE_REPO_ROOT}/gldeck_equalizer_panel.cpp
    ${GLDOZE_REPO_ROOT}/gldeck_icon_button.cpp
    ${GLDOZE_REPO_ROOT}/gldeck_seekbar.cpp
    ${GLDOZE_REPO_ROOT}/gldeck_spectrum_analyzer.cpp
    ${GLDOZE_REPO_ROOT}/gldeck_volume_slider.cpp
    ${GLDOZE_REPO_ROOT}/gldeck_radio.cpp
    ${GLDOZE_REPO_ROOT}/gldeckwindow.cpp
    ${GLDOZE_REPO_ROOT}/gldeck_audio_player.cpp
    ${GLDOZE_REPO_ROOT}/aircraftflightwindow.cpp
    ${GLDOZE_REPO_ROOT}/gpumonitorwindow.cpp
    ${GLDOZE_REPO_ROOT}/glcameraview.cpp
    ${GLDOZE_REPO_ROOT}/glmediabinpanel.cpp
    ${GLDOZE_REPO_ROOT}/glmediabinpanel_assets.cpp
    ${GLDOZE_REPO_ROOT}/glmediacontrols.cpp
    ${GLDOZE_REPO_ROOT}/glsvg.cpp
    ${GLDOZE_REPO_ROOT}/glstreamwindow.cpp
    ${GLDOZE_REPO_ROOT}/glstreampreview.cpp
    ${GLDOZE_REPO_ROOT}/glvideo.cpp
    ${GLDOZE_REPO_ROOT}/glvideowindow.cpp
    ${GLDOZE_REPO_ROOT}/glvideocache.cpp
    ${GLDOZE_REPO_ROOT}/glvideocache_io.cpp
    ${GLDOZE_REPO_ROOT}/glvideopane.cpp
    ${GLDOZE_REPO_ROOT}/glvideoplayback.cpp
    ${GLDOZE_REPO_ROOT}/glvideoplayback_decode.cpp
    ${GLDOZE_REPO_ROOT}/glvideorecorder.cpp
    ${GLDOZE_REPO_ROOT}/glvideorecorder_worker.cpp
    ${GLDOZE_REPO_ROOT}/glvideorecorder_session.cpp
    ${GLDOZE_REPO_ROOT}/glpreviewtilingwindow.cpp
    ${GLDOZE_REPO_ROOT}/glv4lcontrolpanel.cpp
    ${GLDOZE_REPO_ROOT}/gltopwindow.cpp
    ${GLDOZE_REPO_ROOT}/glterminalwindow.cpp
    ${GLDOZE_REPO_ROOT}/terminal_layout_math.cpp
    ${GLDOZE_REPO_ROOT}/glwaveedit.cpp
    ${GLDOZE_REPO_ROOT}/glwaveedit_view.cpp
    ${GLDOZE_REPO_ROOT}/mpris_media_controls.cpp
    ${GLDOZE_REPO_ROOT}/pipewire_player.cpp
    ${GLDOZE_REPO_ROOT}/recorder.cpp
    ${GLDOZE_REPO_ROOT}/recorder_audio.cpp
    ${GLDOZE_REPO_ROOT}/recorder_encoder.cpp
    ${GLDOZE_REPO_ROOT}/recorder_encoder_session.cpp
    ${GLDOZE_REPO_ROOT}/recorder_encoder_worker.cpp
    ${GLDOZE_REPO_ROOT}/rtc_media_source.cpp
    ${GLDOZE_REPO_ROOT}/rtc_session.cpp
    ${GLDOZE_REPO_ROOT}/rtc_signaling_client.cpp
    ${GLDOZE_REPO_ROOT}/rtc_signaling_server.cpp
    ${GLDOZE_REPO_ROOT}/rtc_stream_log.cpp
    ${GLDOZE_REPO_ROOT}/rtc_types.cpp
    ${GLDOZE_REPO_ROOT}/rtc_video_bridge.cpp
    ${GLDOZE_REPO_ROOT}/v4l2_capture.cpp
    ${GLDOZE_REPO_ROOT}/v4l2_capture_device.cpp
    ${GLDOZE_REPO_ROOT}/v4l2_capture_recording.cpp
    ${GLDOZE_REPO_ROOT}/v4l2_capture_stream.cpp
    ${GLDOZE_REPO_ROOT}/glclipcontrolpanel.cpp
    ${GLDOZE_REPO_ROOT}/glclipcontrolpanel_actions.cpp
    ${GLDOZE_REPO_ROOT}/glcommandpalette.cpp
    ${GLDOZE_REPO_ROOT}/glcommanderlistview.cpp
    ${GLDOZE_REPO_ROOT}/glcommandermounts.cpp
    ${GLDOZE_REPO_ROOT}/glcommanderops.cpp
    ${GLDOZE_REPO_ROOT}/glcommanderpane.cpp
    ${GLDOZE_REPO_ROOT}/glcommanderpanel.cpp
    ${GLDOZE_REPO_ROOT}/glcommanderpanel_actions.cpp
    ${GLDOZE_REPO_ROOT}/glcommanderpanel_input.cpp
    ${GLDOZE_REPO_ROOT}/glcommanderpanel_ui.cpp
    ${GLDOZE_REPO_ROOT}/glcommanderprompt.cpp
    ${GLDOZE_REPO_ROOT}/glcommandertransfer.cpp
    ${GLDOZE_REPO_ROOT}/glfilesystembrowser.cpp
    ${GLDOZE_REPO_ROOT}/glfilesystembrowser_ops.cpp
    ${GLDOZE_REPO_ROOT}/gljobspanel.cpp
    ${GLDOZE_REPO_ROOT}/glthumbnailstrip.cpp
    ${GLDOZE_REPO_ROOT}/glaudiocontrolpanel.cpp
    ${GLDOZE_REPO_ROOT}/glcolorpicker.cpp
    ${GLDOZE_REPO_ROOT}/gltopwindow.cpp
  )
  list(REMOVE_ITEM GLDOZE_SHELL_SOURCES
    ${GLDOZE_REPO_ROOT}/gldoze_statusbar_fields.cpp
  )
endif()

if(GLDOZE_ENABLE_X11 AND UNIX AND NOT APPLE)
  list(APPEND GLDOZE_WIDGET_SOURCES ${GLDOZE_REPO_ROOT}/x11_clipboard.cpp)
endif()

add_library(gldoze_project_options INTERFACE)
target_include_directories(gldoze_project_options INTERFACE
  $<BUILD_INTERFACE:${GLDOZE_REPO_ROOT}>
  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/gldoze>
)
if(GLDOZE_MINIMAL_TECHLOBBY)
  target_compile_definitions(gldoze_project_options INTERFACE GLDOZE_MINIMAL_TECHLOBBY=1)
endif()
if(GLDOZE_ENABLE_RSVG)
  target_compile_definitions(gldoze_project_options INTERFACE GLDOZE_ENABLE_RSVG=1)
else()
  target_compile_definitions(gldoze_project_options INTERFACE GLDOZE_ENABLE_RSVG=0)
endif()
if(GLDOZE_ENABLE_DEBUG_DRAW)
  target_compile_definitions(gldoze_project_options INTERFACE GLDOZE_ENABLE_DEBUG_DRAW=1)
else()
  target_compile_definitions(gldoze_project_options INTERFACE GLDOZE_ENABLE_DEBUG_DRAW=0)
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
  target_compile_options(gldoze_project_options INTERFACE
    -ffunction-sections
    -fdata-sections
  )
endif()

function(gldoze_apply_dev_warnings target_name)
  if(GLDOZE_DEV_WARNINGS AND CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
    target_compile_options(${target_name} PRIVATE -Wall -Wextra -Wpedantic)
  endif()
endfunction()

add_library(gldoze_external_deps INTERFACE)
target_link_libraries(gldoze_external_deps INTERFACE Threads::Threads)
# The runtime uses native EGL for both X11 windows and the surfaceless
# pbuffer required by the DRM/KMS Wayland compositor. Keep the EGL/X11
# support available in either desktop build; the X11-specific surface code
# remains gated by GLDOZE_ENABLE_X11 in its own target.
if((GLDOZE_ENABLE_X11 OR GLDOZE_ENABLE_WAYLAND) AND UNIX AND NOT APPLE)
  find_package(X11 REQUIRED)
  target_link_libraries(gldoze_external_deps INTERFACE X11::X11)
  if(GLDOZE_USE_PKGCONFIG_DEPS)
    pkg_check_modules(GLDOZE_RUNTIME_EGL REQUIRED IMPORTED_TARGET egl)
    target_link_libraries(gldoze_external_deps INTERFACE PkgConfig::GLDOZE_RUNTIME_EGL)
  else()
    find_library(GLDOZE_RUNTIME_EGL_LIBRARY NAMES EGL REQUIRED)
    target_link_libraries(gldoze_external_deps INTERFACE ${GLDOZE_RUNTIME_EGL_LIBRARY})
  endif()
endif()
if(WIN32)
  target_link_libraries(gldoze_external_deps INTERFACE ws2_32 urlmon)
endif()
if(VCPKG_TARGET_TRIPLET)
  set(_gldoze_vcpkg_lib_dir "${CMAKE_BINARY_DIR}/vcpkg_installed/${VCPKG_TARGET_TRIPLET}/lib")
  if(EXISTS "${_gldoze_vcpkg_lib_dir}")
    target_link_directories(gldoze_external_deps INTERFACE
      $<BUILD_INTERFACE:${_gldoze_vcpkg_lib_dir}>
    )
  endif()
endif()
if(GLDOZE_MINIMAL_TECHLOBBY)
  if(GLDOZE_USE_PKGCONFIG_DEPS)
    target_link_libraries(gldoze_external_deps INTERFACE
      PkgConfig::SDL3
      PkgConfig::SDL3_IMAGE
      PkgConfig::SDL3_TTF
    )
  else()
    target_link_libraries(gldoze_external_deps INTERFACE
      SDL3::SDL3
      SDL3_image::SDL3_image
      SDL3_ttf::SDL3_ttf
    )
  endif()
else()
if(GLDOZE_USE_PKGCONFIG_DEPS)
  target_link_libraries(gldoze_external_deps INTERFACE
    PkgConfig::SDL3
    PkgConfig::SDL3_IMAGE
    PkgConfig::SDL3_TTF
    PkgConfig::AVCODEC
    PkgConfig::AVFORMAT
    PkgConfig::AVUTIL
    PkgConfig::SWSCALE
    PkgConfig::SWRESAMPLE
    PkgConfig::ARCHIVE
    PkgConfig::RSVG
  )
  if(GLDOZE_ENABLE_PIPEWIRE AND TARGET PkgConfig::PIPEWIRE)
    target_link_libraries(gldoze_external_deps INTERFACE PkgConfig::PIPEWIRE)
    target_compile_definitions(gldoze_external_deps INTERFACE GLDOZE_ENABLE_PIPEWIRE=1)
  endif()
  if(TARGET PkgConfig::GIO)
    target_link_libraries(gldoze_external_deps INTERFACE PkgConfig::GIO)
    target_compile_definitions(gldoze_external_deps INTERFACE GLDOZE_HAS_GIO=1)
  endif()
else()
  target_link_libraries(gldoze_external_deps INTERFACE
    SDL3::SDL3
    SDL3_image::SDL3_image
    SDL3_ttf::SDL3_ttf
    FFMPEG::AVCODEC
    FFMPEG::AVFORMAT
    FFMPEG::AVUTIL
    FFMPEG::SWSCALE
    FFMPEG::SWRESAMPLE
    LibArchive::LibArchive
    unofficial::librsvg::librsvg
  )
endif()
endif()
if(NOT GLDOZE_MINIMAL_TECHLOBBY)
  if(TARGET LibDataChannel::LibDataChannel)
    target_link_libraries(gldoze_external_deps INTERFACE LibDataChannel::LibDataChannel)
    target_compile_definitions(gldoze_external_deps INTERFACE GLDOZE_HAVE_LIBDATACHANNEL=1)
  elseif(TARGET PkgConfig::LIBDATACHANNEL)
    target_link_libraries(gldoze_external_deps INTERFACE PkgConfig::LIBDATACHANNEL)
    target_compile_definitions(gldoze_external_deps INTERFACE GLDOZE_HAVE_LIBDATACHANNEL=1)
  endif()
endif()
if(TARGET OpenGL::GL)
  target_link_libraries(gldoze_external_deps INTERFACE OpenGL::GL)
else()
target_link_libraries(gldoze_external_deps INTERFACE GL)
endif()
target_link_libraries(gldoze_external_deps INTERFACE ZLIB::ZLIB)
if(NOT GLDOZE_MINIMAL_TECHLOBBY)
  if(TARGET OpenGL::GLU)
    target_link_libraries(gldoze_external_deps INTERFACE OpenGL::GLU)
  else()
    target_link_libraries(gldoze_external_deps INTERFACE GLU)
  endif()
endif()

add_library(gldoze_foundation STATIC ${GLDOZE_FOUNDATION_SOURCES})
set_target_properties(gldoze_foundation PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_link_libraries(gldoze_foundation
  PUBLIC
    gldoze_project_options
    gldoze_external_deps
    ${GLDOZE_SQLITE3_TARGET}
    ${CMAKE_DL_LIBS}
)
if(GLDOZE_ENABLE_X11 AND UNIX AND NOT APPLE)
  target_compile_definitions(gldoze_foundation PRIVATE GLDOZE_EGL_PROC_LOADER=1)
endif()
gldoze_apply_dev_warnings(gldoze_foundation)

# GLDeck application state must remain usable by its plugin without linking the
# renderer-backed widget library. Keep renderer-independent models here as they
# are extracted from the legacy panel implementation.
add_library(gldoze_gldeck_model STATIC
	${GLDOZE_REPO_ROOT}/gldeck_playback_session.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_playlist_model.cpp
  ${GLDOZE_REPO_ROOT}/gldeck_playlist_storage.cpp
)
set_target_properties(gldoze_gldeck_model PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(gldoze_gldeck_model
  PUBLIC
    $<BUILD_INTERFACE:${GLDOZE_REPO_ROOT}>
)
target_link_libraries(gldoze_gldeck_model PUBLIC gldoze_project_options)
gldoze_apply_dev_warnings(gldoze_gldeck_model)

add_library(gldoze_widgets STATIC ${GLDOZE_WIDGET_SOURCES})
set_target_properties(gldoze_widgets PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_link_libraries(gldoze_widgets
  PUBLIC
    gldoze_project_options
    gldoze_external_deps
    gldoze_foundation
  PRIVATE
    gldoze_gldeck_model
)
gldoze_apply_dev_warnings(gldoze_widgets)

if(TARGET PkgConfig::GLDOZE_LIBSSH2)
  target_link_libraries(gldoze_widgets PUBLIC PkgConfig::GLDOZE_LIBSSH2)
  target_compile_definitions(gldoze_widgets PRIVATE GLDOZE_HAS_LIBSSH2=1)
endif()

add_library(gldoze_runtime STATIC ${GLDOZE_RUNTIME_SOURCES})
target_link_libraries(gldoze_runtime
  PUBLIC
    gldoze_project_options
    gldoze_external_deps
    gldoze_foundation
    gldoze_widgets
)
if((GLDOZE_ENABLE_X11 OR GLDOZE_ENABLE_WAYLAND) AND UNIX AND NOT APPLE)
  target_compile_definitions(gldoze_runtime PRIVATE GLDOZE_RUNTIME_X11_EGL=1)
endif()
gldoze_apply_dev_warnings(gldoze_runtime)

add_library(gldoze_shell STATIC ${GLDOZE_SHELL_SOURCES})
target_link_libraries(gldoze_shell
  PUBLIC
    gldoze_project_options
    gldoze_external_deps
    gldoze_foundation
    gldoze_widgets
    gldoze_runtime
)
gldoze_apply_dev_warnings(gldoze_shell)

add_library(gldoze_engine STATIC ${GLDOZE_ENGINE_SOURCES})
target_link_libraries(gldoze_engine
  PUBLIC
    gldoze_project_options
    gldoze_external_deps
    gldoze_foundation
    gldoze_widgets
    gldoze_runtime
    gldoze_shell
  PRIVATE
    PNG::PNG
)
if(GLDOZE_ENABLE_X11 AND UNIX AND NOT APPLE)
  target_compile_definitions(gldoze_engine PRIVATE GLDOZE_RENDER_X11_CAPTURE=1)
endif()
gldoze_apply_dev_warnings(gldoze_engine)

add_library(gldoze_app ALIAS gldoze_engine)

# Host-only implementation of manifest discovery and shared-library lifetime.
# It deliberately does not link the renderer or any widget implementation.
add_library(gldoze_plugin_runtime STATIC
  ${GLDOZE_REPO_ROOT}/plugin/plugin_manifest.cpp
  ${GLDOZE_REPO_ROOT}/plugin/plugin_loader.cpp
  ${GLDOZE_REPO_ROOT}/plugin/plugin_capabilities.cpp
  ${GLDOZE_REPO_ROOT}/plugin/plugin_provenance.cpp
  ${GLDOZE_REPO_ROOT}/plugin/plugin_call_context.cpp
)
target_include_directories(gldoze_plugin_runtime
  PUBLIC
    $<BUILD_INTERFACE:${GLDOZE_REPO_ROOT}/plugin>
    $<BUILD_INTERFACE:${GLDOZE_REPO_ROOT}/sdk/include>
)
target_link_libraries(gldoze_plugin_runtime PUBLIC gldoze_project_options ${CMAKE_DL_LIBS})
gldoze_apply_dev_warnings(gldoze_plugin_runtime)

# Third-party application code gets headers only. It must not inherit an
# engine, renderer, SDL, X11, or OpenGL link through the SDK target.
add_library(gldoze_sdk INTERFACE)
target_include_directories(gldoze_sdk INTERFACE
  $<BUILD_INTERFACE:${GLDOZE_REPO_ROOT}/sdk/include>
  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

add_library(gldoze::foundation ALIAS gldoze_foundation)
add_library(gldoze::gldeck_model ALIAS gldoze_gldeck_model)
add_library(gldoze::widgets ALIAS gldoze_widgets)
add_library(gldoze::runtime ALIAS gldoze_runtime)
add_library(gldoze::shell ALIAS gldoze_shell)
add_library(gldoze::engine ALIAS gldoze_engine)
add_library(gldoze::sdk ALIAS gldoze_sdk)

set_target_properties(gldoze_project_options PROPERTIES EXPORT_NAME project_options)
set_target_properties(gldoze_external_deps PROPERTIES EXPORT_NAME external_deps)
set_target_properties(gldoze_foundation PROPERTIES EXPORT_NAME foundation)
set_target_properties(gldoze_gldeck_model PROPERTIES EXPORT_NAME gldeck_model)
set_target_properties(gldoze_widgets PROPERTIES EXPORT_NAME widgets)
set_target_properties(gldoze_runtime PROPERTIES EXPORT_NAME runtime)
set_target_properties(gldoze_shell PROPERTIES EXPORT_NAME shell)
set_target_properties(gldoze_engine PROPERTIES EXPORT_NAME engine)
set_target_properties(gldoze_sdk PROPERTIES EXPORT_NAME sdk)

set(GLDOZE_EXPORT_TARGETS
  gldoze_project_options
  gldoze_external_deps
  gldoze_foundation
  gldoze_gldeck_model
  gldoze_widgets
  gldoze_runtime
  gldoze_shell
  gldoze_engine
  gldoze_sdk
)

install(TARGETS ${GLDOZE_EXPORT_TARGETS}
  EXPORT gldozeTargets
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gldoze
)

install(FILES ${GLDOZE_PUBLIC_HEADERS}
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/gldoze
)

install(DIRECTORY "${GLDOZE_REPO_ROOT}/sdk/include/"
  DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)

write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/gldozeConfigVersion.cmake"
  VERSION ${PROJECT_VERSION}
  COMPATIBILITY SameMajorVersion
)

configure_package_config_file(
  "${GLDOZE_REPO_ROOT}/cmake/gldozeConfig.cmake.in"
  "${CMAKE_CURRENT_BINARY_DIR}/gldozeConfig.cmake"
  INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/gldoze"
)

install(
  FILES
    "${CMAKE_CURRENT_BINARY_DIR}/gldozeConfig.cmake"
    "${CMAKE_CURRENT_BINARY_DIR}/gldozeConfigVersion.cmake"
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/gldoze"
)

install(
  EXPORT gldozeTargets
  FILE gldozeTargets.cmake
  NAMESPACE gldoze::
  DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/gldoze"
)
