###############################################################################
# Builds BornAgain/GUI main executable
###############################################################################

if(WIN32)
    set(executable_name BornAgain)
else()
    set(executable_name bornagain)
endif()

set(source_files main.cpp AppOptions.cpp)

# -----------------------------------------------------------------------------
# Qt configuration
# -----------------------------------------------------------------------------
set(CMAKE_AUTOMOC ON)

# -----------------------------------------------------------------------------
# executable icons
# -----------------------------------------------------------------------------
if(WIN32)
    set(system_addons bornagain.rc)
    if(NOT win32_console)
        set(executable_options WIN32)
    endif()
endif()

if(APPLE)
    set(MACOSX_BUNDLE_ICON_FILE BornAgain.icns)
    set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/BornAgain.icns
        PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
    if(BA_APPLE_BUNDLE)
        set(executable_options MACOSX_BUNDLE)
    endif()
endif()

# -----------------------------------------------------------------------------
# executable
# -----------------------------------------------------------------------------
add_executable(${executable_name}
    ${executable_options}
    ${source_files}
    ${system_addons})

# -----------------------------------------------------------------------------
# dependencies
# -----------------------------------------------------------------------------
target_link_libraries(${executable_name} PRIVATE BornAgainGUI)
target_include_directories(${executable_name} PRIVATE ${CMAKE_SOURCE_DIR})

# -----------------------------------------------------------------------------
# extra target properties
# -----------------------------------------------------------------------------
if(BORNAGAIN_PYTHON)
    target_compile_definitions(${executable_name} PRIVATE -DBORNAGAIN_PYTHON)
endif()

if(WIN32)
    set_target_properties(${executable_name} PROPERTIES LINK_OPTIONS /ENTRY:mainCRTStartup)
    if(win32_console)
        set_target_properties(${executable_name} PROPERTIES COMPILE_DEFINITIONS _CONSOLE)
    endif()
endif()

# -----------------------------------------------------------------------------
# runtime library paths
# -----------------------------------------------------------------------------
#   See our deployment paper (Nejati et al 2024) for explanation.

if(LINUX)
    # NOTE: RPATH must be set also in `GUI/CMakeLists.txt`
    set(link_flags "-Wl,-rpath,\$ORIGIN/../lib")
    set_target_properties(${executable_name} PROPERTIES LINK_FLAGS ${link_flags})
elseif(APPLE)
    set(MACOSX_BUNDLE_IDENTIFIER org.bornagainproject.BornAgain)
    configure_file(${CONFIGURABLES_DIR}/MacOSXBundleInfo.plist.in ${BUILD_VAR_DIR}/Info.plist @ONLY)

    set_target_properties(${executable_name}
        PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${BUILD_VAR_DIR}/Info.plist)

    if(BA_APPLE_BUNDLE)
        target_link_options(${executable_name} PRIVATE
            "-Wl,-rpath,@loader_path/../lib,-rpath,@loader_path/../Frameworks")
    endif()
    target_link_options(${executable_name} PRIVATE
        "-Wl,-rpath,@loader_path/../lib/")
endif()

# -----------------------------------------------------------------------------
# installation section
# -----------------------------------------------------------------------------
if(BA_APPLE_BUNDLE)
    install(TARGETS ${executable_name} BUNDLE DESTINATION "." COMPONENT Applications)
else()
    install(TARGETS ${executable_name} RUNTIME DESTINATION ${destination_bin}
        COMPONENT Applications)
endif()

set(image_files
    ${CMAKE_CURRENT_SOURCE_DIR}/BornAgain.ico
    ${CMAKE_CURRENT_SOURCE_DIR}/BornAgain.icns
    ${CMAKE_SOURCE_DIR}/GUI/images/BornAgain_48x48.png
    ${CMAKE_SOURCE_DIR}/GUI/images/BornAgain_64x64.png)
install(FILES ${image_files} DESTINATION ${destination_images} COMPONENT Applications)

# -----------------------------------------------------------------------------
# system dependent installation
# -----------------------------------------------------------------------------
if(BA_APPLE_BUNDLE)
    install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/BornAgain.icns
        DESTINATION ${destination_root}/Resources/)
    install(FILES ${CMAKE_SOURCE_DIR}/cmake/configurables/qt.conf.mac
        DESTINATION ${destination_root}/Resources/
        RENAME qt.conf)

    # adjust MacOS bundle
    get_property(exe_dir TARGET ${executable_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY)
    set(MACPKG_MAIN_EXE "${exe_dir}/${executable_name}.app/Contents/MacOS/${executable_name}")

    # list of BornAgain core libraries
    set(MACPKG_CORE_LIBS "$CACHE{BornAgain_LIBRARIES}")

    # list of required Qt plugins (paths relative to Qt root dir)
    set(MACPKG_QT_PLUGINS_RELDIR "${QT6_INSTALL_PLUGINS}")
    set(MACPKG_QT_PLUGINS
        platforms/libqcocoa.dylib
        iconengines/libqsvgicon.dylib
        imageformats/libqjpeg.dylib
        imageformats/libqsvg.dylib
        styles/libqmacstyle.dylib
        )
    # Qt plugins directory in within the MacOS bundle
    set(MACPKG_QT_PLUGINS_DIR PlugIns)  # conform to settings in `qt.conf`
    # convert CMake list to space-separated lists
    set(MACPKG_EXTRA_LIBS "${BA_Dependencies}")

    configure_file("${CMAKE_SOURCE_DIR}/deploy/mac/mac_package.py.in"
        "${BUILD_VAR_DIR}/mac_package.py" @ONLY)

endif()

if(WIN32)
    message(STATUS "Configuring the GUI package")

    foreach(comp ${QtComponents})
        set(QtComp Qt6::${comp})
        get_target_property(dll ${QtComp} LOCATION_Release)
        get_property(dll TARGET ${QtComp} PROPERTY LOCATION_Release)
        install(FILES ${dll} DESTINATION ${destination_lib} COMPONENT WinLibraries)
        message(STATUS "Install Qt lib ${QtComp} (${dll})")
    endforeach()

    # extract Qt root-dir
    # 'C:/Qt/6.2.4/msvc2019_64/lib/cmake/Qt6' => 'C:/Qt/6.2.4/msvc2019_64'
    file(TO_CMAKE_PATH "${Qt_DIR}" qt_dir_str)

    install(FILES ${Qt_DIR}/bin/opengl32sw.dll
        DESTINATION ${destination_lib}
        COMPONENT WinLibraries)
    install(FILES ${Qt_PLUGINS_DIR}/platforms/qwindows.dll
        DESTINATION bin/platforms
        COMPONENT WinLibraries)
    install(FILES ${Qt_PLUGINS_DIR}/iconengines/qsvgicon.dll
        DESTINATION bin/iconengines
        COMPONENT WinLibraries)
    install(FILES ${Qt_PLUGINS_DIR}/imageformats/qjpeg.dll ${Qt_PLUGINS_DIR}/imageformats/qsvg.dll
        DESTINATION bin/imageformats
        COMPONENT WinLibraries)

    set(QT_VISTA_STYLE ${Qt_PLUGINS_DIR}/styles/qwindowsvistastyle.dll)
    if(EXISTS ${QT_VISTA_STYLE})
        install(FILES ${QT_VISTA_STYLE} DESTINATION bin/styles COMPONENT WinLibraries)
    else()
        message(AUTHOR_WARNING File ${QT_VISTA_STYLE} not found.)
    endif()
    unset(QT_VISTA_STYLE)
endif()

if(LINUX)
    set(LINUXPKG_MAIN_EXE "${CMAKE_BINARY_DIR}/bin/${executable_name}")
    set(LINUXPKG_FRAMEWORK_DEST "${destination_lib}")

    configure_file(${CMAKE_SOURCE_DIR}/deploy/linux/adjust_pkg_linux.sh.in
        ${BUILD_VAR_DIR}/adjust_pkg_linux.sh @ONLY)
endif()

# execute package-fixing script before CPack builds the final package file
configure_file(${CMAKE_SOURCE_DIR}/cmake/configurables/FixPack.cmake.in
    ${BUILD_VAR_DIR}/FixPack.cmake @ONLY)

install(SCRIPT ${BUILD_VAR_DIR}/FixPack.cmake)
