cmake_minimum_required(VERSION 3.15)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

project(GelykEQ VERSION 1.0.0 LANGUAGES C CXX)

# --- Feature switches ----------------------------------------------------
# Gelyk never uses the embedded web browser and does no networking, so JUCE's
# optional dependency groups stay off:
#
#   JUCE_USE_CURL=0     juce_core's Linux default is 1, which makes it
#                       #include <curl/curl.h> and compile
#                       juce_Network_curl.cpp. Nothing links libcurl (see
#                       NEEDS_CURL below), but its *development headers* would
#                       still be a hard build requirement. Gelyk never touches
#                       URL/WebInputStream, so nothing is lost.
#   JUCE_WEB_BROWSER=0  juce_gui_extra's WebBrowserComponent is the only thing
#                       that #includes <gtk/gtk.h>, <webkit2/webkit2.h>,
#                       <jsc/jsc.h> and <libsoup/soup.h>.
#
# Native file dialogs are not a GTK dependency either: JUCE 8's Linux FileChooser
# shells out to zenity/kdialog via ChildProcess, and Gelyk never opens one.
#
# These are set directory-wide rather than per-target, so that every target
# this project defines inherits them - including the optional GelykEQStandalone
# app, which compiles its own copy of the JUCE modules. As
# target_compile_definitions(GelykEQ ...) they would only reach GelykEQ itself.
# (JUCE's own helper tools are separate nested CMake projects and set what they
# need themselves.)
add_compile_definitions(
    JUCE_WEB_BROWSER=0
    JUCE_USE_CURL=0
)

# --- Linux / BSD only ---------------------------------------------------
# What JUCE does still need on Linux is its own baseline: X11 windowing, ALSA
# and FreeType/fontconfig for juce_graphics text. Those arrive as several
# separate -dev packages on Arch/Artix, so check them up front with a useful
# hint instead of JUCE's raw pkg-config error.
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME MATCHES ".*BSD")
    find_package(PkgConfig REQUIRED)
    foreach(gelyk_dep alsa freetype2 fontconfig)
        pkg_check_modules(GELYK_HAS_${gelyk_dep} QUIET ${gelyk_dep})
        if(NOT GELYK_HAS_${gelyk_dep}_FOUND)
            message(FATAL_ERROR
                "Missing required Linux development package: '${gelyk_dep}'.\n"
                "  Arch/Artix:   alsa-lib freetype2 fontconfig libx11\n"
                "  Debian/Ubuntu: libasound2-dev libfreetype6-dev libfontconfig1-dev libx11-dev\n"
                "  These are JUCE's own requirements (X11 windowing, ALSA, font rendering),\n"
                "  not Gelyk's. No GTK, WebKitGTK, libcurl or file-selector package is needed.")
        endif()
    endforeach()

    # X11's multi-monitor/DPI extensions are dlsym()ed at runtime by JUCE, so
    # their headers are optional. Probe instead of hard-failing on distros that
    # ship just libX11 + libXext (libXrandr/Xinerama/Xcursor are separate
    # packages there). Only libX11's own headers are truly required.
    include(CheckIncludeFileCXX)
    set(gelyk_x11_optional
        "JUCE_USE_XRANDR|X11/extensions/Xrandr.h"
        "JUCE_USE_XINERAMA|X11/extensions/Xinerama.h"
        "JUCE_USE_XSHM|X11/extensions/XShm.h"
        "JUCE_USE_XCURSOR|X11/Xcursor/Xcursor.h"
    )

    set(gelyk_x11_defines)
    foreach(gelyk_opt IN LISTS gelyk_x11_optional)
        string(REPLACE "|" ";" gelyk_parts "${gelyk_opt}")
        list(GET gelyk_parts 0 gelyk_define)
        list(GET gelyk_parts 1 gelyk_header)
        check_include_file_cxx("${gelyk_header}" GELYK_HAVE_${gelyk_define})
        # A failed check leaves the variable empty rather than 0, which would
        # end up as -DJUCE_USE_XCURSOR="" and break the preprocessor.
        if(NOT GELYK_HAVE_${gelyk_define})
            set(GELYK_HAVE_${gelyk_define} 0)
        endif()
        list(APPEND gelyk_x11_defines ${gelyk_define}=${GELYK_HAVE_${gelyk_define}})
    endforeach()

    add_compile_definitions(${gelyk_x11_defines})
endif()

if(NOT DEFINED JUCE_ROOT)
    include(FetchContent)
    set(FETCHCONTENT_QUIET OFF)
    FetchContent_Declare(
        JUCE
        GIT_REPOSITORY https://github.com/juce-framework/JUCE.git
        GIT_TAG        8.0.7
    )
    FetchContent_MakeAvailable(JUCE)
else()
    add_subdirectory(${JUCE_ROOT} JUCE)
endif()

juce_add_plugin(GelykEQ
    VENDOR_NAME                 "Gelyk Audio"
    VENDOR_WEBSITE              "https://gelyk.example"
    VENDOR_EMAIL                "dev@gelyk.example"
    VENDOR_VERSION_CODE         1
    PLUGIN_MANUFACTURER_CODE    Gely
    PLUGIN_CODE                 GkEQ
    FORMATS                     AU VST3
    PRODUCT_NAME                "Gelyk EQ"
    IS_SYNTH                    FALSE
    IS_MIDI_EFFECT              FALSE
    NEEDS_MIDI_INPUT            FALSE
    NEEDS_MIDI_OUTPUT           FALSE
    EDITOR_WANTS_KEYBOARD_FOCUS TRUE
    COPY_PLUGIN_AFTER_BUILD     TRUE
    INSTALL_AU                  TRUE
    INSTALL_VST3                TRUE
    BUNDLE_ID                   com.gelyk.eq
    JucePlugin_Name             "Gelyk EQ"
    JucePlugin_Desc             "A minimalist cyber/neon multiband equalizer"

    # Never link libcurl or WebKitGTK. Gelyk does no networking and has no
    # embedded browser, so both optional Linux dependency groups stay off.
    # (juce_add_plugin leaves these unset = off, this is just explicit.)
    NEEDS_CURL                  FALSE
    NEEDS_WEB_BROWSER           FALSE
)

juce_generate_juce_header(GelykEQ)

# --- Generate Git build info header -------------------------------------
find_package(Git QUIET)
set(GELYK_GIT_BRANCH "unknown")
set(GELYK_GIT_SHA "unknown")
set(GELYK_GIT_DESCRIBE "no-git")
set(GELYK_GIT_DIRTY "")
if(Git_FOUND)
    execute_process(
        COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        OUTPUT_VARIABLE GELYK_GIT_BRANCH
        OUTPUT_STRIP_TRAILING_WHITESPACE
        ERROR_QUIET)
    execute_process(
        COMMAND ${GIT_EXECUTABLE} describe --always --tags --dirty
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        OUTPUT_VARIABLE GELYK_GIT_DESCRIBE
        OUTPUT_STRIP_TRAILING_WHITESPACE
        ERROR_QUIET)
    execute_process(
        COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        OUTPUT_VARIABLE GELYK_GIT_SHA
        OUTPUT_STRIP_TRAILING_WHITESPACE
        ERROR_QUIET)
    execute_process(
        COMMAND ${GIT_EXECUTABLE} status --porcelain
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
        OUTPUT_VARIABLE GELYK_GIT_DIRTY
        ERROR_QUIET)
    if(NOT GELYK_GIT_DIRTY STREQUAL "")
        set(GELYK_GIT_DIRTY "dirty")
    else()
        set(GELYK_GIT_DIRTY "")
    endif()
endif()

string(TIMESTAMP GELYK_BUILD_DATE "%Y-%m-%d %H:%M")

configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/Source/GitInfo.h.in
    ${CMAKE_CURRENT_BINARY_DIR}/Source/GitInfo.h
    @ONLY
)

target_sources(GelykEQ
    PRIVATE
        Source/PluginProcessor.cpp
        Source/PluginEditor.cpp
        Source/EqualizerDSP.cpp
)

target_include_directories(GelykEQ
    PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/Source
)

target_link_libraries(GelykEQ PRIVATE juce::juce_dsp)

target_compile_definitions(GelykEQ PRIVATE JUCE_MODULE_AVAILABLE_juce_dsp=1)

target_compile_options(GelykEQ PRIVATE
    $<$<CXX_COMPILER_ID:AppleClang,Clang>:-Wall -Wextra>
)

option(GELYK_BUILD_STANDALONE "Build a standalone audio app target too" OFF)
if(GELYK_BUILD_STANDALONE)
    target_sources(GelykEQ PRIVATE Source/Standalone.cpp)
    add_executable(GelykEQStandalone ${CMAKE_CURRENT_BINARY_DIR}/JuceLibraryCode/Standalone.cpp)
    target_link_libraries(GelykEQStandalone PRIVATE GelykEQ_impl juce_recommended_config_flags)
endif()

set_target_properties(GelykEQ PROPERTIES
    OUTPUT_NAME GelykEQ
)
