
cmake_minimum_required(VERSION 3.16)
project(mrpt_gui LANGUAGES C CXX)

# Ensure core MRPT packages used here are available to CMake
find_package(mrpt_common REQUIRED)
find_package(mrpt_opengl REQUIRED)
find_package(Eigen3 REQUIRED)

include(./cmake/script_nanogui.cmake REQUIRED)
include(./cmake/script_qt.cmake REQUIRED)
include(./cmake/script_wxwidgets.cmake REQUIRED)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(./cmake/script_opengl.cmake REQUIRED)     # Check for OpenGL / EGL / GLES

if (CMAKE_MRPT_HAS_NANOGUI)
	set(nanogui_dep mrpt_nanogui)
else()
	set(nanogui_dep "")
endif()

# define lib:
set(LIB_SOURCES
  src/about_box_qt.cpp
  src/about_box_wx.cpp
  src/CAboutBox_wx.cpp
  src/CAboutBox_wx.h
  src/CAboutBoxBase.cpp
  src/CAboutBoxBase.h
  src/CAboutBoxQt.cpp
  src/CAboutBoxQt.h
  src/CBaseGUIWindow.cpp
  src/CDisplayWindow.cpp
  src/CDisplayWindow3D.cpp
  src/CDisplayWindowGUI.cpp
  src/CDisplayWindowPlots.cpp
  src/CGlCanvasBase.cpp
  src/CQtGlCanvasBase.cpp
  src/CWxGLCanvasBase.cpp
  src/default_mrpt_glfw_icon.cpp
  src/error_box.cpp
  src/MRPT2NanoguiGLCanvas.cpp
  src/registerAllClasses.cpp
  src/WxSubsystem.cpp
  src/WxUtils.cpp
)
if(CMAKE_MRPT_HAS_WXWIDGETS)
  list(APPEND LIB_SOURCES src/mathplot/mathplot.cpp)
endif()
set(LIB_PUBLIC_HEADERS
  3rdparty/mathplot/mathplot.h
  include/mrpt/gui.h
  include/mrpt/gui/about_box.h
  include/mrpt/gui/CBaseGUIWindow.h
  include/mrpt/gui/CDisplayWindow.h
  include/mrpt/gui/CDisplayWindow3D.h
  include/mrpt/gui/CDisplayWindowGUI.h
  include/mrpt/gui/CDisplayWindowPlots.h
  include/mrpt/gui/CGlCanvasBase.h
  include/mrpt/gui/CMyRedirector.h
  include/mrpt/gui/CQtGlCanvasBase.h
  include/mrpt/gui/CWxGLCanvasBase.h
  include/mrpt/gui/default_mrpt_glfw_icon.h
  include/mrpt/gui/error_box.h
  include/mrpt/gui/gui_frwds.h
  include/mrpt/gui/keycodes.h
  include/mrpt/gui/MRPT2NanoguiGLCanvas.h
  include/mrpt/gui/registerAllClasses.h
  include/mrpt/gui/WxSubsystem.h
  include/mrpt/gui/WxUtils.h
)

# Ensure downstream consumers can find mrpt_nanogui (exported as PUBLIC):
if (CMAKE_MRPT_HAS_NANOGUI)
	set(EXTRA_CONFIG_CMDS "find_dependency(mrpt_nanogui QUIET)")
endif()

# Unit tests. The window-based ones self-skip if there is no window server
# available (see tests/gui_test_common.h); CI runs them under `xvfb-run`.
set(LIB_UNIT_TEST_SOURCES
  tests/CGlCanvasBase_unittest.cpp
  tests/CDisplayWindow_unittest.cpp
  tests/CDisplayWindow3D_unittest.cpp
  tests/WxUtils_unittest.cpp
)

mrpt_add_library(
  TARGET ${PROJECT_NAME}
  SOURCES ${LIB_SOURCES} ${LIB_PUBLIC_HEADERS}
  UNIT_TEST_SOURCES ${LIB_UNIT_TEST_SOURCES}
  PUBLIC_LINK_LIBRARIES
    mrpt::mrpt_opengl
    ${nanogui_dep}
    Eigen3::Eigen  # Needed by nanogui public headers
  CMAKE_DEPENDENCIES
    mrpt_opengl
    Eigen3 # Needed by nanogui public headers
)

# The WxUtils tests include <mrpt/gui/WxUtils.h>, which pulls in wxWidgets
# headers; the library links wxWidgets privately, so the test target needs
# those flags explicitly:
if(TARGET test_${PROJECT_NAME} AND TARGET imp_wxwidgets)
  target_link_libraries(test_${PROJECT_NAME} PRIVATE imp_wxwidgets)
endif()

# Install 3rdparty mathplot header so downstream apps can use it as
# <mrpt/3rdparty/mathplot/mathplot.h>
install(
  FILES 3rdparty/mathplot/mathplot.h
  DESTINATION ${CMAKE_INSTALL_PREFIX}/include/mrpt/3rdparty/mathplot
)

# quiet warnings for 3rdparty sources:
target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/>
)

if(CMAKE_MRPT_HAS_WXWIDGETS)
  if (NOT TARGET imp_wxwidgets)
    message(ERROR "imp_wxwidgets should be defined!")
  endif()
  target_link_libraries(${PROJECT_NAME} PRIVATE imp_wxwidgets)
endif()

if(CMAKE_MRPT_HAS_Qt5)
  target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets Qt5::OpenGL)
endif()

if(MRPT_OPENGL_LIBS)
  # Link against OpenGL:
  target_link_libraries(${PROJECT_NAME} PRIVATE ${MRPT_OPENGL_LIBS})
endif()

if(WIN32 AND NOT TARGET mrpt_glew)
  set(_MRPT_3RDPARTY "${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty")
  if(EXISTS "${_MRPT_3RDPARTY}/glew/src/glew.c")
    add_library(mrpt_glew STATIC "${_MRPT_3RDPARTY}/glew/src/glew.c")
    target_compile_definitions(mrpt_glew PUBLIC GLEW_STATIC)
    target_include_directories(mrpt_glew SYSTEM PUBLIC
      "${_MRPT_3RDPARTY}/glew/include/"
      "${_MRPT_3RDPARTY}/glext/include/")
    if(MSVC)
      target_compile_options(mrpt_glew PRIVATE /W0)
    endif()
    set_target_properties(mrpt_glew PROPERTIES FOLDER "3rd party")
  endif()
endif()

if(TARGET mrpt_glew)  # Basically, for Windows
  target_link_libraries(${PROJECT_NAME} PRIVATE mrpt_glew)
endif()

if (CMAKE_MRPT_HAS_NANOGUI)
  target_link_libraries(${PROJECT_NAME} PUBLIC mrpt_nanogui)
endif()

# Use the mrpt::opengl profiler option here too for the opengl GUIs:
if (MRPT_OPENGL_PROFILER)
  target_compile_definitions(${PROJECT_NAME} PRIVATE MRPT_OPENGL_PROFILER)
endif()

# Python bindings
mrpt_add_python_module(gui
  python_bindings/mrpt_gui_py.cpp
)
