cmake_minimum_required(VERSION 3.20)
project(XMSMeshOperation VERSION 2.0.0)

set(BUILD_SHARED_LIBS ON)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS False)
set(CMAKE_MODULE_PATH
  "${SMTK_DIR}"
  ${CMAKE_MODULE_PATH}
)

include(GNUInstallDirs)
set(CMAKE_INSTALL_CMAKEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})

#Add our Cmake directory to the module search path
list(APPEND CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMake)

find_package(XMSCore REQUIRED NAMES xms xmscore)
find_package(XMSGrid REQUIRED NAMES xms xmsgrid)
find_package(XMSInterp REQUIRED NAMES xms xmsinterp)
find_package(XMSMesher REQUIRED NAMES xms xmsmesher)

# Set the directory where the binaries will be stored
set(EXECUTABLE_OUTPUT_PATH         ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

include(XMSSMTKTestingMacros)

#Setup SMTK
#########################################################################
find_package(smtk QUIET REQUIRED)

# this is probably not the right way to do this, but we need the path to SMTK's
# include directory so EncodeStringFunctions.cmake finds things.
get_target_property(SMTK_INCLUDE_DIR smtkCore INTERFACE_INCLUDE_DIRECTORIES)
get_target_property(SMTK_LIB_DIR smtkCore LOCATION)
get_filename_component(SMTK_LIB_DIR ${SMTK_LIB_DIR} DIRECTORY)

# Setting this ensures that "make install" will leave rpaths to external
# libraries (not part of the build-tree e.g. Qt, ffmpeg, etc.) intact on
# "make install". This ensures that one can install a version of ParaView on the
# build machine without any issues. If this not desired, simply specify
# CMAKE_INSTALL_RPATH_USE_LINK_PATH when configuring and "make install" will
# strip all rpaths, which is default behavior.
if (NOT CMAKE_INSTALL_RPATH_USE_LINK_PATH)
  set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
endif ()

#Setup up the option to enable the testing directory
option(ENABLE_TESTING "Enable Testing" OFF)

#Setup up the option to enable python wrapping using pybind11
option(ENABLE_PYTHON_WRAPPING "Build Python Wrappings" OFF)

include(CMakeDependentOption)

cmake_dependent_option(
  INSTALL_PYTHON_TO_SITE_PACKAGES
  "Install Python modules to the interpreter's site-packages directory or into CMAKE_INSTALL_PREFIX?"
  OFF
  ENABLE_PYTHON_WRAPPING OFF)

if(ENABLE_PYTHON_WRAPPING)
  set(CMAKE_POSITION_INDEPENDENT_CODE ON)

  # by including the correct python cmake scripts before adding pybind11, we
  # work around pybind11's custom python cmake scripts without having to patch
  # pybind11.
  if (NOT PYTHONINTERP_FOUND)
    find_package(PythonInterp 2.7 REQUIRED)
  endif ()

  if (NOT PYTHONLIBS_FOUND)
    find_package(PythonLibs REQUIRED)
  endif ()

  if(MSVC)
    set(PYTHON_MODULE_EXTENSION ".pyd")
  else()
    set(PYTHON_MODULE_EXTENSION ".so")
  endif()
  set(PYTHON_MODULE_PREFIX "")

  find_package(pybind11 REQUIRED)

  set(PYBIND11_FLAGS " ")
  if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR
      CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
      CMAKE_CXX_COMPILER_ID MATCHES "Intel")
    set(PYBIND11_FLAGS "${PYBIND11_FLAGS} -Wno-shadow")
  endif()

  # Initialize PYTHON_MODULEDIR.
  # This stores the location where we'll install our Python modules.
  # Note that PYTHON_MODULEDIR may be provided if the project is being
  # built as a submodule or as part of a superbuild.
  if (NOT DEFINED PYTHON_MODULEDIR)
    if (INSTALL_PYTHON_TO_SITE_PACKAGES)
      execute_process(
        COMMAND
        ${PYTHON_EXECUTABLE}
        -c "import site; print(site.getsitepackages())[-1]"
        RESULT_VARIABLE PYTHON_MODULEDIR
        )
    elseif(WIN32)
      set(PYTHON_MODULEDIR
        "bin/Lib/site-packages")
    else()
      set(PYTHON_MODULEDIR
        "lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages")
    endif()
  endif()
endif()

if(ENABLE_TESTING)
  enable_testing()

  set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib/")
endif()

###  Header locations
#
# Locations of dependent package headers
include_directories(
  "${CMAKE_CURRENT_SOURCE_DIR}"
  "${CMAKE_CURRENT_BINARY_DIR}"
)

# Build the project
add_subdirectory(smtk)

if (SMTK_ENABLE_PARAVIEW_SUPPORT)
  paraview_plugin_scan(
    PLUGIN_FILES "${CMAKE_CURRENT_SOURCE_DIR}/smtk/mesh/xms/plugin/paraview.plugin"
    PROVIDES_PLUGINS paraview_plugins
    ENABLE_BY_DEFAULT ON
    HIDE_PLUGINS_FROM_CACHE ON
  )

  string(REPLACE "-" "_" safe_project_name "${PROJECT_NAME}")

  paraview_plugin_build(
    HEADERS_DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${PROJECT_VERSION}"
    LIBRARY_SUBDIRECTORY "smtk-${smtk_VERSION}"  # put the plugin .xml with smtk plugins.
    PLUGINS ${paraview_plugins}
    PLUGINS_FILE_NAME "smtk.xmsmeshoperation.xml"
    AUTOLOAD ${paraview_plugins}
    INSTALL_EXPORT ${PROJECT_NAME}-plugin
    CMAKE_DESTINATION ${CMAKE_INSTALL_CMAKEDIR}
    ADD_INSTALL_RPATHS ON
    TARGET ${safe_project_name}_paraview_plugins
  )
endif ()

# Construct install CMake logic
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
  "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}ConfigVersion.cmake"
  VERSION ${${PROJECT_NAME}_VERSION}
  COMPATIBILITY AnyNewerVersion
)

export(EXPORT xms_smtk
  FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Targets.cmake"
)
get_property(SMTK_PLUGINS GLOBAL PROPERTY SMTK_PLUGINS)

configure_file(${PROJECT_SOURCE_DIR}/CMake/${PROJECT_NAME}Config.cmake.in
  ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Config.cmake @ONLY)

list(APPEND CMAKE_CONFIGURE_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Config.cmake")

install(EXPORT xms_smtk
  FILE
    ${PROJECT_NAME}Targets.cmake
  DESTINATION
    ${CMAKE_INSTALL_CMAKEDIR}
)
#install(EXPORT
  #FILE
    #${PROJECT_NAME}-Targets.cmake
  #DESTINATION
    #${CMAKE_INSTALL_CMAKEDIR}
#)
install(
  FILES
    "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Config.cmake"
    "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}ConfigVersion.cmake"
  DESTINATION
    ${CMAKE_INSTALL_CMAKEDIR}
  COMPONENT
    Devel
)
