cmake_minimum_required(VERSION 3.7)

set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "Install location")
if(NOT CMAKE_BUILD_TYPE)
  message(STATUS "Setting build type to 'Release' as none was specified.")
  set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
  
endif()

# Superbuild stuff
option(DO_SUPERBUILD "Download and build any project dependencies" ON)
option(USE_PARAVIEW  "Include the ParaView Model Window" OFF)

if (DO_SUPERBUILD)
  include("CMake/Superbuild.cmake")
  if(DOING_SUPERBUILD)
    return()
  else()
    message(STATUS "All dependencies found, skipping superbuild")
  endif()
endif()

# Policy to address @foo@ variable expansion
set(EXPLORER_VERSION_MAJOR 1)
set(EXPLORER_VERSION_MINOR 4)
set(EXPLORER_VERSION_PATCH 0)
set(EXPLORER_VERSION "${EXPLORER_VERSION_MAJOR}.${EXPLORER_VERSION_MINOR}.${EXPLORER_VERSION_PATCH}")


set(CMAKE_CXX_STANDARD 11)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

# Set the possible values of build type for cmake-gui

if(MSVC OR XCode)
  set(CMAKE_CONFIGURATION_TYPES Release Debug RelWithDebInfo CACHE STRING INTERNAL FORCE )
  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo")
endif()

set(project_name PulseExplorer)
project(${project_name})

set(${project_name}_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/CMake")

find_package(Qt5 COMPONENTS Core Widgets Charts REQUIRED)
list(APPEND QT_LIBRARIES
    "Qt5::Core"
    "Qt5::Gui"
    "Qt5::Widgets"
    "Qt5::Charts"
)

if(ENABLE_PARAVIEW)
  find_package(ParaView REQUIRED)
  if (NOT PARAVIEW_BUILD_QT_GUI)
   status(FATAL_ERROR "${project_name} requires ParaView to be built with Qt")
  endif()
endif()

if(NOT Pulse_FOUND)
  find_package(Pulse REQUIRED)
endif()

# Set a consistent MACOSX_RPATH default across all CMake versions.
# When CMake 2.8.12 is required, change this default to 1.
# When CMake 3.0.0 is required, remove this block (see CMP0042).
if(NOT DEFINED CMAKE_MACOSX_RPATH)
  set(CMAKE_MACOSX_RPATH 0)
endif()

set(moc_sources
  controls/MainExplorerWindow.h
  controls/ExplorerIntroWidget.h
  controls/QPulse.h
  controls/CollapsableWidget.h
  controls/ScalarWidget.h
  controls/VitalsMonitorWidget.h
  controls/DataRequestWidget.h
  controls/DataRequestViewWidget.h
  controls/DynamicControlsWidget.h
  controls/PatientEditorWidget.h
  controls/ConditionsEditorWidget.h
  controls/ActionsEditorWidget.h
  controls/ScenarioEditorWidget.h
  controls/PlotSetWidget.h
  controls/LabeledComboBox.h
  
  controls/EnviornmentWidget.h
  
  conditions/ConditionWidget.h
  conditions/ChronicAnemiaWidget.h
  conditions/ChronicObstructivePulmonaryDiseaseWidget.h
  conditions/ChronicPericardialEffusionWidget.h
  conditions/ChronicRenalStenosisWidget.h
  conditions/ChronicVentricularSystolicDysfunctionWidget.h
  conditions/ImpairedAlveolarExchangeWidget.h
  conditions/LobarPneumoniaWidget.h
  conditions/PulmonaryFibrosisWidget.h
  
  actions/ActionWidget.h
  actions/AcuteStressWidget.h
  actions/AirwayObstructionWidget.h
  actions/DyspneaWidget.h
  actions/AsthmaAttackWidget.h
  actions/BronchoconstrictionWidget.h
  actions/CardiacArrestWidget.h
  actions/ChestCompressionForceScaleWidget.h
  actions/ChestOcclusiveDressingWidget.h
  actions/ExerciseWidget.h
  actions/HemorrhageWidget.h
  actions/IntubationWidget.h
  actions/NeedleDecompressionWidget.h
  actions/PericardialEffusionWidget.h
  actions/SubstanceBolusWidget.h
  actions/SubstanceCompoundInfusionWidget.h
  actions/SubstanceInfusionWidget.h
  actions/SupplementalOxygenWidget.h
  actions/TensionPneumothoraxWidget.h
  
  showcases/AnaphylaxisShowcaseWidget.h
  showcases/MultiTraumaShowcaseWidget.h
)

#------------------------------------------------------------------------------
# Add extra library containing custom code for the client.
set(UI_FILES
    ui/MainExplorerWindow.ui
    ui/ExplorerIntro.ui
    ui/PatientEditor.ui
    ui/VitalsMonitor.ui
    ui/DataRequest.ui
    ui/DataRequestView.ui
    ui/DynamicControls.ui
    
    ui/Enviornment.ui
    
    ui/ConditionsEditor.ui
    ui/Condition.ui
    
    ui/ActionsEditor.ui
    ui/Action.ui
    
    ui/ScenarioEditor.ui
    
    ui/AnaphylaxisShowcase.ui
    ui/MultiTraumaShowcase.ui

    ui/PlotSet.ui
    )
source_group("UI" FILES ${UI_FILES})
QT5_WRAP_CPP(MOC_BUILT_SOURCES ${moc_sources})
QT5_WRAP_UI(UI_BUILT_SOURCES ${UI_FILES})

source_group("Generated" FILES
  ${MOC_BUILT_SOURCES}
  ${UI_BUILT_SOURCES}
)
list(APPEND SOURCE ${UI_BUILT_SOURCES})
list(APPEND SOURCE ${MOC_BUILT_SOURCES}) 

set(CONTROLS_FILES
  controls/ExplorerIntroWidget.cxx
  controls/ExplorerIntroWidget.h
  controls/QPulse.cxx
  controls/QPulse.h 
  controls/QPulsePlot.cxx
  controls/QPulsePlot.h
  controls/PlotSetWidget.cxx
  controls/PlotSetWidget.h
  controls/ScalarWidget.cxx
  controls/ScalarWidget.h
  controls/ScalarQuantityWidget.inl
  controls/ScalarQuantityWidget.h
  controls/CollapsableWidget.h
  controls/CollapsableWidget.cxx
  controls/DynamicControlsWidget.cxx
  controls/DynamicControlsWidget.h
  controls/PatientEditorWidget.h
  controls/PatientEditorWidget.cxx
  controls/ConditionsEditorWidget.h
  controls/ConditionsEditorWidget.cxx
  controls/ActionsEditorWidget.h
  controls/ActionsEditorWidget.cxx
  controls/ScenarioEditorWidget.h
  controls/ScenarioEditorWidget.cxx
  controls/DataRequestWidget.cxx
  controls/DataRequestWidget.h
  controls/DataRequestViewWidget.cxx
  controls/DataRequestViewWidget.h
  controls/VitalsMonitorWidget.cxx
  controls/VitalsMonitorWidget.h
  controls/LabeledComboBox.cxx
  controls/LabeledComboBox.h
  
  controls/EnviornmentWidget.cxx
  controls/EnviornmentWidget.h
)
source_group("Controls" FILES ${CONTROLS_FILES})
list(APPEND SOURCE ${CONTROLS_FILES})

set(WINDOW_FILES
  controls/MainExplorerWindow.cxx
  controls/MainExplorerWindow.h
)
if(NOT ENABLE_PARAVIEW)
  list(APPEND WINDOW_FILES controls/Main.cxx)
endif()

source_group("" FILES ${WINDOW_FILES})
list(APPEND SOURCE ${WINDOW_FILES})


set(SHOWCASE_FILES
  showcases/AnaphylaxisShowcaseWidget.cxx
  showcases/AnaphylaxisShowcaseWidget.h
  showcases/MultiTraumaShowcaseWidget.cxx
  showcases/MultiTraumaShowcaseWidget.h
)
source_group("Showcase" FILES ${SHOWCASE_FILES})
list(APPEND SOURCE ${SHOWCASE_FILES})

set(CONDITIONS_FILES
  conditions/ConditionWidget.h
  conditions/ConditionWidget.cxx
  conditions/ChronicAnemiaWidget.cxx
  conditions/ChronicAnemiaWidget.h
  conditions/ChronicObstructivePulmonaryDiseaseWidget.cxx
  conditions/ChronicObstructivePulmonaryDiseaseWidget.h
  conditions/ChronicPericardialEffusionWidget.cxx
  conditions/ChronicPericardialEffusionWidget.h
  conditions/ChronicRenalStenosisWidget.cxx
  conditions/ChronicRenalStenosisWidget.h
  conditions/ChronicVentricularSystolicDysfunctionWidget.cxx
  conditions/ChronicVentricularSystolicDysfunctionWidget.h
  conditions/ImpairedAlveolarExchangeWidget.cxx
  conditions/ImpairedAlveolarExchangeWidget.h
  conditions/LobarPneumoniaWidget.cxx
  conditions/LobarPneumoniaWidget.h
  conditions/PulmonaryFibrosisWidget.cxx
  conditions/PulmonaryFibrosisWidget.h
)
source_group("Conditions" FILES ${CONDITIONS_FILES})
list(APPEND SOURCE ${CONDITIONS_FILES})

set(ACTIONS_FILES
  actions/ActionWidget.h
  actions/ActionWidget.cxx
  actions/AcuteStressWidget.h
  actions/AcuteStressWidget.cxx
  actions/AirwayObstructionWidget.h
  actions/AirwayObstructionWidget.cxx
  actions/DyspneaWidget.h
  actions/DyspneaWidget.cxx
  actions/AsthmaAttackWidget.h
  actions/AsthmaAttackWidget.cxx
  actions/BronchoconstrictionWidget.h
  actions/BronchoconstrictionWidget.cxx
  actions/CardiacArrestWidget.h
  actions/CardiacArrestWidget.cxx
  actions/ChestCompressionForceScaleWidget.h
  actions/ChestCompressionForceScaleWidget.cxx
  actions/ChestOcclusiveDressingWidget.h
  actions/ChestOcclusiveDressingWidget.cxx
  actions/ExerciseWidget.h
  actions/ExerciseWidget.cxx
  actions/HemorrhageWidget.h
  actions/HemorrhageWidget.cxx
  actions/IntubationWidget.h
  actions/IntubationWidget.cxx
  actions/NeedleDecompressionWidget.h
  actions/NeedleDecompressionWidget.cxx
  actions/PericardialEffusionWidget.h
  actions/PericardialEffusionWidget.cxx
  actions/SubstanceBolusWidget.h
  actions/SubstanceBolusWidget.cxx
  actions/SubstanceCompoundInfusionWidget.h
  actions/SubstanceCompoundInfusionWidget.cxx
  actions/SubstanceInfusionWidget.h
  actions/SubstanceInfusionWidget.cxx
  actions/SupplementalOxygenWidget.h
  actions/SupplementalOxygenWidget.cxx
  actions/TensionPneumothoraxWidget.h
  actions/TensionPneumothoraxWidget.cxx
)
source_group("Actions" FILES ${ACTIONS_FILES})
list(APPEND SOURCE ${ACTIONS_FILES})

if(ENABLE_PARAVIEW)
  list(APPEND ${project_name}_SOURCE_FILES 
   controls/GeometryView.cxx
   controls/GeometryView.h
   controls/vtkWaveformWidget.cxx
   controls/vtkWaveformWidget.h
  )
  
  add_definitions( -DPARAVIEW )
  set(CMAKE_MODULE_PATH ${ParaView_CMAKE_DIR})
  include (${PARAVIEW_USE_FILE})
  #include(ParaViewQt)
  # include rules for creating custom applications.
  include(ParaViewBranding)
  build_paraview_client(${project_name}
    TITLE "Pulse Physiology Explorer"
    ORGANIZATION  "Kitware, Inc."
    VERSION_MAJOR 0
    VERSION_MINOR 1
    VERSION_PATCH 0
  # SPLASH_IMAGE "${CMAKE_CURRENT_SOURCE_DIR}/RSplash.png"
    PVMAIN_WINDOW MainExplorerWindow
    PVMAIN_WINDOW_INCLUDE MainExplorerWindow.h
    EXTRA_DEPENDENCIES ${Qt5Charts_LIBRARIES} vtkPVServerManagerRendering
                       ${PULSE_LIBRARIES}
    SOURCES ${SOURCE}
    
  )
  
  #target_include_directories(${project_name} PRIVATE ${PARAVIEW_INCLUDE_DIRS})
  #      ${PARAVIEW_LIBRARIES} 
  #      pqApplicationComponents
  #      vtkPVServerManagerApplication
  #      vtksys vtkPVServerManagerRendering)
  
else()
  message(STATUS "Building without ParaView")
  add_executable(${project_name} MACOSX_BUNDLE ${SOURCE})
  target_include_directories(${project_name} PRIVATE ${Qt_INCLUDE_DIRS})
  target_include_directories(${project_name} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
  target_include_directories(${project_name} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
  target_link_libraries(${project_name} Pulse ${Qt5Charts_LIBRARIES})
  if(NOT MSVC)
    target_link_libraries(${project_name} general  -lpthread -lm)
  endif()
endif()

if(MSVC) # Configure running executable out of MSVC
  set_property(TARGET ${project_name} PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}/bin")
endif()


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_INSTALL}/bin/config" DESTINATION .)
install(DIRECTORY "${Pulse_INSTALL}/bin/ecg" DESTINATION .)
install(DIRECTORY "${Pulse_INSTALL}/bin/environments" DESTINATION .)
install(DIRECTORY "${Pulse_INSTALL}/bin/nutrition" DESTINATION .)
install(DIRECTORY "${Pulse_INSTALL}/bin/patients" DESTINATION .)
install(DIRECTORY "${Pulse_INSTALL}/bin/resource" DESTINATION .)
install(DIRECTORY "${Pulse_INSTALL}/bin/states" DESTINATION .)
install(DIRECTORY "${Pulse_INSTALL}/bin/substances" DESTINATION .)
#install(DIRECTORY "${Pulse_INSTALL}/bin/verification/scenarios" DESTINATION .
#        PATTERN "*.csv" EXCLUDE)
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 Packaging
#

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/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     "${EXPLORER_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR     "${EXPLORER_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH     "${EXPLORER_VERSION_PATCH}")
set(CPACK_PACKAGE_VERSION           "${EXPLORER_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  "${EXPLORER_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)
