# Manyo Library LevmarTools module
set(MODULENAME LevmarTools)

#
# ========= Dependencies =========
#

# Find OpenMP, GSL
find_package(GSL REQUIRED)
find_package(OpenMP)

if (POLICY CMP0167)
    cmake_policy (SET CMP0167 NEW)
endif ()
find_package(Boost 1.66.0 REQUIRED
    COMPONENTS
        serialization
)

#
# ========= SWIG =========
#

CMAKE_POLICY(SET CMP0086 NEW)
find_package(SWIG REQUIRED)
include(UseSWIG)

#
# ========= Library =========
#

add_library(${MODULENAME} SHARED)
target_sources(${MODULENAME} PRIVATE
    AdvAdditionalData.cc
    AdvAugmentedLorentzian.cc
    AdvAugmentedLorentzianConv.cc
    AdvBSpline.cc
    AdvConstant.cc
    AdvConstantConv.cc
    AdvConvDeconv.cc
    AdvConvDeconvPre.cc
    AdvConvergenceStat.cc
    AdvConvolutionBase.cc
    AdvConvolutionByFFT.cc
    AdvConvolutionConsts.cc
    AdvDampedHarmonicOscillator.cc
    AdvDampedHarmonicOscillatorConv.cc
    AdvDeconvolutionByFFT.cc
    AdvDeltaConv.cc
    AdvDomain.cc
    AdvEqualSpacing.cc
    AdvErrorFunction.cc
    AdvExponential.cc
    AdvExtVectorTool.cc
    AdvFitCommand.cc
    AdvFuncBase.cc
    AdvFuncComb.cc
    AdvFuncCombToElementContainer.cc
    AdvFuncConv.cc
    AdvFuncParser.cc
    AdvGaussian.cc
    AdvGaussianConv.cc
    AdvGslFFTComplex.cc
    AdvInsMEM.cc
    AdvLevmarArgs.cc
    AdvLevmarConsts.cc
    AdvLevmarControl.cc
    AdvLevmarFit.cc
    AdvLevmarFunc.cc
    AdvLevmarImmutables.cc
    AdvLorentzian.cc
    AdvLorentzianConv.cc
    AdvMatrixUtil.cc
    AdvMessage.cc
    AdvMethod.cc
    AdvMethodFactory.cc
    AdvMethodType.cc
    AdvModel.cc
    AdvModelDistribution.cc
    AdvModelLayer.cc
    AdvModelParam.cc
    AdvModelParamSet.cc
    AdvModelParticle.cc
    AdvModelParticleType.cc
    AdvModelSmallAngle.cc
    AdvModelSpecular.cc
    AdvModelSpecularMul.cc
    AdvMovingAverage.cc
    AdvMultiDataLevmar.cc
    AdvMultiDataLevmarConsts.cc
    AdvMultiDataMethod.cc
    AdvMultiDataMethodFactory.cc
    AdvMultiDataOperationBase.cc
    AdvMultiDataPeakFit.cc
    AdvNewLevmar.cc
    AdvOperationBase.cc
    AdvOperationType.cc
    AdvParamSet.cc
    AdvPeak.cc
    AdvPeakData.cc
    AdvPeakFit.cc
    AdvPeakSearch.cc
    AdvPeakType.cc
    AdvPolynomial1.cc
    AdvPolynomial1Conv.cc
    AdvPolynomial2.cc
    AdvPolynomial2Conv.cc
    AdvPolynomial3.cc
    AdvPolynomial3Conv.cc
    AdvPseudoVoigt1.cc
    AdvPseudoVoigt1Conv.cc
    AdvPseudoVoigt2.cc
    AdvPseudoVoigt2Conv.cc
    AdvReportConvergenceProcess.cc
    AdvSimulatedAnnealingArgs.cc
    AdvSimulatedAnnealing.cc
    AdvSimulatedAnnealingConsts.cc
    AdvSmoothing.cc
    AdvTrapezoid.cc
    AdvTriangle.cc
    AdvVectorArrayConv.cc
    AdvVectorComplexTool.cc
    AdvVectorGSLVectorConv.cc
    ThreadBase.cc
)

#
# ========= Compile Settings =========
#

target_compile_features(${MODULENAME} PRIVATE cxx_std_11)
target_compile_options(${MODULENAME} PRIVATE
    -O3
    -Werror=return-type
)

#
# ========= Compile Definitions =========
#

if (${LIBMXML} MATCHES "mxml4")
    target_compile_definitions(${MODULENAME} PRIVATE LIBMXML4)
endif()

#
# ========= Include Paths =========
#

target_include_directories(${MODULENAME}
    PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}
    PRIVATE
        ${MANYO_ROOT_PATH}/include/manyo
        ${MANYO_ROOT_PATH}/include/manyo/MLF
        ${MANYO_ROOT_PATH}/include/manyo/Utsusemi
        ${MANYO_NEXUS_PATH}/include
        ${MANYO_MXML_INC_PATH}
        ${CMAKE_CURRENT_SOURCE_DIR}/../lib-levmar/2.5
)

#
# ========= Linking =========
#

target_link_libraries(${MODULENAME}
    PRIVATE
        Manyo
        MLF
        NeXus
        levmar
        ${LIBMXML}
        Python::Python
        OpenMP::OpenMP_CXX
        GSL::gsl
        Boost::serialization
        util
        dl
)

target_link_directories(${MODULENAME}
    PRIVATE
        ${MANYO_ROOT_PATH}/${MANYO_LIB_PATH}
        ${MANYO_NEXUS_PATH}/lib
        ${MANYO_MXML_LIB_PATH}
        ${CMAKE_BINARY_DIR}/lib-levmar/2.5
)

#
# ========= SWIG Module =========
#

set_property(SOURCE ${MODULENAME}.i PROPERTY CPLUSPLUS ON)
set_property(SOURCE ${MODULENAME}.i
    PROPERTY INCLUDE_DIRECTORIES
        ${MANYO_ROOT_PATH}/include/manyo
        ${MANYO_ROOT_PATH}/include/manyo/MLF
        ${MANYO_ROOT_PATH}/include/manyo/Utsusemi
        ${MANYO_NEXUS_PATH}/include
)

swig_add_library(Manyo${MODULENAME}
    TYPE MODULE
    LANGUAGE python
    OUTPUT_DIR ${PROJECT_BINARY_DIR}/
    SOURCES ${MODULENAME}.i
)

# Compile definitions
if (${LIBMXML} MATCHES "mxml4")
    target_compile_definitions(Manyo${MODULENAME} PRIVATE LIBMXML4)
endif()

# Compile definitions
if (${LIBMXML} MATCHES "mxml4")
    target_compile_definitions(Manyo${MODULENAME} PRIVATE LIBMXML4)
endif()

# Include paths
target_include_directories(Manyo${MODULENAME}
    PUBLIC
        ${CMAKE_CURRENT_SOURCE_DIR}
    PRIVATE
        ${MANYO_ROOT_PATH}/include/manyo
        ${MANYO_ROOT_PATH}/include/manyo/MLF
        ${MANYO_ROOT_PATH}/include/manyo/Utsusemi
        ${MANYO_NEXUS_PATH}/include
        ${MANYO_MXML_INC_PATH}
        ${CMAKE_CURRENT_SOURCE_DIR}/../lib-levmar/2.5
)

# Linking
target_link_libraries(Manyo${MODULENAME}
    PRIVATE
        ${MODULENAME}
        Manyo
        MLF
        NeXus
        levmar
        ${LIBMXML}
        Python::Python
        OpenMP::OpenMP_CXX
        GSL::gsl
        Boost::serialization
        util
        dl
)

target_link_directories(Manyo${MODULENAME}
    PRIVATE
        ${MANYO_ROOT_PATH}/${MANYO_LIB_PATH}
        ${MANYO_NEXUS_PATH}/lib
        ${MANYO_MXML_LIB_PATH}
        ${CMAKE_BINARY_DIR}/lib-levmar/2.5
)

#
# ========= Install =========
#

# Install library
install(TARGETS ${MODULENAME}
    RUNTIME DESTINATION bin
    LIBRARY DESTINATION ${MANYO_ROOT_PATH}/${MANYO_LIB_PATH}
)
install(FILES
    AdvAdditionalData.hh
    AdvAugmentedLorentzianConv.hh
    AdvAugmentedLorentzian.hh
    AdvBSpline.hh
    AdvConstantConv.hh
    AdvConstant.hh
    AdvContainerBaseTemplate.hh
    AdvContainerDumpTool.hh
    AdvContainerForMatrix.hh
    AdvContainerForVector.hh
    AdvConvDeconv.hh
    AdvConvDeconvPre.hh
    AdvConvergenceStat.hh
    AdvConvolutionBase.hh
    AdvConvolutionByFFT.hh
    AdvConvolutionConsts.hh
    AdvDampedHarmonicOscillatorConv.hh
    AdvDampedHarmonicOscillator.hh
    AdvDeconvolutionByFFT.hh
    AdvDeltaConv.hh
    AdvDomain.hh
    AdvEqualSpacing.hh
    AdvErrorFunction.hh
    AdvExponential.hh
    AdvExtVectorTool.hh
    AdvFitCommand.hh
    AdvFuncBase.hh
    AdvFuncComb.hh
    AdvFuncCombToElementContainer.hh
    AdvFuncConv.hh
    AdvFuncParser.hh
    AdvGaussianConv.hh
    AdvGaussian.hh
    AdvGslFFTComplex.hh
    AdvInsMEM.hh
    AdvLevmarArgs.hh
    AdvLevmarConsts.hh
    AdvLevmarControl.hh
    AdvLevmarFit.hh
    AdvLevmarFunc.hh
    AdvLevmarImmutables.hh
    AdvLogger.hh
    AdvLorentzianConv.hh
    AdvLorentzian.hh
    AdvMatrixUtil.hh
    AdvMessage.hh
    AdvMethodFactory.hh
    AdvMethod.hh
    AdvMethodType.hh
    AdvModelDistribution.hh
    AdvModel.hh
    AdvModelInterference.hh
    AdvModelLayer.hh
    AdvModelParam.hh
    AdvModelParamSet.hh
    AdvModelParticle.hh
    AdvModelParticleType.hh
    AdvModelSmallAngle.hh
    AdvModelSpecular.hh
    AdvModelSpecularMul.hh
    AdvMovingAverage.hh
    AdvMultiDataLevmarConsts.hh
    AdvMultiDataLevmar.hh
    AdvMultiDataMethodFactory.hh
    AdvMultiDataMethod.hh
    AdvMultiDataOperationBase.hh
    AdvMultiDataPeakFit.hh
    AdvNewLevmar.hh
    AdvOperationBase.hh
    AdvOperationType.hh
    AdvParameterIOconst.hh
    AdvParamSet.hh
    AdvPeakData.hh
    AdvPeakFit.hh
    AdvPeak.hh
    AdvPeakSearch.hh
    AdvPeakType.hh
    AdvPolynomial1Conv.hh
    AdvPolynomial1.hh
    AdvPolynomial2Conv.hh
    AdvPolynomial2.hh
    AdvPolynomial3Conv.hh
    AdvPolynomial3.hh
    AdvPseudoVoigt1Conv.hh
    AdvPseudoVoigt1.hh
    AdvPseudoVoigt2Conv.hh
    AdvPseudoVoigt2.hh
    AdvReportConvergenceProcess.hh
    AdvSimulatedAnnealingArgs.hh
    AdvSimulatedAnnealingConsts.hh
    AdvSimulatedAnnealing.hh
    AdvSmoothing.hh
    AdvTrapezoid.hh
    AdvTriangle.hh
    AdvVectorArrayConv.hh
    AdvVectorComplexTool.hh
    AdvVectorGslVectorComplex.hh
    AdvVectorGSLVectorConv.hh
    ThreadBase.hh
    DESTINATION ${MANYO_ROOT_PATH}/include/manyo/${MODULENAME}
)

# Install Manyo folder for Python
install(TARGETS Manyo${MODULENAME}
    LIBRARY DESTINATION ${MANYO_PATH}/Manyo/${MODULENAME}
)

install(FILES
    ${PROJECT_BINARY_DIR}/${MODULENAME}.py
    __init__.py
    DESTINATION ${MANYO_PATH}/Manyo/${MODULENAME}
)

install(FILES
    sample/sample.py
    DESTINATION ${MANYO_ROOT_PATH}/share/Manyo/sample/${MODULENAME}
)
