cmake_minimum_required(VERSION 3.5)
project(daq_viewer LANGUAGES CXX)

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

# ─── Options ─────────────────────────────────────────────────────────
option(DAQ_USE_SDL2    "Use SDL2 instead of GLFW" OFF)
option(DAQ_OPENGL3     "Request OpenGL 3.2 core profile" OFF)
option(DAQ_VENDOR_DEPS "Compile vendored third-party sources" ON)

# ─── Platform detection ──────────────────────────────────────────────
if(UNIX AND NOT APPLE)
    find_package(Threads REQUIRED)
    find_package(OpenGL REQUIRED)
    set(DAQ_PLATFORM_LIBS ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} ${OPENGL_LIBRARIES})
    if(NOT DAQ_USE_SDL2)
        find_package(X11 REQUIRED)
        list(APPEND DAQ_PLATFORM_LIBS ${X11_LIBRARIES})
    endif()
endif()

# ─── Third-party libraries ───────────────────────────────────────────

set(IMGUI_DIR  "${CMAKE_SOURCE_DIR}/third_party/imgui")
set(IMPLOT_DIR "${CMAKE_SOURCE_DIR}/third_party/implot")
set(GLFW_DIR   "${CMAKE_SOURCE_DIR}/third_party/glfw")

# --- Dear ImGui ---
if(DAQ_VENDOR_DEPS AND EXISTS "${IMGUI_DIR}/imgui.cpp")
    file(GLOB IMGUI_SOURCES
        "${IMGUI_DIR}/*.cpp"
        "${IMGUI_DIR}/backends/imgui_impl_glfw.cpp"
        "${IMGUI_DIR}/backends/imgui_impl_opengl2.cpp"
        "${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp"
    )
    add_library(imgui STATIC ${IMGUI_SOURCES})
    target_include_directories(imgui PUBLIC
        "${IMGUI_DIR}"
        "${IMGUI_DIR}/backends"
    )
    target_compile_definitions(imgui PUBLIC
        IMGUI_DISABLE_OBSOLETE_FUNCTIONS=1
    )
    target_compile_definitions(imgui PRIVATE
        $<$<BOOL:${DAQ_OPENGL3}>:IMGUI_IMPL_OPENGL_LOADER_GLAD>
    )
    set(IMGUI_TARGET imgui)
else()
    message(FATAL_ERROR
        "ImGui sources not found at ${IMGUI_DIR}.\n"
        "Clone https://github.com/ocornut/imgui into third_party/imgui\n"
        "or set DAQ_VENDOR_DEPS=OFF and provide a system-installed ImGui.")
endif()

# --- ImPlot ---
if(DAQ_VENDOR_DEPS AND EXISTS "${IMPLOT_DIR}/implot.cpp")
    add_library(implot STATIC
        "${IMPLOT_DIR}/implot.cpp"
        "${IMPLOT_DIR}/implot_items.cpp"
    )
    target_include_directories(implot PUBLIC "${IMPLOT_DIR}")
    target_link_libraries(implot PUBLIC ${IMGUI_TARGET})
    set(IMPLOT_TARGET implot)
else()
    message(FATAL_ERROR
        "ImPlot sources not found at ${IMPLOT_DIR}.\n"
        "Clone https://github.com/epezent/implot into third_party/implot")
endif()

# --- GLFW (or SDL2) ---
if(NOT DAQ_USE_SDL2)
    if(EXISTS "${GLFW_DIR}/src/glfw_config.h")
        add_subdirectory("${GLFW_DIR}" glfw_build EXCLUDE_FROM_ALL)
        set(GLFW_TARGET glfw)
    else()
        find_package(glfw3 QUIET)
        if(NOT glfw3_FOUND)
            message(FATAL_ERROR
                "GLFW not found. Options:\n"
                "  - Clone https://github.com/glfw/glfw into third_party/glfw\n"
                "  - Install libglfw3-dev system package\n"
                "  - Set DAQ_USE_SDL2=ON to use SDL2 instead")
        endif()
        set(GLFW_TARGET glfw)
    endif()
else()
    find_package(SDL2 REQUIRED)
    set(GLFW_TARGET ${SDL2_LIBRARIES})
endif()

# ─── Application sources ─────────────────────────────────────────────
set(DAQ_SOURCES
    src/main.cpp
    src/config.cpp
    src/protocol.cpp
    src/decimator.cpp
    src/trigger_engine.cpp
    src/udp_client.cpp
    src/source.cpp
    src/renderer.cpp
    # ring_buffer.h is header-only (template); .cpp has explicit instantiations
    # kept for backward compatibility but not needed by the new code
    src/ring_buffer.cpp
)

add_executable(daq_viewer ${DAQ_SOURCES})

target_include_directories(daq_viewer PRIVATE src)

target_link_libraries(daq_viewer PRIVATE
    ${IMGUI_TARGET}
    ${IMPLOT_TARGET}
    ${GLFW_TARGET}
    ${DAQ_PLATFORM_LIBS}
)

# GL version
if(DAQ_OPENGL3)
    target_compile_definitions(daq_viewer PRIVATE DAQ_OPENGL3)
else()
    target_compile_definitions(daq_viewer PRIVATE DAQ_OPENGL2)
endif()

# ─── Compiler flags ──────────────────────────────────────────────────
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
    target_compile_options(daq_viewer PRIVATE -Wall -Wextra -Wpedantic)
endif()

# ─── Install ─────────────────────────────────────────────────────────
install(TARGETS daq_viewer RUNTIME DESTINATION bin)
install(FILES config/example.ini DESTINATION share/daq_viewer)
