cmake_minimum_required(VERSION 3.7)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS False)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} /EHsc")
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

if(UNIX AND NOT APPLE)
  set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/")
endif()

if(NOT CMAKE_INSTALL_PREFIX OR CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  message(STATUS "Setting install dir inside build dir ${CMAKE_BINARY_DIR} ")
  set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "Install location" FORCE)
else()
  message(STATUS "Using preset install directory ${CMAKE_INSTALL_PREFIX}")
endif()

#------------------------------------------------------------------------------
# Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  message(STATUS "Setting build type to 'Release' as none was specified.")
  set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
  mark_as_advanced(CMAKE_BUILD_TYPE)
  # Set the possible values of build type for cmake-gui
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()

set(CMAKE_DEBUG_POSTFIX "d")

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

project(PulseExplorer VERSION 2.0.1 LANGUAGES C CXX)

find_package(Qt5 COMPONENTS Core Widgets
                            OpenGL Concurrent
                            Svg PrintSupport REQUIRED)
list(APPEND QT_LIBRARIES
    "Qt5::Core"
    "Qt5::Gui"
    "Qt5::Widgets"
    "Qt5::OpenGL"
    "Qt5::Concurrent"
    "Qt5::Svg"
    "Qt5::PrintSupport"
)

#-----------------------------------------------------------------------------
# Project install directories
#-----------------------------------------------------------------------------
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "Install location" FORCE)
endif()
set(CMAKE_PREFIX_PATH ${CMAKE_INSTALL_PREFIX})
# Let's go ahead and make these directories
file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)
file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/include)
file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/lib)


#-----------------------------------------------------------------------------
# Update CMake module path & cmake dir
#-----------------------------------------------------------------------------
set(CMAKE_MODULE_PATH
    ${CMAKE_CURRENT_SOURCE_DIR}/cmake
    ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules
    ${CMAKE_CURRENT_SOURCE_DIR}/cmake/utilities
    ${CMAKE_INSTALL_PREFIX}
    ${CMAKE_INSTALL_PREFIX}/lib/cmake # Many packages install their cmake to lib
    )
set(${PROJECT_NAME}_CMAKE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

#-----------------------------------------------------------------------------
# SUPERBUILD
#-----------------------------------------------------------------------------
option(${PROJECT_NAME}_SUPERBUILD "Initial pull and build of all dependent libraries/executables" ON)

if(${PROJECT_NAME}_SUPERBUILD)
  #-----------------------------------------------------------------------------
  # Define External dependencies
  #-----------------------------------------------------------------------------
  macro(define_dependency extProj)
    list(APPEND ${PROJECT_NAME}_DEPENDENCIES ${extProj})
    option(USE_SYSTEM_${extProj} "Exclude ${extProj} from superbuild and use an existing build." OFF)
    mark_as_advanced(USE_SYSTEM_${extProj})
  endmacro()

  define_dependency(Pulse)
  define_dependency(Qwt)

  if(${PROJECT_NAME}_DEPENDENCIES)
    #-----------------------------------------------------------------------------
    # Solve project dependencies
    #-----------------------------------------------------------------------------
    # Call CMakeLists.txt in cmake/external which will solve the dependencies
    # and add the external projects, including this one: this top-level
    # CMakeLists.txt will be called back with SUPERBUILD=OFF, to execute
    # the rest of the code below (INNERBUILD), which explains the `return`
    add_subdirectory(cmake/external)
    return()
  else()
    message(STATUS "No dependencies, skipping superbuild")
  endif()
endif()

#-----------------------------------------------------------------------------
#                               INNERBUILD
#-----------------------------------------------------------------------------

include(Find)# Our find macros
include(AddLibrary)# Extras to do when creating a library
include(AddExecutable)# Extras to do when creating an executable

#-----------------------------------------------------------------------------
# Find external dependencies and Source
#-----------------------------------------------------------------------------

find_package(Qwt REQUIRED)
find_package(Pulse REQUIRED)
add_subdirectory(src)

#-----------------------------------------------------------------------------
#                                  INSTALL
#-----------------------------------------------------------------------------

set(qt_plugin_dest_dir bin)
set(qt_rsrc_dest_dir bin)
if(APPLE)
  set(qt_plugin_dest_dir "${PROJECT_NAME}.app/Contents/Plugins")
  set(qt_rsrc_dest_dir "${PROJECT_NAME}.app/Contents/Resources")
  set(APP "${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME}.app")
endif()
install (TARGETS ${PROJECT_NAME}
         BUNDLE DESTINATION .
         RUNTIME DESTINATION bin)
install (DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/data" DESTINATION .)
# install pulse components
install(DIRECTORY "${Pulse_ROOT}/bin/config" DESTINATION .)
install(DIRECTORY "${Pulse_ROOT}/bin/ecg" DESTINATION .)
install(DIRECTORY "${Pulse_ROOT}/bin/environments" DESTINATION .)
install(DIRECTORY "${Pulse_ROOT}/bin/nutrition" DESTINATION .)
install(DIRECTORY "${Pulse_ROOT}/bin/patients" DESTINATION .)
install(DIRECTORY "${Pulse_ROOT}/bin/resource" DESTINATION .)
install(DIRECTORY "${Pulse_ROOT}/bin/states" DESTINATION .)
install(DIRECTORY "${Pulse_ROOT}/bin/substances" DESTINATION .)
#install(DIRECTORY "${Pulse_ROOT}/bin/verification/scenarios" DESTINATION .
#        PATTERN "*.csv" EXCLUDE)

# Install (ONLY) QWT shared library
if(Qwt_ROOT_DIR)
  if(WIN32)
    install(FILES ${Qwt_ROOT_DIR}/lib/qwt.dll
             CONFIGURATIONS Release
             RUNTIME DESTINATION bin)
    install(FILES ${Qwt_ROOT_DIR}/lib/qwtd.dll
             CONFIGURATIONS Debug
             RUNTIME DESTINATION bin)
  elseif(NOT APPLE)
    install(FILES ${Qwt_ROOT_DIR}/lib/libqwt.so
             CONFIGURATIONS Release
             RUNTIME DESTINATION lib)
    install(FILES ${Qwt_ROOT_DIR}/lib/libqwtd.so
             CONFIGURATIONS Debug
             RUNTIME DESTINATION lib)
  else()
    # APPLE
    install(FILES ${Qwt_ROOT_DIR}/lib/qwt.dylib
             CONFIGURATIONS Release
             RUNTIME DESTINATION bin)
    install(FILES ${Qwt_ROOT_DIR}/lib/qwtd.dylib
             CONFIGURATIONS Debug
             RUNTIME DESTINATION bin)
  endif()
endif()

install(CODE "
  file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qt_rsrc_dest_dir}/qt.conf\" \"[Paths]\nPlugins = Plugins\")
  ")
if(APPLE)
  install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/resource/pulse.icns" DESTINATION ${qt_rsrc_dest_dir})
endif()

#-----------------------------------------------------------------------------
#                                    CPACK
#-----------------------------------------------------------------------------

if (WIN32)
  set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
endif()
include(InstallRequiredSystemLibraries)

# Get Qt deployment executable
get_target_property( uic_location Qt5::uic IMPORTED_LOCATION )
get_filename_component( _qt_bin_dir ${uic_location} DIRECTORY )
set(qt_root_dir "${_qt_bin_dir}/..")
set(_qt_version "${Qt5_VERSION_MAJOR}.${Qt5_VERSION_MINOR}.${Qt5_VERSION_PATCH}")
message(STATUS "QT located : ${qt_root_dir}")

if(WIN32)
  find_program(DEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}")
  if( NOT EXISTS ${DEPLOYQT_EXECUTABLE} )
    message( FATAL_ERROR "Failed to locate qtdeploy executable" )
  else()
    install( CODE "execute_process(COMMAND \"${DEPLOYQT_EXECUTABLE}\" \"\${CMAKE_INSTALL_PREFIX}/bin/qwt.dll\")" )
    install( CODE "execute_process(COMMAND \"${DEPLOYQT_EXECUTABLE}\" \"\${CMAKE_INSTALL_PREFIX}/bin/PulseExplorer.exe\")" )
  endif()
  install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/CMake/PulseExplorer.bat" DESTINATION "./")
elseif(APPLE)
  install(DIRECTORY "${qt_root_dir}/plugins/iconengines" DESTINATION ${qt_plugin_dest_dir})
  install(DIRECTORY "${qt_root_dir}/plugins/imageformats" DESTINATION ${qt_plugin_dest_dir})
  install(DIRECTORY "${qt_root_dir}/plugins/platforms" DESTINATION ${qt_plugin_dest_dir})
  install(DIRECTORY "${qt_root_dir}/translations" DESTINATION ${qt_plugin_dest_dir})
  install(CODE "
    file(GLOB_RECURSE QTPLUGINS \"${CMAKE_INSTALL_PREFIX}/${qt_plugin_dest_dir}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
    # Fix permissions on copied libraries so they can be fixed up.
    set(BU_CHMOD_BUNDLE_ITEMS ON) # fixes permissions on libraries
    include(BundleUtilities)
    fixup_bundle(\"${APP}\" \"\${QTPLUGINS}\" \"${qt_root_dir}/lib\")
  ")
else()
  foreach(target ${QT_LIBRARIES})
    get_target_property(type ${target} TYPE)
    if(NOT type STREQUAL "SHARED_LIBRARY")
      continue()
    endif()
    get_property(location TARGET ${target} PROPERTY LOCATION_RELEASE)
    # Install .so and versioned .so.x.y
    get_filename_component(QT_LIB_DIR_tmp ${location} PATH)
    get_filename_component(QT_LIB_NAME_tmp ${location} NAME)
    string(REPLACE ".${_qt_version}" "" QT_LIB_NAME_tmp ${QT_LIB_NAME_tmp})
    install(DIRECTORY ${QT_LIB_DIR_tmp}/
        DESTINATION "bin" COMPONENT Runtime
        FILES_MATCHING PATTERN "${QT_LIB_NAME_tmp}*"
        PATTERN "${QT_LIB_NAME_tmp}*.debug" EXCLUDE)
  endforeach()
  # ICU libraries
  file(GLOB ICU_LIBS ${qt_root_dir}/lib/libicu*)
  install(FILES ${ICU_LIBS}
    DESTINATION "bin" COMPONENT Runtime)
  # Shell script to start the application
  install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/cmake/PulseExplorer.sh" DESTINATION "./")
endif()

# Define package dependencies
set(EXPLORER_DEPS "")

if(EXISTS /etc/redhat-release)
  file(READ /etc/redhat-release RHEL_VERSION)
  string(REGEX REPLACE ".*release ([^\\. ]*).*" "\\1" RHEL_VERSION "${RHEL_VERSION}")
  set(CPACK_SYSTEM_NAME "el${RHEL_VERSION}.${CMAKE_SYSTEM_PROCESSOR}")
  set(CPACK_RPM_PACKAGE_AUTOREQPROV " no")
  set(CPACK_RPM_PACKAGE_REQUIRES "${EXPLORER_DEPS}")
else()
  set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
endif()

if (APPLE)
  set(CPACK_GENERATOR ZIP)
  #set(CPACK_GENERATOR DragNDrop)
else()
  set(CPACK_GENERATOR ZIP)
endif()
set(CPACK_PACKAGE_NAME              "PulseExplorer")
set(CPACK_PACKAGE_VENDOR            "Kitware, Inc.")
set(CPACK_PACKAGE_CONTACT           "kitware@kitware.com")
set(CPACK_MONOLITHIC_INSTALL        true)
set(CPACK_PACKAGE_VERSION_MAJOR     "${PROJECT_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR     "${PROJECT_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH     "${PROJECT_VERSION_PATCH}")
set(CPACK_PACKAGE_VERSION           "${PROJECT_VERSION}")
#set(CPACK_RESOURCE_FILE_LICENSE     "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_FILE_NAME         "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}")
set(CPACK_PACKAGE_ICON              "${CMAKE_CURRENT_SOURCE_DIR}/resource/pulse_logo.png")
#set(CPACK_DMG_DS_STORE              "${CMAKE_CURRENT_SOURCE_DIR}/packaging/DS_Store")

if(APPLE)
  set(CPACK_BUNDLE_STARTUP_COMMAND  PulseExplorer)
  set(CPACK_PACKAGE_ICON            "${CMAKE_CURRENT_SOURCE_DIR}/resource/pulse_logo.png")
  set(CPACK_BUNDLE_ICON             pulse.icns)
  set(MACOSX_BUNDLE_ICON_FILE       pulse.icns)
  set(MACOSX_BUNDLE_BUNDLE_VERSION  "${PROJECT_VERSION}")
  set(MACOSX_BUNDLE_EXECUTABLE_NAME PulseExplorer)
  #set_target_properties(${project_name}
  #  PROPERTIES
  #    MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/resource/explorer.plist.in)
endif()

# NSIS Package options
set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\PulseExplorer.exe")
set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/resource\\\\pulse.ico")
set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/resource\\\\pulse.ico")
set(CPACK_NSIS_CONTACT "${CPACK_PACKAGE_CONTACT}")
set(CPACK_NSIS_HELP_LINK "http://www.kitware.com")
set(CPACK_NSIS_URL_INFO_ABOUT "http://pulse.kitware.com")
set(CPACK_NSIS_MENU_LINKS "http://pulse.kitware.com" "Pulse Documentation")
set(CPACK_PACKAGE_EXECUTABLES "PulseExplorer" "Pulse Physiology Explorer" ${CPACK_PACKAGE_EXECUTABLES})

include (CPack)
