# Allinea LGPL libraries.
#
# If using as a subproject of a larger CMake build system, define
# ALLINEA_LGPL_EXTERNALLY_CONFIGURED to TRUE and ensure the following
# are defined before CMake reaches this subdirectory.
#
#    - USE_X11 :  TRUE if X11 and OpenGL libraries should be located and linked
#    - The appropriate Qt modules have been loaded i.e Qt::QtGui, Qt::Widgets etc
#    - The library target 'z' has been created (potentially as an imported target)
#    - ALLINEA_ARCH is set to an appropriate string for the coroutines implementation to use
#    - LGPL_INSTALL_DIR is set to the directory where the shared libraries should be installed

####################################################
##
##  Configuration
##
####################################################

# C++ language standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if (NOT ALLINEA_LGPL_EXTERNALLY_CONFIGURED)
    find_package(Qt5Widgets REQUIRED)

    # Architecture for coroutines
    set (ALLINEA_ARCH "x86_64" CACHE STRING "Architecture. Used to select the coroutines implementation to use.")

    # Directory to use with install() commands
    set (LGPL_INSTALL_DIR lib)
endif ()

# Prevent dlopen/dump tampering of shared libraries.
# Applied globally to this directory so that any new libraries are
# automatically covered.
if (LINUX)
    add_link_options("-Wl,-z,nodlopen")
    add_link_options("-Wl,-z,nodump")
endif ()

# Make a guess as to whether X11 support should be included
if (LINUX AND BUILD_DISTRIBUTED_GUI_LIBS)
  set (TMP_USE_X11 ON)
else ()
  set (TMP_USE_X11 OFF)
endif ()

# Create an option for the use of X11 libraries
option (USE_X11 "Use X11 libraries" ${TMP_USE_X11})
unset (TMP_USE_X11)

if (USE_X11)
  # Find X11 and OpenGL packages if they have not been set up by a calling CMakeLists.txt
  if (NOT DEFINED OPENGL_INCLUDE_DIR)
    find_package (OpenGL REQUIRED)      # Sets OPENGL_INCLUDE_DIR and OPENGL_LIBRARIES
  endif ()
endif ()

# On Windows, output *.dll, *.exp etc to the CMAKE_LIBRARY_OUTPUT_DIRECTORY rather than the
# CMAKE_RUNTIME_OUTPUT_DIRECTORY.
# To do this set (for this directory and descendants) CMAKE_RUNTIME_OUTPUT_DIRECTORY accordingly.
if (WIN32)
  set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
  set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
endif ()


if (APPLE)
  set (CMAKE_INSTALL_RPATH "@loader_path/../lib")
endif ()

# All targets in this directory tree are Qt-based

set (CMAKE_AUTOMOC ON)
set (CMAKE_AUTORCC ON)
set (CMAKE_AUTOUIC ON)


####################################################
##
##  Definitions
##
####################################################

if (WIN32)
  # On Windows we must also define UNICODE (otherwise we get type conversion errors
  # when passing strings to Windows functions)
  set (LGPL_EXTRA_FLAGS "-DUNICODE")
endif (WIN32)

set (LGPL_CUSTOM_QT_DEFINES "${LGPL_EXTRA_FLAGS} ${LGPL_COMPILE_OPTIONS}")

# Convert argument string into a list (for use in following CMake commands)
separate_arguments (LGPL_CUSTOM_QT_DEFINES)


####################################################
##
##  Build subprojects
##
####################################################
if (BUILD_DISTRIBUTED_GUI_LIBS)
  add_subdirectory (texteditor)
  add_subdirectory (terminal)         # Sets terminal_SOURCES
  add_subdirectory (remotefiledialog) # Sets remotefiledialog_FORMS and remotefiledialog_SOURCES
endif ()

####################################################
##
##  Construct the ddt-util library
##
####################################################

# List all other sources files
set (util_SOURCES
  internstringcache.cpp
  pathstring.cpp
  qfindbytearray.cpp
  qpipereader.cpp
  qpipewriter.cpp
  qringbuffer.cpp
  )

if (WIN32)
  list (APPEND util_SOURCES
    qpipereader_win.cpp
    qpipewriter_win.cpp
    )
else ()
  list (APPEND util_SOURCES
    qpipereader_unix.cpp
    qpipewriter_unix.cpp
    )
endif (WIN32)

# Unless on Windows the coroutines implementation will require using some assembler
if (NOT WIN32)
  enable_language (ASM)
endif ()
add_subdirectory (coroutine) # sets ${coroutine_SOURCES} in this scope

add_library (ddt-util SHARED
  ${util_SOURCES}
  ${coroutine_SOURCES}
  )

target_include_directories (ddt-util
  PUBLIC  ${CMAKE_CURRENT_SOURCE_DIR}
  ${CMAKE_CURRENT_SOURCE_DIR}/coroutine
  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
  )

set_target_properties (ddt-util PROPERTIES
  DEFINE_SYMBOL    BUILD_LGPL_CORE
  COMPILE_OPTIONS  "${LGPL_CUSTOM_QT_DEFINES}"
  LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/internal/
  )

if (APPLE)
  set_target_properties (ddt-util PROPERTIES
    LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath -Wl,@loader_path/../lib -Wl,-install_name -Wl,@rpath/libddt-util.dylib"
    )
endif ()

target_compile_definitions (ddt-util
  PRIVATE $<$<CONFIG:Debug>:DDT_DEBUG_BUILD>
  )

if (WIN32)
  target_compile_definitions (ddt-util
    PRIVATE _CRT_SECURE_NO_WARNINGS
    )
endif ()

target_link_libraries (ddt-util
    PUBLIC Qt::Core
  )

install (TARGETS ddt-util
        DESTINATION "${LGPL_INSTALL_DIR}"
        )

####################################################
##
##  Construct the ddt-util-gui library
##
####################################################

# List all other sources files
set (util-gui_SOURCES
  detailsbutton.cpp
  detailswidget.cpp
  fixedheightlistwidget.cpp
  flatcommandlinkbutton.cpp
  mdatable.cpp
  remotefiledialog.cpp
  sectionmap.cpp
  tiplabel.cpp
  widercommandlinkbutton.cpp
  )

if (BUILD_DISTRIBUTED_GUI_LIBS)
  add_library (ddt-util-gui SHARED
    ${util-gui_SOURCES}

    # from terminal/ subdirectory
    ${terminal_SOURCES}

    # from remotefiledialog/ subdirectory
    ${remotefiledialog_SOURCES}
    ${remotefiledialog_FORMS}
    )

  target_include_directories (ddt-util-gui
    PUBLIC  ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/terminal
    ${CMAKE_CURRENT_SOURCE_DIR}/remotefiledialog
    PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
    )

  set_target_properties (ddt-util-gui PROPERTIES
    DEFINE_SYMBOL    BUILD_LGPL_GUI
    COMPILE_OPTIONS  "${LGPL_CUSTOM_QT_DEFINES}"
    LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/internal/
    )

  if (APPLE)
    set_target_properties (ddt-util-gui PROPERTIES
      LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath -Wl,@loader_path/../lib -Wl,-install_name -Wl,@rpath/libddt-util-gui.dylib"
      )
  endif ()

  target_compile_definitions (ddt-util-gui
    PRIVATE $<$<CONFIG:Debug>:DDT_DEBUG_BUILD>
    )

  target_link_libraries (ddt-util-gui
    PUBLIC ddt-util
    Qt::Widgets
    Qt::Network
    Qt::CorePrivate
    )
  if (${QT_VERSION_MAJOR} VERSION_GREATER_EQUAL 6)
    find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core5Compat REQUIRED)
    target_link_libraries (ddt-util-gui
      PUBLIC Qt::Core5Compat
    )
  endif()

  if(WIN32 AND ${QT_VERSION_MAJOR} VERSION_LESS_EQUAL 5)
    find_package(Qt${QT_VERSION_MAJOR}WinExtras REQUIRED)
    target_link_libraries (ddt-util-gui
      PUBLIC Qt::WinExtras
    )
  endif()

  if (USE_X11)
    target_link_libraries (ddt-util-gui
        PRIVATE CONAN_PKG::mesa
    )
    if (${QT_VERSION_MAJOR} VERSION_LESS_EQUAL 5)
      target_link_libraries (ddt-util-gui
          PRIVATE Qt::X11Extras
      )
    endif()

    add_custom_target (copy_opengl_libs ALL
      COMMENT "Copying OpenGL libraries"
      )

    foreach (lib ${OPENGL_LIBRARIES})
      get_filename_component (basename ${lib} NAME)
      add_custom_command (OUTPUT ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${basename}
        COMMAND ${CMAKE_COMMAND} -E copy ${lib} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${basename}
        DEPENDS ${lib}
        COMMENT "Copying OpenGL library ${basename}"
        VERBATIM
        )
      add_custom_target (copy_opengl_lib_${basename}
        DEPENDS ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${basename}
        )
      add_dependencies (copy_opengl_libs copy_opengl_lib_${basename})
    endforeach ()
  endif ()

  # Additional link libraries on Windows
  if (WIN32)
    target_link_libraries (ddt-util-gui
      PUBLIC shell32
      ole32
      user32
      )
  endif ()

  install (TARGETS ddt-util-gui
        DESTINATION "${LGPL_INSTALL_DIR}"
        )
endif ()                        # not building Licence Server
