ADD_LIBRARY(JFJochBraggIntegration STATIC
        BraggIntegrationEngine.cpp
        BraggIntegrationEngine.h
        BraggIntegrationEngineCPU.cpp
        BraggIntegrationEngineCPU.h
        BraggPanel.cpp
        BraggPanel.h
        BraggPassA.h
        BraggPassB.h
        BraggExp.h
        SpotFootprint.cpp
        SpotFootprint.h
        Regression.h
        CalcISigma.cpp
        CalcISigma.h
        SystematicAbsence.h
        SpotWidth.cpp
        SpotWidth.h
        BackgroundGain.cpp
        BackgroundGain.h
        BackgroundAperture.cpp
        BackgroundAperture.h
        RingBackground.cpp
        RingBackground.h
)

TARGET_LINK_LIBRARIES(JFJochBraggIntegration JFJochImagePreprocessing JFJochCommon)

IF (JFJOCH_CUDA_AVAILABLE)
    TARGET_SOURCES(JFJochBraggIntegration PRIVATE ../indexing/CUDAMemHelpers.h
            BraggIntegrationEngineGPU.cu BraggIntegrationEngineGPU.h)
ENDIF()

IF (APPLE)
    # The Metal engine compiles its kernels when the program starts, from source carried in the binary:
    # macOS has the Metal compiler built in, while the offline one is an Xcode download of its own. The
    # source is the stencil, exp and pass headers the CPU engine compiles and the kernels, copied
    # into a generated .cpp here; editing one of them re-runs the configure.
    SET(METAL_PARTS stencil BraggStencil.h pass_a BraggPassA.h exp BraggExp.h pass_b BraggPassB.h
            kernels BraggIntegrationEngineMetal.metal)
    SET(METAL_SOURCE "// Generated from image_analysis/bragg_integration by its CMakeLists.txt - do not edit.\n")
    WHILE (METAL_PARTS)
        LIST(POP_FRONT METAL_PARTS name file)
        FILE(READ ${CMAKE_CURRENT_SOURCE_DIR}/${file} text)
        STRING(APPEND METAL_SOURCE "extern const char *const bragg_metal_source_${name};\n"
                "const char *const bragg_metal_source_${name} = R\"BRAGG_METAL(\n// ${file}\n${text})BRAGG_METAL\";\n")
        SET_PROPERTY(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file})
    ENDWHILE()
    # Written only when it changed, so a configure does not rebuild the library.
    FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/BraggIntegrationEngineMetalSource.cpp.tmp "${METAL_SOURCE}")
    CONFIGURE_FILE(${CMAKE_CURRENT_BINARY_DIR}/BraggIntegrationEngineMetalSource.cpp.tmp
                   ${CMAKE_CURRENT_BINARY_DIR}/BraggIntegrationEngineMetalSource.cpp COPYONLY)

    TARGET_SOURCES(JFJochBraggIntegration PRIVATE BraggIntegrationEngineMetal.mm BraggIntegrationEngineMetal.h
            BraggIntegrationEngineMetal.metal ${CMAKE_CURRENT_BINARY_DIR}/BraggIntegrationEngineMetalSource.cpp)
    SET_SOURCE_FILES_PROPERTIES(BraggIntegrationEngineMetal.mm PROPERTIES COMPILE_OPTIONS -fobjc-arc)
    SET_SOURCE_FILES_PROPERTIES(BraggIntegrationEngineMetal.metal PROPERTIES HEADER_FILE_ONLY ON)
    TARGET_LINK_LIBRARIES(JFJochBraggIntegration "-framework Metal" "-framework Foundation")
ENDIF()
