cmake_minimum_required(VERSION 3.12...3.15 FATAL_ERROR)
include(ExternalProject)
include(FetchContent)

project(Beams CXX)

set(CMAKE_POSITION_INDEPENDENT_CODE TRUE CACHE BOOL "Make position independent executables")

FetchContent_Declare(
  fmt
  URL                    https://github.com/fmtlib/fmt/releases/download/9.1.0/fmt-9.1.0.zip
  # OVERRIDE_FIND_PACKAGE
)
set(FMT_TEST OFF CACHE BOOL "Disable tests")
FetchContent_MakeAvailable(fmt)

option(BEAMS_USE_GUI "Build Beams with GUI" OFF)

if(BEAMS_USE_GUI)
  find_package(OpenGL 2 REQUIRED)
  find_package(glfw3 REQUIRED)
  FetchContent_Declare(
    imgui
    URL                    https://github.com/ocornut/imgui/archive/refs/tags/v1.89.8.zip
    # OVERRIDE_FIND_PACKAGE
  )
  FetchContent_Populate(imgui)
  FetchContent_Declare(
    glad
    URL                    https://github.com/Dav1dde/glad/archive/refs/tags/v2.0.4.zip
  )
  FetchContent_Populate(glad)

  add_library(imgui STATIC
  ${imgui_SOURCE_DIR}/imgui.cpp
  ${imgui_SOURCE_DIR}/imgui_draw.cpp
  ${imgui_SOURCE_DIR}/imgui_demo.cpp
  ${imgui_SOURCE_DIR}/imgui_tables.cpp
  ${imgui_SOURCE_DIR}/imgui_widgets.cpp

  ${imgui_SOURCE_DIR}/backends/imgui_impl_glfw.cpp
  ${imgui_SOURCE_DIR}/backends/imgui_impl_opengl2.cpp
  )
  target_include_directories(imgui
    PUBLIC
      ${imgui_SOURCE_DIR}
      ${imgui_SOURCE_DIR}/backends
  )
endif()

find_package(VTKm REQUIRED QUIET)

if(TARGET vtkm_rendering AND VTKm_ENABLE_MPI)
  
  set (BEAMS_SOURCES
  Beams.cxx
  Config.cxx
  Intersections.cxx
  main.cxx
  SceneFactory.cxx
  Timer.cxx
  
  mpi/MpiEnv.cxx

  rendering/BoundsMap.cxx

  rendering/DirectVolumeRendererStructured.cxx
  rendering/Light.cxx
  rendering/LightCollection.cxx
  rendering/LitVolumeRenderer.cxx
  rendering/MapperLitVolume.cxx
  rendering/MapperVolumeBase.cxx
  rendering/MapperDirectVolume.cxx
  rendering/MapperPhongVolume.cxx
  rendering/PhongVolumeRendererStructured.cxx

  rendering/RangeMap.cxx
  rendering/Scene.cxx
  rendering/FileSceneBase.cxx
  rendering/SummerMovieScene.cxx
  rendering/PerlinScene.cxx
  rendering/SpheresScene.cxx
  rendering/Utils.cxx
  rendering/compositing/Compositor.cxx
  rendering/compositing/DirectSendCompositor.cxx
  rendering/compositing/FDirectSendCompositor.cxx
  rendering/compositing/Image.cxx
  rendering/compositing/PartialCompositor.cxx
  rendering/compositing/PayloadCompositor.cxx
  rendering/compositing/PayloadImage.cxx
  rendering/compositing/PNGEncoder.cxx
  rendering/compositing/RadixKCompositor.cxx

  utils/File.cxx
  utils/Fmt.cxx
  utils/Image.cxx
  utils/String.cxx
  utils/Timings.cxx

  source/IcoSphere.cxx
  source/PerlinNoise.cxx
  source/Spheres.cxx
  )

  if(BEAMS_USE_GUI)
    set (BEAMS_SOURCES
      ${BEAMS_SOURCES}
      gui/Window.cxx
    )
  endif()

  set (BEAMS_DEVICE_SOURCES
    rendering/DirectVolumeRendererStructured.cxx
    rendering/LitVolumeRenderer.cxx
    rendering/MapperLitVolume.cxx
    rendering/MapperDirectVolume.cxx
    rendering/MapperPhongVolume.cxx
    rendering/PhongVolumeRendererStructured.cxx
    rendering/Scene.cxx

    source/PerlinNoise.cxx
    source/Spheres.cxx
  )

  set (BEAMS_INCLUDE .)

  set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)

  add_executable(Beams ${BEAMS_SOURCES})
  target_include_directories(Beams PUBLIC ${BEAMS_INCLUDE})
  target_link_libraries(Beams PRIVATE vtkm_rendering vtkm_source vtkm_cont vtkm_filter_density_estimate)
  target_link_libraries(Beams PRIVATE fmt::fmt)
  target_link_libraries(Beams PRIVATE MPI::MPI_CXX)

  if(BEAMS_USE_GUI)
    target_compile_definitions(Beams PRIVATE BEAMS_USE_GUI)
    target_link_libraries(Beams PRIVATE OpenGL::GL)
    target_link_libraries(Beams PRIVATE glfw)
    target_link_libraries(Beams PRIVATE imgui)
  endif()

  vtkm_add_target_information(Beams
                              DROP_UNUSED_SYMBOLS
                              MODIFY_CUDA_FLAGS
                              DEVICE_SOURCES ${BEAMS_DEVICE_SOURCES})
else()
  message(STATUS "Skipping Beams because VTK-m was not built with MPI.")
endif()
