set(sources)
set(headers
  CompilerInfo.h
)
set(operationHeaders)
set(jsonHeaders)

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

set(jsonClasses
  json/jsonResource
)

set(operators
  AllPrimitivesFeature
  AdjacencyFeature
  Boolean
  BooleanIntersect
  BooleanSubtract
  BooleanUnite
  ChartGeneration
  CreateAnnotationResource
  Delete
  Duplicate
  Export
  ExportFeb
  ExportFebModel
  ExportModel
  GrowSelection
  Import
  ImprintGeometry
  ImprintImage
  NetgenSurfaceRemesher
  NormalFeature
  LinearToQuadratic
  PointProximityFeature
  PointsOfPrimitivesFeature
  ProportionalEdit
  ProximityFeature
  Read
  ReconstructSurface
  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
  grow_feature
  imprint_geometry
  imprint_image
  normal_feature
  point_proximity_feature
  points_of_primitives_feature
  proportional_edit
  proximity_feature
  quadratic_promotion
  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()

set(icon_files)
foreach(icon ${icons})
  smtk_encode_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/icons/${icon}.svg"
    TYPE "_svg"
    TARGET_OUTPUT targetName
    HEADER_OUTPUT headerName)
  list(APPEND aevaDependencies ${targetName})
  list(APPEND headers ${headerName})
  list(APPEND icon_files "${CMAKE_CURRENT_SOURCE_DIR}/icons/${icon}.svg")
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()

# Turn "json classes" into source and json headers entries
foreach(class ${jsonClasses})
  list(APPEND jsonHeaders ${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 operationHeaders operators/${operator}.h)
  list(APPEND aevaDependencies ${targetName})
endforeach()

find_package(Boost REQUIRED COMPONENTS filesystem)
if (SMTK_ENABLE_MARKUP)
  set(aeva_smtk_libs smtkMarkup)
endif()

add_library(smtkAEVASession SHARED ${sources} ${headers})
add_dependencies(smtkAEVASession ${aevaDependencies})
target_link_libraries(smtkAEVASession
  PUBLIC
    smtkCore
    ${aeva_smtk_libs}
    ${aeva_pv_libs}
    vtkSMTKSourceExt
    vtkSMTKOperationsExt
    VTK::AEVAExt
    VTK::MeshingNetGen
    nglib
  PRIVATE
    VTK::CommonCore
    VTK::CommonDataModel
    VTK::IOExodus
    VTK::IOImage
    VTK::IOXML
    VTK::IOGeometry
    VTK::ImagingHybrid
    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()
if (SMTK_ENABLE_MARKUP)
  target_compile_definitions(smtkAEVASession PUBLIC SMTK_ENABLE_MARKUP)
endif()
# when SMTK is updated:
# target_compile_definitions(smtkAEVASession PRIVATE QT_NO_KEYWORDS)

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(
  FILES
    ${operationHeaders}
  DESTINATION
    include/${PROJECT_NAME}/${PROJECT_VERSION}/${dir_prefix}/operators)

install(
  FILES
    ${jsonHeaders}
  DESTINATION
    include/${PROJECT_NAME}/${PROJECT_VERSION}/${dir_prefix}/json)

# 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}"
)

# Install icons
install(
  FILES
    ${icon_files}
  DESTINATION
    share/${PROJECT_NAME}/${PROJECT_VERSION}/${dir_prefix}/icons
)

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()
