cmake_minimum_required(VERSION 3.21)
project(omareel VERSION 0.1.0 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_AUTOMOC ON)

find_package(Qt6 6.8 REQUIRED COMPONENTS Core Concurrent Gui GuiPrivate Quick QuickControls2 Multimedia OpenGL Svg Test)
find_package(LayerShellQt REQUIRED)
find_package(PkgConfig REQUIRED)
option(OMAREEL_BUILD_HYPRLAND_PLUGIN "Build the matching Hyprland capture exclusion plugin" ON)
if(OMAREEL_BUILD_HYPRLAND_PLUGIN)
    pkg_check_modules(HYPRLAND QUIET hyprland)
    if(HYPRLAND_FOUND)
        add_subdirectory(plugin)
    endif()
endif()
pkg_check_modules(TURBOJPEG REQUIRED IMPORTED_TARGET libturbojpeg)
pkg_check_modules(LIBEVDEV REQUIRED IMPORTED_TARGET libevdev)
pkg_check_modules(WAYLAND_CLIENT REQUIRED IMPORTED_TARGET wayland-client)
find_program(WAYLAND_SCANNER REQUIRED NAMES wayland-scanner)

function(generate_wayland_protocol protocol_name protocol_xml)
    set(protocol_header ${CMAKE_CURRENT_BINARY_DIR}/generated/${protocol_name}-client-protocol.h)
    set(protocol_code ${CMAKE_CURRENT_BINARY_DIR}/generated/${protocol_name}-protocol.c)
    add_custom_command(OUTPUT ${protocol_header} ${protocol_code}
        COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/generated
        COMMAND ${WAYLAND_SCANNER} client-header ${protocol_xml} ${protocol_header}
        COMMAND ${WAYLAND_SCANNER} private-code ${protocol_xml} ${protocol_code}
        DEPENDS ${protocol_xml}
        VERBATIM)
    set(GENERATED_WAYLAND_SOURCES ${GENERATED_WAYLAND_SOURCES} ${protocol_header} ${protocol_code} PARENT_SCOPE)
endfunction()

generate_wayland_protocol(ext-image-capture-source-v1
    /usr/share/wayland-protocols/staging/ext-image-capture-source/ext-image-capture-source-v1.xml)
generate_wayland_protocol(ext-image-copy-capture-v1
    /usr/share/wayland-protocols/staging/ext-image-copy-capture/ext-image-copy-capture-v1.xml)
generate_wayland_protocol(ext-foreign-toplevel-list-v1
    /usr/share/wayland-protocols/staging/ext-foreign-toplevel-list/ext-foreign-toplevel-list-v1.xml)

qt_standard_project_setup()
qt_policy(SET QTP0004 NEW)

add_library(omareel_core STATIC
    src/core/Project.cpp
    src/core/InputLog.cpp
    src/core/CursorPath.cpp
    src/core/MotionTrack.cpp
    src/core/KeystrokeTrack.cpp
    src/core/ZoomTimeline.cpp
    src/core/ClipTimeline.cpp
    src/core/CameraTimeline.cpp
    src/core/Theme.cpp
    src/core/OmarchyPaths.cpp
    src/core/RecordingMetadata.cpp
    src/core/RecordingPreferences.cpp
    src/record/CursorSampler.cpp
    src/record/CameraCapture.cpp
    src/record/EvdevListener.cpp
    src/record/RegionPicker.cpp
    src/record/Recorder.cpp
    src/record/CaptureExclusion.cpp
    src/record/ScreenCapture.cpp
    ${GENERATED_WAYLAND_SOURCES}
)
target_include_directories(omareel_core PUBLIC src PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated)
target_link_libraries(omareel_core
    PUBLIC Qt6::Core Qt6::Gui Qt6::Quick Qt6::Multimedia Qt6::Svg
    PRIVATE PkgConfig::LIBEVDEV PkgConfig::WAYLAND_CLIENT PkgConfig::TURBOJPEG
)

add_library(omareel_render STATIC)
qt_add_qml_module(omareel_ui STATIC
    URI Omareel.Ui
    VERSION 1.0
    RESOURCE_PREFIX /qt/qml
    OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Omareel/Ui
    QML_FILES
        src/ui/qml/ui/OmButton.qml
        src/ui/qml/ui/OmIconButton.qml
        src/ui/qml/ui/OmButtonGroup.qml
        src/ui/qml/ui/OmToggle.qml
        src/ui/qml/ui/OmSlider.qml
        src/ui/qml/ui/OmTrimHandle.qml
        src/ui/qml/ui/OmSectionHeader.qml
        src/ui/qml/ui/OmHero.qml
        src/ui/qml/ui/OmSeparator.qml
        src/ui/qml/ui/OmDropdown.qml
        src/ui/qml/ui/OmTextField.qml
        src/ui/qml/ui/OmPopupCard.qml
        src/ui/qml/ui/OmListRow.qml
        src/ui/qml/ui/OmConfirm.qml
)
target_link_libraries(omareel_ui PUBLIC Qt6::Quick Qt6::QuickControls2)
set_source_files_properties(
    src/ui/qml/Composition.qml
    src/ui/qml/Background.qml
    src/ui/qml/RoundedFrame.qml
    src/ui/qml/CursorOverlay.qml
    src/ui/qml/CameraOverlay.qml
    src/ui/qml/KeystrokeOverlay.qml
    src/ui/qml/Main.qml
    src/ui/qml/TopBar.qml
    src/ui/qml/PreviewPane.qml
    src/ui/qml/BottomBar.qml
    src/ui/qml/SidePanel.qml
    src/ui/qml/PanelSlider.qml
    src/ui/qml/PanelLabel.qml
    src/ui/qml/PanelHeading.qml
    src/ui/qml/PanelValue.qml
    src/ui/qml/IconToolButton.qml
    src/ui/qml/EditorButton.qml
    src/ui/qml/EditorSlider.qml
    src/ui/qml/EditorSwitch.qml
    src/ui/qml/EditorComboBox.qml
    src/ui/qml/BackgroundPanel.qml
    src/ui/qml/ShapePanel.qml
    src/ui/qml/CursorPanel.qml
    src/ui/qml/ZoomPanel.qml
    src/ui/qml/AudioPanel.qml
    src/ui/qml/ClipPanel.qml
    src/ui/qml/CameraPanel.qml
    src/ui/qml/KeystrokesPanel.qml
    src/ui/qml/ExportDialog.qml
    src/ui/qml/Timeline.qml
    src/ui/qml/ClipTrack.qml
    src/ui/qml/ZoomTrack.qml
    src/ui/qml/Launcher.qml
    src/ui/qml/RecordingBar.qml
    PROPERTIES QT_RESOURCE_ALIAS ""
)
set_source_files_properties(src/ui/qml/Composition.qml PROPERTIES QT_RESOURCE_ALIAS "Composition.qml")
set_source_files_properties(src/ui/qml/Background.qml PROPERTIES QT_RESOURCE_ALIAS "Background.qml")
set_source_files_properties(src/ui/qml/RoundedFrame.qml PROPERTIES QT_RESOURCE_ALIAS "RoundedFrame.qml")
set_source_files_properties(src/ui/qml/CursorOverlay.qml PROPERTIES QT_RESOURCE_ALIAS "CursorOverlay.qml")
set_source_files_properties(src/ui/qml/CameraOverlay.qml PROPERTIES QT_RESOURCE_ALIAS "CameraOverlay.qml")
foreach(qml_name IN ITEMS Main TopBar PreviewPane BottomBar SidePanel PanelSlider PanelLabel PanelHeading PanelValue IconToolButton EditorButton EditorSlider EditorSwitch EditorComboBox BackgroundPanel ShapePanel CursorPanel ZoomPanel AudioPanel ClipPanel CameraPanel KeystrokesPanel ExportDialog Timeline ClipTrack ZoomTrack Launcher RecordingBar)
    set_source_files_properties(src/ui/qml/${qml_name}.qml PROPERTIES QT_RESOURCE_ALIAS "${qml_name}.qml")
endforeach()
qt_add_qml_module(omareel_render
    URI Omareel
    VERSION 1.0
    RESOURCE_PREFIX /qt/qml
    OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Omareel
    SOURCES
        src/render/FrameSource.h src/render/FrameSource.cpp
        src/render/FfmpegDecoder.h src/render/FfmpegDecoder.cpp
        src/render/Exporter.h src/render/Exporter.cpp
        src/render/PreviewSink.h src/render/PreviewSink.cpp
        src/ui/Editor.h src/ui/Editor.cpp
        src/ui/Launcher.h src/ui/Launcher.cpp
        src/ui/RecordingBar.h src/ui/RecordingBar.cpp
    QML_FILES
        src/ui/qml/Composition.qml
        src/ui/qml/Background.qml
        src/ui/qml/RoundedFrame.qml
        src/ui/qml/CursorOverlay.qml
        src/ui/qml/CameraOverlay.qml
        src/ui/qml/KeystrokeOverlay.qml
        src/ui/qml/Main.qml
        src/ui/qml/TopBar.qml
        src/ui/qml/PreviewPane.qml
        src/ui/qml/BottomBar.qml
        src/ui/qml/SidePanel.qml
        src/ui/qml/PanelSlider.qml
        src/ui/qml/PanelLabel.qml
        src/ui/qml/PanelHeading.qml
        src/ui/qml/PanelValue.qml
        src/ui/qml/IconToolButton.qml
        src/ui/qml/EditorButton.qml
        src/ui/qml/EditorSlider.qml
        src/ui/qml/EditorSwitch.qml
        src/ui/qml/EditorComboBox.qml
        src/ui/qml/BackgroundPanel.qml
        src/ui/qml/ShapePanel.qml
        src/ui/qml/CursorPanel.qml
        src/ui/qml/ZoomPanel.qml
        src/ui/qml/AudioPanel.qml
        src/ui/qml/ClipPanel.qml
        src/ui/qml/CameraPanel.qml
        src/ui/qml/KeystrokesPanel.qml
        src/ui/qml/ExportDialog.qml
        src/ui/qml/Timeline.qml
        src/ui/qml/ClipTrack.qml
        src/ui/qml/ZoomTrack.qml
        src/ui/qml/Launcher.qml
        src/ui/qml/RecordingBar.qml
)
qt_add_resources(omareel_render "omareel_assets"
    PREFIX "/omareel"
    FILES
        assets/cursors/arrow.svg assets/cursors/arrow-dark.svg assets/cursors/pointer.svg
        assets/gradients.json
        assets/icons/lucide/undo-2.svg assets/icons/lucide/redo-2.svg
        assets/icons/lucide/palette.svg assets/icons/lucide/square.svg
        assets/icons/lucide/mouse-pointer-2.svg assets/icons/lucide/zoom-in.svg
        assets/icons/lucide/zoom-out.svg
        assets/icons/lucide/film.svg assets/icons/lucide/camera.svg assets/icons/lucide/volume-2.svg
        assets/icons/lucide/play.svg assets/icons/lucide/pause.svg
        assets/icons/lucide/skip-back.svg assets/icons/lucide/skip-forward.svg
        assets/icons/lucide/scissors.svg assets/icons/lucide/crop.svg assets/icons/lucide/image.svg
        assets/icons/lucide/monitor.svg assets/icons/lucide/app-window.svg assets/icons/lucide/scan.svg
        assets/icons/lucide/save.svg assets/icons/lucide/download.svg assets/icons/lucide/x.svg
        assets/icons/lucide/check.svg assets/icons/lucide/plus.svg assets/icons/lucide/chevron-down.svg
        assets/icons/lucide/folder-open.svg assets/icons/lucide/settings-2.svg
        assets/icons/lucide/video.svg assets/icons/lucide/mic.svg assets/icons/lucide/mic-off.svg
        assets/icons/lucide/rotate-cw.svg assets/icons/lucide/flip-horizontal-2.svg
        assets/icons/lucide/circle.svg assets/icons/lucide/square-dashed.svg
        assets/icons/lucide/layers.svg
        assets/icons/lucide/keyboard.svg
        assets/icons/reel.svg
        assets/sounds/click.wav
)
target_include_directories(omareel_render PUBLIC src src/render)
target_link_libraries(omareel_render PUBLIC omareel_core omareel_ui Qt6::Concurrent Qt6::Quick Qt6::QuickControls2 Qt6::Multimedia Qt6::OpenGL)

qt_add_executable(omareel src/main.cpp src/ui/CaptureTestClient.cpp)
target_link_libraries(omareel PRIVATE omareel_render Qt6::Quick Qt6::Multimedia Qt6::GuiPrivate LayerShellQt::Interface PkgConfig::WAYLAND_CLIENT)
target_compile_definitions(omareel PRIVATE OMAREEL_VERSION="${PROJECT_VERSION}")
add_custom_command(TARGET omareel POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E rm -f $<TARGET_FILE_DIR:omareel>/omarecord
    COMMAND ${CMAKE_COMMAND} -E create_symlink omareel $<TARGET_FILE_DIR:omareel>/omarecord)

include(CTest)
if(BUILD_TESTING)
    foreach(test_name IN ITEMS zoomtimeline cursorpath cliptimeline cameratimeline keystroketrack project inputlog regionpicker omarchypaths recorder)
        qt_add_executable(test_${test_name} tests/test_${test_name}.cpp)
        target_link_libraries(test_${test_name} PRIVATE omareel_core Qt6::Test)
        add_test(NAME ${test_name} COMMAND test_${test_name})
    endforeach()
    qt_add_executable(test_exporter_smoke tests/test_exporter_smoke.cpp)
    target_link_libraries(test_exporter_smoke PRIVATE omareel_render Qt6::Test)
    add_test(NAME exporter_smoke COMMAND test_exporter_smoke)
    qt_add_executable(test_editor tests/test_editor.cpp)
    target_link_libraries(test_editor PRIVATE omareel_render Qt6::Test)
    add_test(NAME editor COMMAND test_editor)
endif()

install(TARGETS omareel RUNTIME DESTINATION bin)
install(FILES pkg/omareel.desktop DESTINATION share/applications)
install(FILES pkg/omareel.svg DESTINATION share/icons/hicolor/scalable/apps)
foreach(icon_size IN ITEMS 16 32 48 64 128 256)
    install(FILES pkg/icons/omareel-${icon_size}.png
            DESTINATION share/icons/hicolor/${icon_size}x${icon_size}/apps
            RENAME omareel.png)
endforeach()
install(CODE "execute_process(COMMAND \"${CMAKE_COMMAND}\" -E create_symlink omareel \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/bin/omarecord\")")
