cmake_minimum_required(VERSION 3.22)

project(Zufallsmanufaktur VERSION 0.1.0 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Static MSVC runtime, so the plugin does not depend on the VC++ redistributable on the host machine.
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

# JUCE is pinned to a release tag; bump it deliberately.
include(FetchContent)
FetchContent_Declare(
    JUCE
    GIT_REPOSITORY https://github.com/juce-framework/JUCE.git
    GIT_TAG        8.0.15
    GIT_SHALLOW    TRUE
)
FetchContent_MakeAvailable(JUCE)

# Copying into the system VST3 folder needs write access to it (usually admin rights on Windows).
option(MG_COPY_PLUGIN_AFTER_BUILD "Copy the built plugin into MG_VST3_COPY_DIR" ON)
set(MG_VST3_COPY_DIR "C:/Program Files/Common Files/VST3" CACHE PATH "Where the .vst3 is copied after the build")

# Host-independent engine: no JUCE, so it can be unit-tested on its own.
add_library(melody_engine STATIC
    Source/engine/MelodyEngine.cpp
    Source/engine/MelodyParams.cpp
    Source/engine/PatchCode.cpp
    Source/engine/style/StyleProfile.cpp
)
target_include_directories(melody_engine PUBLIC Source)
target_link_libraries(melody_engine PRIVATE juce::juce_recommended_warning_flags)

enable_testing()
add_executable(melody_engine_tests
    tests/TestMain.cpp
    tests/MelodyEngineTest.cpp
    tests/StyleTest.cpp
    tests/PatchCodeTest.cpp
)
target_link_libraries(melody_engine_tests PRIVATE melody_engine juce::juce_recommended_warning_flags)
add_test(NAME melody_engine_tests COMMAND melody_engine_tests)

# The plugin layer (style JSON, parameters) needs JUCE, so it gets a console test of its own.
juce_add_console_app(plugin_tests PRODUCT_NAME "Plugin Tests")
target_sources(plugin_tests PRIVATE tests/PluginTests.cpp Source/plugin/StyleJson.cpp Source/plugin/Parameters.cpp
    Source/plugin/PresetManager.cpp Source/plugin/SnapshotBank.cpp Source/plugin/UndoHistory.cpp)
target_include_directories(plugin_tests PRIVATE Source)
target_compile_definitions(plugin_tests PRIVATE JUCE_WEB_BROWSER=0 JUCE_USE_CURL=0)
target_link_libraries(plugin_tests PRIVATE melody_engine juce::juce_audio_processors juce::juce_recommended_config_flags)
add_test(NAME plugin_tests COMMAND plugin_tests)

# The VST3 manifest step runs a freshly built Windows helper, which a Linux cross build cannot run.
if(CMAKE_CROSSCOMPILING)
    set(MG_VST3_AUTO_MANIFEST FALSE)
else()
    set(MG_VST3_AUTO_MANIFEST TRUE)
endif()

juce_add_plugin(Zufallsmanufaktur
    COMPANY_NAME "Treeker"
    PRODUCT_NAME "Zufallsmanufaktur"
    DESCRIPTION "Deterministische Melodiefertigung"
    # The old name stays in the bundle id; the VST3 class id comes from the two codes below, so
    # songs saved with "Melody Generator" find this plugin.
    BUNDLE_ID com.Treeker.MelodyGenerator
    PLUGIN_MANUFACTURER_CODE Trkr
    PLUGIN_CODE MlGn
    FORMATS VST3 Standalone
    IS_SYNTH TRUE
    NEEDS_MIDI_INPUT TRUE
    NEEDS_MIDI_OUTPUT TRUE
    IS_MIDI_EFFECT FALSE
    EDITOR_WANTS_KEYBOARD_FOCUS TRUE
    VST3_CATEGORIES Instrument
    COPY_PLUGIN_AFTER_BUILD ${MG_COPY_PLUGIN_AFTER_BUILD}
    VST3_COPY_DIR "${MG_VST3_COPY_DIR}"
    VST3_AUTO_MANIFEST ${MG_VST3_AUTO_MANIFEST}
)

# The brand's typefaces (SIL Open Font License, see Resources/fonts/README.md), compiled into the plugin.
juce_add_binary_data(mg_fonts SOURCES
    Resources/fonts/Barlow-Regular.ttf
    Resources/fonts/Barlow-SemiBold.ttf
    Resources/fonts/BarlowCondensed-SemiBold.ttf
    Resources/fonts/BarlowCondensed-Bold.ttf
    Resources/fonts/IBMPlexMono-Regular.ttf
    Resources/fonts/IBMPlexMono-Medium.ttf
)

target_sources(Zufallsmanufaktur PRIVATE
    Source/plugin/GlobalSettings.cpp
    Source/plugin/Parameters.cpp
    Source/plugin/PluginEditor.cpp
    Source/plugin/PluginProcessor.cpp
    Source/plugin/PresetController.cpp
    Source/plugin/PresetManager.cpp
    Source/plugin/SnapshotBank.cpp
    Source/plugin/StyleJson.cpp
    Source/plugin/UndoHistory.cpp
    Source/synth/SimpleSynth.cpp
    Source/ui/Controls.cpp
    Source/ui/Dialogs.cpp
    Source/ui/HeaderBar.cpp
    Source/ui/Panels.cpp
    Source/ui/PatternView.cpp
    Source/ui/SettingsOverlay.cpp
    Source/ui/SnapshotBar.cpp
    Source/ui/Theme.cpp
)

target_include_directories(Zufallsmanufaktur PRIVATE Source)

# Renders the window offscreen into a PNG (README screenshot, layout checks). Not a test.
juce_add_console_app(ui_snapshot PRODUCT_NAME "UI Snapshot")
get_target_property(MG_PLUGIN_SOURCES Zufallsmanufaktur SOURCES)
list(FILTER MG_PLUGIN_SOURCES INCLUDE REGEX "^Source/")
target_sources(ui_snapshot PRIVATE tools/UiSnapshot.cpp ${MG_PLUGIN_SOURCES})
target_include_directories(ui_snapshot PRIVATE Source)
target_compile_definitions(ui_snapshot PRIVATE JUCE_WEB_BROWSER=0 JUCE_USE_CURL=0 JucePlugin_Name="Zufallsmanufaktur")
target_link_libraries(ui_snapshot PRIVATE melody_engine mg_fonts juce::juce_audio_utils juce::juce_recommended_config_flags)

target_compile_definitions(Zufallsmanufaktur PUBLIC
    JUCE_WEB_BROWSER=0
    JUCE_USE_CURL=0
    JUCE_VST3_CAN_REPLACE_VST2=0
)

target_link_libraries(Zufallsmanufaktur
    PRIVATE
        melody_engine
        mg_fonts
        juce::juce_audio_utils
    PUBLIC
        juce::juce_recommended_config_flags
        juce::juce_recommended_lto_flags
        juce::juce_recommended_warning_flags
)
