# Example GUI App CMakeLists.txt

# To get started on a new GUI app, copy this entire folder (containing this file and C++ sources) to
# a convenient location, and then start making modifications. For other examples of CMakeLists for
# GUI apps, check `extras/Projucer` and `examples/DemoRunner` in the JUCE repo.

# 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.22)

# 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(GUI_APP_EXAMPLE VERSION 0.0.1)

set(LOCAL_PATHS_FILE "${CMAKE_CURRENT_SOURCE_DIR}/LocalPaths.cmake")
if(EXISTS "${LOCAL_PATHS_FILE}")
    include("${LOCAL_PATHS_FILE}")
endif()

# 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.

set(JUCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/JUCE-master" CACHE PATH "Path to the JUCE source tree")
add_subdirectory("${JUCE_DIR}" JUCE)

set(REFLEX_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/reflex" CACHE PATH "Path to the Reflex source tree")
set(REFLEX_LIB_DIR "${REFLEX_DIR}/bin/lib/win")

find_package(Reflex REQUIRED CONFIG
    PATHS "${REFLEX_DIR}/cmake"
    NO_DEFAULT_PATH
)

set(REFLEX_RESOURCES_XML "${CMAKE_CURRENT_SOURCE_DIR}/resources.xml")
set(REFLEX_RESOURCES_CPP "${CMAKE_CURRENT_SOURCE_DIR}/resources.cpp")

add_library(reflex::common STATIC IMPORTED GLOBAL)
set_target_properties(reflex::common PROPERTIES
    IMPORTED_LOCATION_DEBUG "${REFLEX_LIB_DIR}/Debug/x64/ReflexCommon.lib"
    IMPORTED_LOCATION_RELEASE "${REFLEX_LIB_DIR}/Release/x64/ReflexCommon.lib"
    IMPORTED_LOCATION_RELWITHDEBINFO "${REFLEX_LIB_DIR}/Release/x64/ReflexCommon.lib"
    IMPORTED_LOCATION_MINSIZEREL "${REFLEX_LIB_DIR}/Release/x64/ReflexCommon.lib"
)

add_library(reflex::common_ui STATIC IMPORTED GLOBAL)
set_target_properties(reflex::common_ui PROPERTIES
    IMPORTED_LOCATION_DEBUG "${REFLEX_LIB_DIR}/Debug/x64/ReflexCommonUI.lib"
    IMPORTED_LOCATION_RELEASE "${REFLEX_LIB_DIR}/Release/x64/ReflexCommonUI.lib"
    IMPORTED_LOCATION_RELWITHDEBINFO "${REFLEX_LIB_DIR}/Release/x64/ReflexCommonUI.lib"
    IMPORTED_LOCATION_MINSIZEREL "${REFLEX_LIB_DIR}/Release/x64/ReflexCommonUI.lib"
)

add_library(reflex::system_opengl STATIC IMPORTED GLOBAL)
set_target_properties(reflex::system_opengl PROPERTIES
    IMPORTED_LOCATION_DEBUG "${REFLEX_LIB_DIR}/Debug/x64/ReflexSystemOpenGL.lib"
    IMPORTED_LOCATION_RELEASE "${REFLEX_LIB_DIR}/Release/x64/ReflexSystemOpenGL.lib"
    IMPORTED_LOCATION_RELWITHDEBINFO "${REFLEX_LIB_DIR}/Release/x64/ReflexSystemOpenGL.lib"
    IMPORTED_LOCATION_MINSIZEREL "${REFLEX_LIB_DIR}/Release/x64/ReflexSystemOpenGL.lib"
)

add_library(reflex::target_library STATIC IMPORTED GLOBAL)
set_target_properties(reflex::target_library PROPERTIES
    IMPORTED_LOCATION_DEBUG "${REFLEX_LIB_DIR}/Debug/x64/ReflexTargetLibrary.lib"
    IMPORTED_LOCATION_RELEASE "${REFLEX_LIB_DIR}/Release/x64/ReflexTargetLibrary.lib"
    IMPORTED_LOCATION_RELWITHDEBINFO "${REFLEX_LIB_DIR}/Release/x64/ReflexTargetLibrary.lib"
    IMPORTED_LOCATION_MINSIZEREL "${REFLEX_LIB_DIR}/Release/x64/ReflexTargetLibrary.lib"
)

# 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

# If your app depends the VST2 SDK, perhaps to host VST2 plugins, CMake needs to be told where
# to find the SDK on your system. This setup should be done before calling `juce_add_gui_app`.

# juce_set_vst2_sdk_path(...)

# `juce_add_gui_app` adds an executable target with the name passed as the first argument
# (ReflexInJuceTest here). This target is a normal CMake target, but has a lot of extra properties set
# up by default. This function accepts many optional arguments. Check the readme at
# `docs/CMake API.md` in the JUCE repo for the full list.

juce_add_gui_app(ReflexJuceDemo
    # VERSION ...                       # Set this if the app version is different to the project version
    # ICON_BIG ...                      # ICON_* arguments specify a path to an image file to use as an icon
    # ICON_SMALL ...
    # DOCUMENT_EXTENSIONS ...           # Specify file extensions that should be associated with this app
    # COMPANY_NAME ...                  # Specify the name of the app's author
    PRODUCT_NAME "Reflex Juce Demo")     # The name of the final executable, which can differ from the target name

set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ReflexJuceDemo)

# `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(ReflexInJuceTest)

# `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(ReflexJuceDemo
    PRIVATE
        Main.cpp
        MainComponent.cpp
        resources.cpp
        reflex_view_demo.cpp
        ${REFLEX_DIR}/src/reflex_ext/reflex_ext_file.cpp
		${REFLEX_DIR}/src/reflex_ext/reflex_ext_bootstrap.cpp
        ${REFLEX_DIR}/src/reflex_ext/reflex_ext_ide.cpp
        ${REFLEX_DIR}/src/reflex_ext/reflex_ext_glx.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(ReflexJuceDemo
    PRIVATE
        REFLEX_BOOTSTRAP_TYPE_APP
        # 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_gui_app` call
        JUCE_USE_CURL=0     # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_gui_app` call
        JUCE_APPLICATION_NAME_STRING="$<TARGET_PROPERTY:ReflexJuceDemo,JUCE_PRODUCT_NAME>"
        JUCE_APPLICATION_VERSION_STRING="$<TARGET_PROPERTY:ReflexJuceDemo,JUCE_VERSION>")

target_include_directories(ReflexJuceDemo
    PRIVATE
        "${REFLEX_DIR}/include"
)

# 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(GuiAppData SOURCES ...)

# `target_link_libraries` links libraries and JUCE modules to other libraries or executables. Here,
# we're linking our executable target to the `juce::juce_gui_extra` 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.

set_target_properties(ReflexJuceDemo PROPERTIES
    CXX_STANDARD 20
    CXX_STANDARD_REQUIRED YES
    CXX_EXTENSIONS NO
    MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
)

if(EXISTS "${REFLEX_RESOURCES_XML}")
    _reflex_add_resource_build(ReflexJuceDemo "${REFLEX_RESOURCES_XML}")
endif()

target_link_libraries(ReflexJuceDemo
    PRIVATE
        # GuiAppData            # If we'd created a binary data target, we'd link to it here
        juce::juce_gui_basics
        reflex::target_library
        reflex::common_ui
        reflex::common
        reflex::system_opengl
    PUBLIC
        juce::juce_recommended_config_flags
        juce::juce_recommended_lto_flags
        juce::juce_recommended_warning_flags)
