#-----------------------------------------------------------------------------
cmake_minimum_required(VERSION 3.20.6)
#-----------------------------------------------------------------------------

project(vtkAddon
  LANGUAGES CXX C
  DESCRIPTION "General-purpose features that may be integrated into VTK library in the future."
)


set(vtkAddon_CMAKE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/CMake)
set(CMAKE_MODULE_PATH ${vtkAddon_CMAKE_DIR} ${CMAKE_MODULE_PATH})

include(CMakeDependentOption)
include(vtkAddonFunctionAddExecutable)

# --------------------------------------------------------------------------
# Dependencies
# --------------------------------------------------------------------------

#
# VTK
#
set(vtkAddon_VTK_COMPONENTS
  CommonComputationalGeometry
  FiltersModeling
  FiltersHybrid
  FiltersSources
  ImagingGeneral
  RenderingOpenGL2
  RenderingVolumeOpenGL2
  eigen
)
if(vtkAddon_WRAP_PYTHON)
  list(APPEND vtkAddon_VTK_COMPONENTS Python)
endif()
find_package(VTK REQUIRED COMPONENTS ${vtkAddon_VTK_COMPONENTS})
if(${VTK_VERSION} VERSION_LESS "8.90")
  include(${VTK_USE_FILE})
endif()
set(vtkAddon_LIBS ${VTK_LIBRARIES})

# --------------------------------------------------------------------------
# Options
# --------------------------------------------------------------------------
if(NOT DEFINED BUILD_SHARED_LIBS)
  option(BUILD_SHARED_LIBS "Build with shared libraries." ON)
endif()

if(NOT DEFINED BUILD_TESTING)
  option(BUILD_TESTING "Test the project" OFF)
endif()

if(NOT DEFINED vtkAddon_USE_UTF8)
  option(vtkAddon_USE_UTF8 "Make applications use UTF-8 as code page." OFF)
endif()

if(NOT DEFINED vtkAddon_WRAP_PYTHON)
  cmake_dependent_option(vtkAddon_WRAP_PYTHON "Build python wrapping" OFF "VTK_WRAP_PYTHON" OFF)
endif()

if(NOT DEFINED vtkAddon_LAUNCH_COMMAND)
  set(vtkAddon_LAUNCH_COMMAND "" CACHE STRING "Command for setting up environment and running executables")
endif()

# --------------------------------------------------------------------------
# Configure headers
# --------------------------------------------------------------------------
set(configure_header_file vtkAddonConfigure.h)
configure_file(
  ${CMAKE_CURRENT_SOURCE_DIR}/${configure_header_file}.in
  ${CMAKE_CURRENT_BINARY_DIR}/${configure_header_file}
  )

# --------------------------------------------------------------------------
# Sources
# --------------------------------------------------------------------------
set(vtkAddon_SRCS
  vtkAddon.h
  ${CMAKE_CURRENT_BINARY_DIR}/${configure_header_file}
  vtkAddonExport.h
  vtkAddonTestingMacros.h
  vtkAddonMathUtilities.cxx
  vtkAddonMathUtilities.h
  vtkAddonSetGet.h
  vtkAddonTestingUtilities.cxx
  vtkAddonTestingUtilities.h
  vtkAddonTestingUtilities.txx
  vtkCurveGenerator.cxx
  vtkCurveGenerator.h
  vtkErrorSink.cxx
  vtkErrorSink.h
  vtkImageLabelDilate3D.cxx
  vtkImageLabelDilate3D.h
  vtkLinearSpline.cxx
  vtkLinearSpline.h
  vtkLoggingMacros.h
  vtkOrientedBSplineTransform.cxx
  vtkOrientedBSplineTransform.h
  vtkOrientedGridTransform.cxx
  vtkOrientedGridTransform.h
  vtkParallelTransportFrame.cxx
  vtkParallelTransportFrame.h
  vtkParametricPolynomialApproximation.cxx
  vtkParametricPolynomialApproximation.h
  vtkPersonInformation.cxx
  vtkPersonInformation.h
  vtkRawRGBVolumeCodec.cxx
  vtkRawRGBVolumeCodec.h
  vtkSingleton.h
  vtkSlicerDijkstraGraphGeodesicPath.cxx
  vtkSlicerDijkstraGraphGeodesicPath.h
  vtkStreamingVolumeCodec.cxx
  vtkStreamingVolumeCodec.h
  vtkStreamingVolumeCodecFactory.cxx
  vtkStreamingVolumeCodecFactory.h
  vtkStreamingVolumeFrame.cxx
  vtkStreamingVolumeFrame.h
  vtkTestingOutputWindow.cxx
  vtkTestingOutputWindow.h
)

if(VTK_RENDERING_BACKEND STREQUAL "OpenGL2")
  set(vtkAddon_SRCS
    ${vtkAddon_SRCS}
    vtkOpenGLShaderComputation.cxx
    vtkOpenGLShaderComputation.h
    vtkOpenGLTextureImage.cxx
    vtkOpenGLTextureImage.h
  )
  find_package(OpenGL)
  set(vtkAddon_LIBS
    ${vtkAddon_LIBS}
    ${OPENGL_LIBRARIES}
  )
endif()

# Abstract/pure virtual classes

#set_source_files_properties(
#  ABSTRACT
#  )

# Helper classes

set_source_files_properties(
  vtkAddonSetGet.h
  vtkAddonTestingUtilities.h
  vtkLoggingMacros.h
  WRAP_EXCLUDE
  )

# --------------------------------------------------------------------------
# Build library
# --------------------------------------------------------------------------
set(lib_name ${PROJECT_NAME})

set(srcs ${vtkAddon_SRCS})
add_library(${lib_name} ${srcs})

target_link_libraries(${lib_name} ${vtkAddon_LIBS})

if(NOT DEFINED ${PROJECT_NAME}_INSTALL_INCLUDE_DIR)
  set(${PROJECT_NAME}_INSTALL_INCLUDE_DIR "include/${PROJECT_NAME}")
endif()

target_include_directories(${lib_name} BEFORE PUBLIC
  $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
  $<INSTALL_INTERFACE:${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}>
)

# --------------------------------------------------------------------------
# Folder
# --------------------------------------------------------------------------
if(NOT DEFINED ${PROJECT_NAME}_FOLDER)
  set(${PROJECT_NAME}_FOLDER ${PROJECT_NAME})
endif()
if(NOT "${${PROJECT_NAME}_FOLDER}" STREQUAL "")
  set_target_properties(${lib_name} PROPERTIES FOLDER ${${PROJECT_NAME}_FOLDER})
endif()

# --------------------------------------------------------------------------
# Export target
# --------------------------------------------------------------------------

# Export targets for a build tree
if(NOT DEFINED ${PROJECT_NAME}_EXPORT_FILE)
  set(${PROJECT_NAME}_EXPORT_FILE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake)
endif()
export(TARGETS ${lib_name} APPEND FILE ${${PROJECT_NAME}_EXPORT_FILE})

# --------------------------------------------------------------------------
# Install library
# --------------------------------------------------------------------------
if(NOT DEFINED ${PROJECT_NAME}_INSTALL_BIN_DIR)
  set(${PROJECT_NAME}_INSTALL_BIN_DIR bin)
endif()
if(NOT DEFINED ${PROJECT_NAME}_INSTALL_LIB_DIR)
  set(${PROJECT_NAME}_INSTALL_LIB_DIR lib/${PROJECT_NAME})
endif()

install(TARGETS ${lib_name}
  EXPORT vtkAddonTargets
  RUNTIME DESTINATION ${${PROJECT_NAME}_INSTALL_BIN_DIR} COMPONENT RuntimeLibraries
  LIBRARY DESTINATION ${${PROJECT_NAME}_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries
  ARCHIVE DESTINATION ${${PROJECT_NAME}_INSTALL_LIB_DIR} COMPONENT Development
  )

# --------------------------------------------------------------------------
# Python Wrapping
# --------------------------------------------------------------------------
if(vtkAddon_WRAP_PYTHON)

  if(NOT DEFINED ${PROJECT_NAME}_INSTALL_PYTHON_MODULE_LIB_DIR)
    set(${PROJECT_NAME}_INSTALL_PYTHON_MODULE_LIB_DIR ${${PROJECT_NAME}_INSTALL_LIB_DIR})
  endif()
  if(NOT DEFINED ${PROJECT_NAME}_INSTALL_PYTHON_LIB_DIR)
    set(${PROJECT_NAME}_INSTALL_PYTHON_LIB_DIR ${${PROJECT_NAME}_INSTALL_LIB_DIR})
  endif()

  include(vtkMacroKitPythonWrap)

  vtkMacroKitPythonWrap(
    KIT_NAME ${lib_name}
    KIT_SRCS ${vtkAddon_SRCS}
    KIT_INSTALL_BIN_DIR ${${PROJECT_NAME}_INSTALL_BIN_DIR}
    KIT_INSTALL_LIB_DIR ${${PROJECT_NAME}_INSTALL_PYTHON_LIB_DIR}
    KIT_MODULE_INSTALL_LIB_DIR ${${PROJECT_NAME}_INSTALL_PYTHON_MODULE_LIB_DIR}
    )
  # Export target
  export(TARGETS ${lib_name}Python APPEND FILE ${${PROJECT_NAME}_EXPORT_FILE})
  if(${VTK_VERSION} VERSION_LESS "8.90")
    export(TARGETS ${lib_name}PythonD APPEND FILE ${${PROJECT_NAME}_EXPORT_FILE})
  endif()
  # Folder
  if(NOT "${${PROJECT_NAME}_FOLDER}" STREQUAL "")
    set_target_properties(${lib_name}Python PROPERTIES FOLDER ${${PROJECT_NAME}_FOLDER})
    if(${VTK_VERSION} VERSION_LESS "8.90")
      set_target_properties(${lib_name}PythonD PROPERTIES FOLDER ${${PROJECT_NAME}_FOLDER})
    endif()
    if(TARGET ${lib_name}Hierarchy)
      set_target_properties(${lib_name}Hierarchy PROPERTIES FOLDER ${${PROJECT_NAME}_FOLDER})
    endif()
  endif()
endif()

# --------------------------------------------------------------------------
# Testing
# --------------------------------------------------------------------------
if(BUILD_TESTING)
  include(CTest)
  add_subdirectory(Testing)
endif()

# --------------------------------------------------------------------------
# Set INCLUDE_DIRS variable
# --------------------------------------------------------------------------
set(${PROJECT_NAME}_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
  CACHE INTERNAL "${PROJECT_NAME} include dirs" FORCE)

# --------------------------------------------------------------------------
# Configure support file
# --------------------------------------------------------------------------

# Configure 'vtkAddonConfig.cmake' for a build tree
configure_file(
  ${CMAKE_CURRENT_SOURCE_DIR}/vtkAddonConfig.cmake.in
  ${CMAKE_CURRENT_BINARY_DIR}/vtkAddonConfig.cmake
  @ONLY
  )

# --------------------------------------------------------------------------
# Install development files
# --------------------------------------------------------------------------

if(NOT DEFINED ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT)
  set(${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT ON)
endif()

if(NOT DEFINED ${PROJECT_NAME}_INSTALL_CMAKE_DIR)
  # uses one of find_package universal prefix by default
  set(${PROJECT_NAME}_INSTALL_CMAKE_DIR "${PROJECT_NAME}/lib/cmake/${PROJECT_NAME}")
endif()

if(NOT ${PROJECT_NAME}_INSTALL_NO_DEVELOPMENT)
  # Install vtkAddon headers, uses a pattern because they are not explicitly listed
  set(vtkAddon_HEADERS ${vtkAddon_SRCS})
  list(FILTER vtkAddon_HEADERS INCLUDE REGEX ".*\\.(h|txx)$")
  install(
    FILES ${vtkAddon_HEADERS}
    DESTINATION "${${PROJECT_NAME}_INSTALL_INCLUDE_DIR}"
    COMPONENT Development
    )

  # Configure vtkAddonInstallConfig.cmake for the install tree
  include(CMakePackageConfigHelpers)
  configure_package_config_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/vtkAddonInstallConfig.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/install/vtkAddonConfig.cmake
    INSTALL_DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKE_DIR}"
    )

  install(
    FILES ${CMAKE_CURRENT_BINARY_DIR}/install/vtkAddonConfig.cmake
    DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKE_DIR}"
    COMPONENT Development
    )

  install(
    EXPORT vtkAddonTargets
    FILE ${PROJECT_NAME}Targets.cmake
    DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKE_DIR}"
    COMPONENT Development
    )
endif()

# Install vtkAddon CMake files
install(
  FILES
  ${CMAKE_SOURCE_DIR}/CMake/vtkAddonFunctionAddExecutable.cmake
  ${CMAKE_SOURCE_DIR}/CMake/vtkAddonFunctionAddExecutable.cmake
  ${CMAKE_SOURCE_DIR}/CMake/vtkMacroKitPythonWrap.cmake
  ${CMAKE_SOURCE_DIR}/CMake/vtkWrapHierarchy.cmake
  ${CMAKE_SOURCE_DIR}/CMake/vtkWrapperInit.data.in
  ${CMAKE_SOURCE_DIR}/CMake/vtkWrapPython.cmake
  ${CMAKE_SOURCE_DIR}/CMake/WindowsApplicationUseUtf8.manifest
  DESTINATION "${${PROJECT_NAME}_INSTALL_CMAKE_DIR}"
  COMPONENT Development
  )
