# name of the camitk core target 
if (PACKAGING_NSIS)
   set(CAMITK_CORE_LIB_TARGET_NAME library_${CAMITK_CORE_LIB_NAME})
else()
    set(CAMITK_CORE_LIB_TARGET_NAME library-${CAMITK_CORE_LIB_NAME})
endif()

if(PYTHON_BINDING)    
    set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:/camitk/cmake/pybind11")
    message(STATUS "CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}")
    set(PYBIND11_FINDPYTHON ON)
    find_package(pybind11 CONFIG REQUIRED)
endif()

# Don't forget to include output directory, otherwise
# the UI file won't be wrapped!
include_directories(
  ${CMAKE_CURRENT_BINARY_DIR}
  ${CMAKE_CURRENT_SOURCE_DIR}
  ${CMAKE_CURRENT_SOURCE_DIR}/action
  ${CMAKE_CURRENT_SOURCE_DIR}/hotplug
  ${CMAKE_CURRENT_SOURCE_DIR}/application
  ${CMAKE_CURRENT_SOURCE_DIR}/component
  ${CMAKE_CURRENT_SOURCE_DIR}/component/mesh
  ${CMAKE_CURRENT_SOURCE_DIR}/component/image
  ${CMAKE_CURRENT_SOURCE_DIR}/operators
  ${CMAKE_CURRENT_SOURCE_DIR}/utils
  ${CMAKE_CURRENT_SOURCE_DIR}/viewer
  ${CAMITK_INCLUDE_DIRECTORIES} 
)

# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)

# find all sources files, set rules for qt files...
gather_headers_and_sources(${CAMITK_CORE_LIB_TARGET_NAME}) 

# Needed for a correct CamiTK core plugin management (decl export/import) on WIN32
add_definitions(-DCOMPILE_CAMITK_API)

# prepare the library specific info (SONAME...)
set(CAMITKCORE_LIBRARY_PROPERTIES ${CAMITKCORE_LIBRARY_PROPERTIES}
    VERSION   "${CAMITK_VERSION_MAJOR}.${CAMITK_VERSION_MINOR}.${CAMITK_VERSION_PATCH}"
    SOVERSION "${CAMITK_VERSION_MAJOR}"
)

# camitkcore only depends on qtpropertybrowser and extensiongenerator, which are public libraries
# add the library path as an additional to look for.
link_directories(${CAMITK_BUILD_BIN_DIR} ${CAMITK_PUBLIC_LIB_DIR})

# CAMITK_CORE_LIB_NAME needs to be SHARED and loaded only ONCE otherwise the extensions
# can have their own copy of CAMITK_CORE_LIB_NAME, which will generates loads of problems
# because of the Singleton design pattern and various factory bits in CAMITK_CORE_LIB_NAME.
add_library(${CAMITK_CORE_LIB_TARGET_NAME} SHARED ${${CAMITK_CORE_LIB_TARGET_NAME}_SOURCES})

# Update XML Project description adding this target as a subproject of the main CamiTK project with
# its dependencies (in the CMake target point of view)
if(PACKAGING_NSIS)
    camitk_register_subproject(CORELIB ${CAMITK_CORE_LIB_TARGET_NAME} DEPENDENCIES library_qtpropertybrowser library_camitkextensiongenerator)
else()
    camitk_register_subproject(CORELIB ${CAMITK_CORE_LIB_TARGET_NAME} DEPENDENCIES library-qtpropertybrowser library-camitkextensiongenerator)
endif()

# set the library specific info (SONAME...)
set_target_properties(${CAMITK_CORE_LIB_TARGET_NAME} PROPERTIES ${CAMITKCORE_LIBRARY_PROPERTIES} LINK_INTERFACE_LIBRARIES "")
if (WIN32 AND MSVC)
    # property required for camitk file association on windows platform compilation with Visual Studio
    set_target_properties(${CAMITK_CORE_LIB_TARGET_NAME} PROPERTIES COMPILE_FLAGS "/Zc:wchar_t-"
                                                         DEBUG_POSTFIX ${CAMITK_DEBUG_POSTFIX})
endif()

# for VTK9, see https://docs.vtk.org/en/latest/advanced/migration_guides/ModuleMigration.html
if("${VTK_VERSION}" VERSION_GREATER_EQUAL 9.0)
    vtk_module_autoinit(
        TARGETS ${CAMITK_CORE_LIB_TARGET_NAME}
        MODULES ${CAMITK_VTK_LIBRARIES})
endif()

if(PYTHON_BINDING)
    set(CAMITK_PYTHON_LIBRARIES Python::Python pybind11::pybind11 pybind11::embed)
else()
    unset(CAMITK_PYTHON_LIBRARIES)
endif()

target_link_libraries(${CAMITK_CORE_LIB_TARGET_NAME} PRIVATE ${CAMITK_LIBRARIES} ${CAMITK_PYTHON_LIBRARIES} ${CAMITK_QT_LIBRARIES})

# output directory
if (MSVC)
    set_target_properties(${CAMITK_CORE_LIB_TARGET_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CAMITK_BUILD_BIN_DIR}
                                                                    LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_BIN_DIR}
                                                                    LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_BIN_DIR}
    )
    set_target_properties(${CAMITK_CORE_LIB_TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CAMITK_BUILD_BIN_DIR}
                                                                    RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_BIN_DIR}
                                                                    RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_BIN_DIR}
    )
    set_target_properties(${CAMITK_CORE_LIB_TARGET_NAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CAMITK_BUILD_BIN_DIR}
                                                                    ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_BIN_DIR}
                                                                    ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_BIN_DIR}                                                        
    )
else()
    set_target_properties(${CAMITK_CORE_LIB_TARGET_NAME} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CAMITK_BUILD_PUBLIC_LIB_DIR}
                                                                    LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PUBLIC_LIB_DIR}
                                                                    LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PUBLIC_LIB_DIR}
    )
    set_target_properties(${CAMITK_CORE_LIB_TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CAMITK_BUILD_PUBLIC_LIB_DIR}
                                                                    RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PUBLIC_LIB_DIR}
                                                                    RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PUBLIC_LIB_DIR}
    )
    set_target_properties(${CAMITK_CORE_LIB_TARGET_NAME} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CAMITK_BUILD_PUBLIC_LIB_DIR}
                                                                    ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CAMITK_BUILD_PUBLIC_LIB_DIR}
                                                                    ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CAMITK_BUILD_PUBLIC_LIB_DIR}                                                        
    )
endif()

if(PACKAGING_NSIS)
    add_dependencies(${CAMITK_CORE_LIB_TARGET_NAME} library_qtpropertybrowser)
    add_dependencies(${CAMITK_CORE_LIB_TARGET_NAME} library_extensiongenerator)
    # add the dependency to the qtpropertybrowser automoc target
    set_property(TARGET ${CAMITK_CORE_LIB_TARGET_NAME} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS library_qtpropertybrowser)
    set_property(TARGET ${CAMITK_CORE_LIB_TARGET_NAME} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS library_extensiongenerator)
else()
    add_dependencies(${CAMITK_CORE_LIB_TARGET_NAME} library-qtpropertybrowser)
    add_dependencies(${CAMITK_CORE_LIB_TARGET_NAME} library-camitkextensiongenerator)
    # add the dependency to the qtpropertybrowser and extensiongenerator automoc target
    set_property(TARGET ${CAMITK_CORE_LIB_TARGET_NAME} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS library-qtpropertybrowser)
    set_property(TARGET ${CAMITK_CORE_LIB_TARGET_NAME} APPEND PROPERTY AUTOGEN_TARGET_DEPENDS library-camitkextensiongenerator)
endif()



# -- unit testing
camitk_add_subdirectory(testing)


# -- headers to install 
# TODO create a manually selected list (some headers are just needed internally)
# TODO create few specific include files like: CamiTKCore and CamiTKComponent that
# include most of the needed headers and that can be used simply e.g.
# #include <CamiTKComponent>
# i.e. without the trailing .h
file(GLOB_RECURSE ${CAMITK_CORE_LIB_TARGET_NAME}_INSTALL_H *.h *.txx CamiTKDisableWarnings CamiTKReEnableWarnings)

#--------------
# installation
#--------------
export_headers(${${CAMITK_CORE_LIB_TARGET_NAME}_INSTALL_H} 
               COMPONENT ${CAMITK_CORE_LIB_TARGET_NAME}
               GROUP libraries
)

# change the output library name (without the prefix 'library')
set_target_properties(${CAMITK_CORE_LIB_TARGET_NAME}
                       PROPERTIES OUTPUT_NAME ${CAMITK_CORE_LIB_NAME}
)

# lib installation
install(TARGETS ${CAMITK_CORE_LIB_TARGET_NAME}
        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/${CAMITK_SHORT_VERSION_STRING}
        COMPONENT ${CAMITK_CORE_LIB_TARGET_NAME}
)

cpack_add_component(${CAMITK_CORE_LIB_TARGET_NAME}
                    DISPLAY_NAME ${CAMITK_CORE_LIB_TARGET_NAME}
                    DESCRIPTION "The core of CamiTK allows other extensions to work together (required for any extension to work)."
                    REQUIRED
                    GROUP SDK
)

# Export build tree includes directly (needed for camitk so that it does not need to look into build/include
# and can be build in parallel) (note: uses modern cmake)
target_include_directories(${CAMITK_CORE_LIB_TARGET_NAME} PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/action>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/hotplug>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/application>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/component>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/component/mesh>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/component/image>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/operators>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/utils>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/viewer>
    $<INSTALL_INTERFACE:include>
    $<INSTALL_INTERFACE:include/action>
    $<INSTALL_INTERFACE:include/hotplug>
    $<INSTALL_INTERFACE:include/application>
    $<INSTALL_INTERFACE:include/component>
    $<INSTALL_INTERFACE:include/component/mesh>
    $<INSTALL_INTERFACE:include/component/image>
    $<INSTALL_INTERFACE:include/operators>
    $<INSTALL_INTERFACE:include/utils>
    $<INSTALL_INTERFACE:include/viewer>
)
