# Fire CMakeLists.txt

# To get started on a new plugin, copy this entire folder (containing this file and C++ sources) to
# a convenient location, and then start making modifications.

# The first line of any CMake project should be a call to `cmake_minimum_required`, which checks
# that the installed CMake will be able to understand the following CMakeLists, and ensures that
# CMake's behaviour is compatible with the named version. This is a standard CMake command, so more
# information can be found in the CMake docs.

cmake_minimum_required(VERSION 3.15)

set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Minimum OS X deployment version")

# Building universals increases build times
# set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "")

# The top-level CMakeLists.txt file for a project must contain a literal, direct call to the
# `project()` command. `project()` sets up some helpful variables that describe source/binary
# directories, and the current project version. This is a standard CMake command.

project(Fire VERSION 1.0.0)

# If you've installed JUCE somehow (via a package manager, or directly using the CMake install
# target), you'll need to tell this project that it depends on the installed copy of JUCE. If you've
# included JUCE directly in your source tree (perhaps as a submodule), you'll need to tell CMake to
# include that subdirectory as part of the build.

# find_package(JUCE CONFIG REQUIRED)        # If you've installed JUCE to your system
# or
# add_subdirectory(JUCE)                    # If you've put JUCE in a subdirectory called JUCE

include(FetchContent)
FetchContent_Declare(
        JUCE
        GIT_REPOSITORY https://github.com/juce-framework/JUCE.git
        GIT_TAG 7.0.1
)
FetchContent_MakeAvailable(JUCE)

FetchContent_Declare(
        readerwriterqueue
        GIT_REPOSITORY https://github.com/cameron314/readerwriterqueue
        GIT_TAG v1.0.6
)
FetchContent_MakeAvailable(readerwriterqueue)

# If you are building a VST2 or AAX plugin, CMake needs to be told where to find these SDKs on your
# system. This setup should be done before calling `juce_add_plugin`.

# juce_set_vst2_sdk_path(...)
# juce_set_aax_sdk_path(...)

# `juce_add_plugin` adds a static library target with the name passed as the first argument
# (Fire here). This target is a normal CMake target, but has a lot of extra properties set
# up by default. As well as this shared code static library, this function adds targets for each of
# the formats specified by the FORMATS arguments. This function accepts many optional arguments.
# Check the readme at `docs/CMake API.md` in the JUCE repo for the full list.

juce_add_plugin(Fire
        # VERSION ...                                   # Set this if the plugin version is different to the project version
        # ICON_BIG ...                                  # ICON_* arguments specify a path to an image file to use as an icon for the Standalone
        # ICON_SMALL ...
        COMPANY_NAME Wings                              # Specify the name of the plugin's author
        IS_SYNTH FALSE                                  # Is this a synth or an effect?
        NEEDS_MIDI_INPUT TRUE                           # Does the plugin need midi input?
        NEEDS_MIDI_OUTPUT FALSE                         # Does the plugin need midi output?
        IS_MIDI_EFFECT FALSE                            # Is this plugin a MIDI effect?
        # EDITOR_WANTS_KEYBOARD_FOCUS TRUE/FALSE        # Does the editor need keyboard focus?
        COPY_PLUGIN_AFTER_BUILD TRUE                    # Should the plugin be installed to a default location after building?
        PLUGIN_MANUFACTURER_CODE Manu                   # A four-character manufacturer id with at least one upper-case character
        PLUGIN_CODE Nykr                                # A unique four-character plugin id with exactly one upper-case character
        # GarageBand 10.3 requires the first letter to be upper-case, and the remaining letters to be lower-case
        FORMATS AU VST3                                 # The formats to build. Other valid formats are: AAX Unity VST AU AUv3
        PRODUCT_NAME "Fire")                            # The name of the final executable, which can differ from the target name

target_link_libraries(Fire PUBLIC readerwriterqueue)
target_link_libraries(Fire PRIVATE juce::juce_dsp)

target_compile_features(Fire PRIVATE cxx_std_20)

# `juce_generate_juce_header` will create a JuceHeader.h for a given target, which will be generated
# into your build tree. This should be included with `#include <JuceHeader.h>`. The include path for
# this header will be automatically added to the target. The main function of the JuceHeader is to
# include all your JUCE module headers; if you're happy to include module headers directly, you
# probably don't need to call this.

juce_generate_juce_header(Fire)

# `target_sources` adds source files to a target. We pass the target that needs the sources as the
# first argument, then a visibility parameter for the sources which should normally be PRIVATE.
# Finally, we supply a list of source files that will be built into the target. This is a standard
# CMake command.

target_sources(Fire
        PRIVATE
        Source/PluginEditor.cpp
        Source/PluginProcessor.cpp
        Source/DSP/WidthProcessor.cpp
        Source/Panels/ControlPanel/Graph\ Components/DistortionGraph.cpp
        Source/Panels/ControlPanel/Graph\ Components/GraphPanel.cpp
        Source/Panels/ControlPanel/Graph\ Components/GraphTemplate.cpp
        Source/Panels/ControlPanel/Graph\ Components/Oscilloscope.cpp
        Source/Panels/ControlPanel/Graph\ Components/VUMeter.cpp
        Source/Panels/ControlPanel/Graph\ Components/VUPanel.cpp
        Source/Panels/ControlPanel/Graph\ Components/WidthGraph.cpp
        Source/Panels/ControlPanel/BandPanel.cpp
        Source/Panels/ControlPanel/GlobalPanel.cpp
        Source/Panels/SpectrogramPanel/CloseButton.cpp
        Source/Panels/SpectrogramPanel/DraggableButton.cpp
        Source/Panels/SpectrogramPanel/EnableButton.cpp
        Source/Panels/SpectrogramPanel/FilterControl.cpp
        Source/Panels/SpectrogramPanel/FreqDividerGroup.cpp
        Source/Panels/SpectrogramPanel/FreqTextLabel.cpp
        Source/Panels/SpectrogramPanel/Multiband.cpp
        Source/Panels/SpectrogramPanel/SoloButton.cpp
        Source/Panels/SpectrogramPanel/SpectrumComponent.cpp
        Source/Panels/SpectrogramPanel/VerticalLine.cpp
        Source/Panels/TopPanel/Preset.cpp
        Source/Utility/VersionInfo.cpp
        )

# `target_compile_definitions` adds some preprocessor definitions to our target. In a Projucer
# project, these might be passed in the 'Preprocessor Definitions' field. JUCE modules also make use
# of compile definitions to switch certain features on/off, so if there's a particular feature you
# need that's not on by default, check the module header for the correct flag to set here. These
# definitions will be visible both to your code, and also the JUCE module code, so for new
# definitions, pick unique names that are unlikely to collide! This is a standard CMake command.

target_compile_definitions(Fire
        PUBLIC
        # JUCE_WEB_BROWSER and JUCE_USE_CURL would be on by default, but you might not need them.
        JUCE_WEB_BROWSER=0  # If you remove this, add `NEEDS_WEB_BROWSER TRUE` to the `juce_add_plugin` call
        JUCE_USE_CURL=0     # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_plugin` call
        JUCE_VST3_CAN_REPLACE_VST2=0)

# If your target needs extra binary assets, you can add them here. The first argument is the name of
# a new static library target that will include all the binary resources. There is an optional
# `NAMESPACE` argument that can specify the namespace of the generated binary data class. Finally,
# the SOURCES argument should be followed by a list of source files that should be built into the
# static library. These source files can be of any kind (wav data, images, fonts, icons etc.).
# Conversion to binary-data will happen when your target is built.

juce_add_binary_data(FireData SOURCES
        resource/firelogo.png
        resource/firewingslogo.png)

# https://forum.juce.com/t/building-my-vst3-with-linux-and-juce6-couple-of-tiny-things/39014
set_target_properties(FireData PROPERTIES POSITION_INDEPENDENT_CODE TRUE)

# `target_link_libraries` links libraries and JUCE modules to other libraries or executables. Here,
# we're linking our executable target to the `juce::juce_audio_utils` module. Inter-module
# dependencies are resolved automatically, so `juce_core`, `juce_events` and so on will also be
# linked automatically. If we'd generated a binary data target above, we would need to link to it
# here too. This is a standard CMake command.

target_link_libraries(Fire
        PRIVATE
        FireData
        juce::juce_audio_utils
        PUBLIC
        juce::juce_recommended_config_flags
        juce::juce_recommended_lto_flags
        juce::juce_recommended_warning_flags)

# BUILD_TESTING is ON by default
# include(CTest) does this too, but adds tons of targets we don't want
enable_testing()

# All test .cpp files should be listed here
set(TestFiles
        test/CatchMain.cpp
        test/PluginTest.cpp)

# Download the tagged version of Catch2
Include(FetchContent)
FetchContent_Declare(
        Catch2
        GIT_REPOSITORY https://github.com/catchorg/Catch2.git
        GIT_TAG v2.13.7)
FetchContent_MakeAvailable(Catch2)

# Setup the test executable, again C++ 20 please
add_executable(Tests ${TestFiles})
target_compile_features(Tests PRIVATE cxx_std_20)

# Pull in our plugin code for tests
target_include_directories(Tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_link_libraries(Tests PRIVATE Catch2::Catch2 Fire FireData juce::juce_audio_utils)

# Make an Xcode Scheme for the test executable so we can run tests in the IDE
set_target_properties(Tests PROPERTIES XCODE_GENERATE_SCHEME ON)

# Organize the test source in the Tests/ folder in the IDE
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/test PREFIX "" FILES ${TestFiles})

# Load and use the .cmake file provided by Catch2
# https://github.com/catchorg/Catch2/blob/devel/docs/cmake-integration.md#parseandaddcatchtestscmake
# We have to manually provide the source directory here for now
# https://github.com/catchorg/Catch2/issues/2026
include(${Catch2_SOURCE_DIR}/contrib/Catch.cmake)
catch_discover_tests(Tests)