set(sources)
set(headers)

set(classes
  CellSelection
  Geometry
  NameManager
  Operation
  OperationDecorator
  Predicates
  Registrar
  Resource
  Session
  json/jsonResource
)

set(operators
  AllPrimitivesFeature
  AdjacencyFeature
  Boolean
  BooleanIntersect
  BooleanSubtract
  BooleanUnite
  ChartGeneration
  CreateAnnotationResource
  Delete
  Duplicate
  EditFreeformAttributes
  Export
  ExportFeb
  ExportFebModel
  ExportModel
  GrowSelection
  Import
  ImprintGeometry
  ImprintImage
  # MeshLabel
  NetgenSurfaceRemesher
  NormalFeature
  LinearToQuadratic
  PointsOfPrimitivesFeature
  ProportionalEdit
  ProximityFeature
  Read
  ReconstructSurface
  # Segment
  SmoothSurface
  TextureAtlas
  UnreferencedPrimitives
  VolumeMesher
  VolumeInspect
  Write
)

set(icons
  adjacency_feature
  all_primitives_feature
  boolean_unite
  boolean_intersect
  boolean_subtract
  boolean_symmetric_subtract
  create_annotations
  contains_feature
  duplicate
  freeform_attributes
  grow_feature
  imprint_geometry
  imprint_image
  normal_feature
  quadratic_promotion
  points_of_primitives_feature
  proportional_edit
  proximity_feature
  reconstruct_surface
  smooth_surface
  unreferenced_primitives
  volume_inspector
  volume_mesh
)

set(aeva_pv_depends)
set(aeva_pv_private_depends)
if(SMTK_ENABLE_PARAVIEW_SUPPORT)
  list(APPEND classes RegisterStyleFunction)
  list(APPEND operators SelectionResponder)
  set(aeva_pv_libs smtkPVServerExt)
  set(aeva_pv_private_libs smtkPQComponentsExt)
endif()

foreach(icon ${icons})
  smtk_encode_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/icons/${icon}.svg" TYPE "_svg" TARGET_OUTPUT targetName)
  list(APPEND aevaDependencies ${targetName})
endforeach()

# smtk_encode_file results in errors on MSVC about too-long array.
# As long as we don't need the includes, we can use VTK's solution:
vtk_encode_string(
  INPUT "${CMAKE_CURRENT_SOURCE_DIR}/../../../data/workflow/aeva.sbt"
  NAME "aeva_xml"
  HEADER_OUTPUT sbtHeader
  SOURCE_OUTPUT sbtSource
  BINARY
  NUL_TERMINATE)
list(APPEND sources "${sbtSource}")
list(APPEND headers "${sbtHeader}")

file(GLOB SESSION_FILES "*.h" "*.cxx")
source_group("session" FILES ${SESSION_FILES})
file(GLOB OPERATIONS_FILES "operators/*.h" "operators/*.cxx" "operators/*.sbt")
source_group("session\\operators" FILES ${OPERATIONS_FILES})

# Turn "classes" into source and headers entries
foreach(class ${classes})
  list(APPEND headers ${class}.h)
  list(APPEND sources ${class}.cxx)
endforeach()

# Configure smtk/session/aeva/Version.{h,cxx}
configure_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/Version.h.in"
  "${CMAKE_CURRENT_BINARY_DIR}/Version.h"
  @ONLY
)
configure_file(
  "${CMAKE_CURRENT_SOURCE_DIR}/Version.cxx.in"
  "${CMAKE_CURRENT_BINARY_DIR}/Version.cxx"
  @ONLY
)
list(APPEND headers "${CMAKE_CURRENT_BINARY_DIR}/Version.h")
list(APPEND sources "${CMAKE_CURRENT_BINARY_DIR}/Version.cxx")

# Operators which have XML descriptions in separate files
# need to have it encoded as a string in a header.
foreach (operator ${operators})
  smtk_encode_file("${CMAKE_CURRENT_SOURCE_DIR}/operators/${operator}.sbt"
  TARGET_OUTPUT targetName)
  list(APPEND sources operators/${operator}.cxx)
  list(APPEND headers operators/${operator}.h)
  list(APPEND aevaDependencies ${targetName})
endforeach()

find_package(Boost REQUIRED COMPONENTS filesystem)

add_library(smtkAEVASession SHARED ${sources} ${headers})
add_dependencies(smtkAEVASession ${aevaDependencies})
target_link_libraries(smtkAEVASession
  PUBLIC
    smtkCore
    ${aeva_pv_libs}
    vtkSMTKSourceExt
    vtkSMTKOperationsExt
    VTK::AEVAExt
    VTK::MeshingNetGen
    nglib
  PRIVATE
    VTK::CommonCore
    VTK::CommonDataModel
    VTK::IOExodus
    VTK::IOImage
    VTK::IOXML
    VTK::IOGeometry
    VTK::FiltersCore
    VTK::FiltersExtraction
    VTK::FiltersGeometry
    VTK::FiltersParallelDIY2
    VTK::FiltersPoints
    VTK::AcceleratorsVTKmFilters
    VTK::eigen
    ${aeva_pv_private_libs}
    ${ITK_LIBRARIES}
    ${__dependencies}
    Boost::filesystem
    VTK::hdf5
    VTK::pugixml
)
target_include_directories(smtkAEVASession
  PUBLIC
    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
    $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
    $<INSTALL_INTERFACE:include>
)
target_compile_definitions(smtkAEVASession PRIVATE ${HDF5_DEFINITIONS})
if (SMTK_ENABLE_PARAVIEW_SUPPORT)
  target_compile_definitions(smtkAEVASession PUBLIC SMTK_ENABLE_PARAVIEW_SUPPORT)
endif()

generate_export_header(smtkAEVASession EXPORT_FILE_NAME Exports.h)

smtk_get_kit_name(name dir_prefix)

# Install the header files
# XXX: SMTK assumes everything shares its version number. Hack it up.
set(SMTK_VERSION "${PROJECT_VERSION}")
smtk_public_headers(smtkAEVASession
  ${headers}
  ${CMAKE_CURRENT_BINARY_DIR}/Exports.h)

# Install the library and exports
install(
  TARGETS smtkAEVASession
  EXPORT  AEVASession
  ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
  PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${PROJECT_VERSION}/${dir_prefix}"
)

if(SMTK_ENABLE_PARAVIEW_SUPPORT)
  paraview_plugin_scan(
    PLUGIN_FILES "${CMAKE_CURRENT_SOURCE_DIR}/plugin/paraview.plugin"
    PROVIDES_PLUGINS paraview_plugins
    ENABLE_BY_DEFAULT ON
    HIDE_PLUGINS_FROM_CACHE ON
  )
  paraview_plugin_build(
    HEADERS_DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/${PROJECT_VERSION}"
    LIBRARY_SUBDIRECTORY "${PROJECT_NAME}-${PROJECT_VERSION}"
    PLUGINS ${paraview_plugins}
    PLUGINS_FILE_NAME "aeva.session.xml"
    AUTOLOAD ${paraview_plugins}
    INSTALL_EXPORT AEVASessionPlugins
    CMAKE_DESTINATION ${CMAKE_INSTALL_CMAKEDIR}
    ADD_INSTALL_RPATHS ON
    TARGET aeva_session_paraview_plugins
  )
endif()

if (AEVA_ENABLE_PYTHON)
  add_subdirectory(pybind11)
endif()

if (AEVA_ENABLE_TESTING)
  add_subdirectory(testing)
endif()
