cmake_minimum_required(VERSION 2.8)

project(Orthanc)

# Version of the build, should always be "mainline" except in release branches
set(ORTHANC_VERSION "1.2.0")

# Version of the database schema. History:
#   * Orthanc 0.1.0 -> Orthanc 0.3.0 = no versioning
#   * Orthanc 0.3.1                  = version 2
#   * Orthanc 0.4.0 -> Orthanc 0.7.2 = version 3
#   * Orthanc 0.7.3 -> Orthanc 0.8.4 = version 4
#   * Orthanc 0.8.5 -> Orthanc 0.9.4 = version 5
#   * Orthanc 0.9.5 -> mainline      = version 6
set(ORTHANC_DATABASE_VERSION 6)


#####################################################################
## CMake parameters tunable at the command line
#####################################################################

# Parameters of the build
SET(STATIC_BUILD OFF CACHE BOOL "Static build of the third-party libraries (necessary for Windows)")
SET(STANDALONE_BUILD ON CACHE BOOL "Standalone build (all the resources are embedded, necessary for releases)")
SET(ENABLE_SSL ON CACHE BOOL "Include support for SSL")
SET(DCMTK_DICTIONARY_DIR "" CACHE PATH "Directory containing the DCMTK dictionaries \"dicom.dic\" and \"private.dic\" (only when using system version of DCMTK)") 
SET(ALLOW_DOWNLOADS OFF CACHE BOOL "Allow CMake to download packages")
SET(UNIT_TESTS_WITH_HTTP_CONNEXIONS ON CACHE BOOL "Allow unit tests to make HTTP requests")
SET(ENABLE_JPEG ON CACHE BOOL "Enable JPEG decompression")
SET(ENABLE_JPEG_LOSSLESS ON CACHE BOOL "Enable JPEG-LS (Lossless) decompression")
SET(ENABLE_PLUGINS ON CACHE BOOL "Enable plugins")
SET(BUILD_SERVE_FOLDERS ON CACHE BOOL "Whether to build the ServeFolders plugin")
SET(BUILD_MODALITY_WORKLISTS ON CACHE BOOL "Whether to build the sample plugin to serve modality worklists")
SET(BUILD_RECOVER_COMPRESSED_FILE ON CACHE BOOL "Whether to build the companion tool to recover files compressed using Orthanc")
SET(ENABLE_PKCS11 OFF CACHE BOOL "Enable PKCS#11 for HTTPS client authentication using hardware security modules and smart cards")
SET(ENABLE_PROFILING OFF CACHE BOOL "Whether to enable the generation of profiling information with gprof")

# Advanced parameters to fine-tune linking against system libraries
SET(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp")
SET(USE_SYSTEM_GOOGLE_TEST ON CACHE BOOL "Use the system version of Google Test")
SET(USE_SYSTEM_SQLITE ON CACHE BOOL "Use the system version of SQLite")
SET(USE_SYSTEM_MONGOOSE ON CACHE BOOL "Use the system version of Mongoose")
SET(USE_SYSTEM_LUA ON CACHE BOOL "Use the system version of Lua")
SET(USE_SYSTEM_DCMTK ON CACHE BOOL "Use the system version of DCMTK")
SET(USE_SYSTEM_BOOST ON CACHE BOOL "Use the system version of Boost")
SET(USE_SYSTEM_LIBPNG ON CACHE BOOL "Use the system version of libpng")
SET(USE_SYSTEM_LIBJPEG ON CACHE BOOL "Use the system version of libjpeg")
SET(USE_SYSTEM_CURL ON CACHE BOOL "Use the system version of LibCurl")
SET(USE_SYSTEM_OPENSSL ON CACHE BOOL "Use the system version of OpenSSL")
SET(USE_SYSTEM_ZLIB ON CACHE BOOL "Use the system version of ZLib")
SET(USE_SYSTEM_PUGIXML ON CACHE BOOL "Use the system version of Pugixml")
SET(USE_SYSTEM_LIBP11 OFF CACHE BOOL "Use the system version of libp11 (PKCS#11 wrapper library)")

# Advanced parameters
SET(USE_PUGIXML ON CACHE BOOL "Use the Pugixml parser (turn off only for debug)")
SET(USE_DCMTK_361 OFF CACHE BOOL "Use forthcoming DCMTK version 3.6.1 in static builds (instead of 3.6.0)")
SET(USE_DCMTK_361_PRIVATE_DIC ON CACHE BOOL "Use the dictionary of private tags from DCMTK 3.6.1 in static builds (which is more up-to-date)")

# Distribution-specific settings
SET(USE_GTEST_DEBIAN_SOURCE_PACKAGE OFF CACHE BOOL "Use the sources of Google Test shipped with libgtest-dev (Debian only)")
SET(SYSTEM_MONGOOSE_USE_CALLBACKS ON CACHE BOOL "The system version of Mongoose uses callbacks (version >= 3.7)")
SET(USE_BOOST_ICONV ON CACHE BOOL "Use iconv instead of wconv (Windows only)")

mark_as_advanced(USE_GTEST_DEBIAN_SOURCE_PACKAGE)
mark_as_advanced(SYSTEM_MONGOOSE_USE_CALLBACKS)
mark_as_advanced(USE_BOOST_ICONV)
mark_as_advanced(USE_PUGIXML)

# Path to the root folder of the Orthanc distribution
set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR})
set(ENABLE_DCMTK_NETWORK ON)

# Some basic inclusions
include(CheckIncludeFiles)
include(CheckIncludeFileCXX)
include(CheckLibraryExists)
include(FindPythonInterp)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/AutoGeneratedCode.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/DownloadPackage.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/Compiler.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/VisualStudioPrecompiledHeaders.cmake)



#####################################################################
## List of source files
#####################################################################

set(ORTHANC_CORE_SOURCES
  Core/Cache/MemoryCache.cpp
  Core/Cache/SharedArchive.cpp
  Core/ChunkedBuffer.cpp
  Core/Compression/DeflateBaseCompressor.cpp
  Core/Compression/GzipCompressor.cpp
  Core/Compression/HierarchicalZipWriter.cpp
  Core/Compression/ZipWriter.cpp
  Core/Compression/ZlibCompressor.cpp
  Core/DicomFormat/DicomArray.cpp
  Core/DicomFormat/DicomMap.cpp
  Core/DicomFormat/DicomTag.cpp
  Core/DicomFormat/DicomImageInformation.cpp
  Core/DicomFormat/DicomIntegerPixelAccessor.cpp
  Core/DicomFormat/DicomInstanceHasher.cpp
  Core/DicomFormat/DicomValue.cpp
  Core/Enumerations.cpp
  Core/FileStorage/FilesystemStorage.cpp
  Core/FileStorage/StorageAccessor.cpp
  Core/HttpClient.cpp
  Core/HttpServer/BufferHttpSender.cpp
  Core/HttpServer/EmbeddedResourceHttpHandler.cpp
  Core/HttpServer/FilesystemHttpHandler.cpp
  Core/HttpServer/HttpToolbox.cpp
  Core/HttpServer/HttpOutput.cpp
  Core/HttpServer/StringHttpOutput.cpp
  Core/HttpServer/MongooseServer.cpp
  Core/HttpServer/HttpFileSender.cpp
  Core/HttpServer/FilesystemHttpSender.cpp
  Core/HttpServer/HttpContentNegociation.cpp
  Core/HttpServer/HttpStreamTranscoder.cpp
  Core/Logging.cpp
  Core/RestApi/RestApiCall.cpp
  Core/RestApi/RestApiGetCall.cpp
  Core/RestApi/RestApiHierarchy.cpp
  Core/RestApi/RestApiPath.cpp
  Core/RestApi/RestApiOutput.cpp
  Core/RestApi/RestApi.cpp
  Core/MultiThreading/BagOfTasksProcessor.cpp
  Core/MultiThreading/Mutex.cpp
  Core/MultiThreading/ReaderWriterLock.cpp
  Core/MultiThreading/RunnableWorkersPool.cpp
  Core/MultiThreading/Semaphore.cpp
  Core/MultiThreading/SharedMessageQueue.cpp
  Core/Images/Font.cpp
  Core/Images/FontRegistry.cpp
  Core/Images/IImageWriter.cpp
  Core/Images/Image.cpp
  Core/Images/ImageAccessor.cpp
  Core/Images/ImageBuffer.cpp
  Core/Images/ImageProcessing.cpp
  Core/Images/JpegErrorManager.cpp
  Core/Images/JpegReader.cpp
  Core/Images/JpegWriter.cpp
  Core/Images/PngReader.cpp
  Core/Images/PngWriter.cpp
  Core/SQLite/Connection.cpp
  Core/SQLite/FunctionContext.cpp
  Core/SQLite/Statement.cpp
  Core/SQLite/StatementId.cpp
  Core/SQLite/StatementReference.cpp
  Core/SQLite/Transaction.cpp
  Core/SystemToolbox.cpp
  Core/TemporaryFile.cpp
  Core/Toolbox.cpp
  Core/WebServiceParameters.cpp
  Core/Lua/LuaContext.cpp
  Core/Lua/LuaFunctionCall.cpp
  )


set(ORTHANC_SERVER_SOURCES
  OrthancServer/DatabaseWrapper.cpp
  OrthancServer/DatabaseWrapperBase.cpp
  OrthancServer/DicomDirWriter.cpp
  OrthancServer/DicomModification.cpp
  OrthancServer/DicomProtocol/DicomFindAnswers.cpp
  OrthancServer/DicomProtocol/DicomServer.cpp
  OrthancServer/DicomProtocol/DicomUserConnection.cpp
  OrthancServer/DicomProtocol/RemoteModalityParameters.cpp
  OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp
  OrthancServer/ExportedResource.cpp
  OrthancServer/FromDcmtkBridge.cpp
  OrthancServer/Internals/CommandDispatcher.cpp
  OrthancServer/Internals/DicomFrameIndex.cpp
  OrthancServer/Internals/DicomImageDecoder.cpp
  OrthancServer/Internals/FindScp.cpp
  OrthancServer/Internals/MoveScp.cpp
  OrthancServer/Internals/StoreScp.cpp
  OrthancServer/LuaScripting.cpp
  OrthancServer/OrthancFindRequestHandler.cpp
  OrthancServer/OrthancHttpHandler.cpp
  OrthancServer/OrthancInitialization.cpp
  OrthancServer/OrthancMoveRequestHandler.cpp
  OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp
  OrthancServer/OrthancRestApi/OrthancRestApi.cpp
  OrthancServer/OrthancRestApi/OrthancRestArchive.cpp
  OrthancServer/OrthancRestApi/OrthancRestChanges.cpp
  OrthancServer/OrthancRestApi/OrthancRestModalities.cpp
  OrthancServer/OrthancRestApi/OrthancRestResources.cpp
  OrthancServer/OrthancRestApi/OrthancRestSystem.cpp
  OrthancServer/ParsedDicomFile.cpp
  OrthancServer/QueryRetrieveHandler.cpp
  OrthancServer/Search/HierarchicalMatcher.cpp
  OrthancServer/Search/IFindConstraint.cpp
  OrthancServer/Search/LookupIdentifierQuery.cpp
  OrthancServer/Search/LookupResource.cpp
  OrthancServer/Search/SetOfResources.cpp
  OrthancServer/Search/ListConstraint.cpp
  OrthancServer/Search/RangeConstraint.cpp
  OrthancServer/Search/ValueConstraint.cpp
  OrthancServer/Search/WildcardConstraint.cpp
  OrthancServer/ServerContext.cpp
  OrthancServer/ServerEnumerations.cpp
  OrthancServer/ServerIndex.cpp
  OrthancServer/ServerToolbox.cpp
  OrthancServer/SliceOrdering.cpp
  OrthancServer/ToDcmtkBridge.cpp

  # From "lua-scripting" branch
  OrthancServer/DicomInstanceToStore.cpp
  OrthancServer/Scheduler/DeleteInstanceCommand.cpp
  OrthancServer/Scheduler/ModifyInstanceCommand.cpp
  OrthancServer/Scheduler/ServerCommandInstance.cpp
  OrthancServer/Scheduler/ServerJob.cpp
  OrthancServer/Scheduler/ServerScheduler.cpp
  OrthancServer/Scheduler/StorePeerCommand.cpp
  OrthancServer/Scheduler/StoreScuCommand.cpp
  OrthancServer/Scheduler/CallSystemCommand.cpp
  )


set(ORTHANC_UNIT_TESTS_SOURCES
  UnitTestsSources/DicomMapTests.cpp
  UnitTestsSources/FileStorageTests.cpp
  UnitTestsSources/FromDcmtkTests.cpp
  UnitTestsSources/MemoryCacheTests.cpp
  UnitTestsSources/ImageTests.cpp
  UnitTestsSources/RestApiTests.cpp
  UnitTestsSources/SQLiteTests.cpp
  UnitTestsSources/SQLiteChromiumTests.cpp
  UnitTestsSources/ServerIndexTests.cpp
  UnitTestsSources/VersionsTests.cpp
  UnitTestsSources/ZipTests.cpp
  UnitTestsSources/LuaTests.cpp
  UnitTestsSources/MultiThreadingTests.cpp
  UnitTestsSources/UnitTestsMain.cpp
  UnitTestsSources/ImageProcessingTests.cpp
  UnitTestsSources/JpegLosslessTests.cpp
  UnitTestsSources/StreamTests.cpp
  )


if (ENABLE_PLUGINS)
  list(APPEND ORTHANC_SERVER_SOURCES
    Plugins/Engine/OrthancPluginDatabase.cpp
    Plugins/Engine/OrthancPlugins.cpp
    Plugins/Engine/PluginsEnumerations.cpp
    Plugins/Engine/PluginsErrorDictionary.cpp
    Plugins/Engine/PluginsManager.cpp
    Plugins/Engine/SharedLibrary.cpp
    )

  list(APPEND ORTHANC_UNIT_TESTS_SOURCES
    UnitTestsSources/PluginsTests.cpp
    )
endif()


set(ORTHANC_ALL_SOURCES
  ${ORTHANC_CORE_SOURCES}
  ${ORTHANC_SERVER_SOURCES}
  ${ORTHANC_UNIT_TESTS_SOURCES}
  Plugins/Samples/ServeFolders/Plugin.cpp
  Plugins/Samples/ModalityWorklists/Plugin.cpp
  OrthancServer/main.cpp
  )


if (CMAKE_COMPILER_IS_GNUCXX
    AND NOT CMAKE_CROSSCOMPILING 
    AND NOT USE_DCMTK_361)
  # Add the "-pedantic" flag only on the Orthanc sources, and only if
  # using DCMTK 3.6.0
  set_source_files_properties(${ORTHANC_ALL_SOURCES}
    PROPERTIES COMPILE_FLAGS -pedantic
    )
endif()


set(ORTHANC_EMBEDDED_FILES
  PREPARE_DATABASE            ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/PrepareDatabase.sql
  UPGRADE_DATABASE_3_TO_4     ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/Upgrade3To4.sql
  UPGRADE_DATABASE_4_TO_5     ${CMAKE_CURRENT_SOURCE_DIR}/OrthancServer/Upgrade4To5.sql
  CONFIGURATION_SAMPLE        ${CMAKE_CURRENT_SOURCE_DIR}/Resources/Configuration.json
  DICOM_CONFORMANCE_STATEMENT ${CMAKE_CURRENT_SOURCE_DIR}/Resources/DicomConformanceStatement.txt
  LUA_TOOLBOX                 ${CMAKE_CURRENT_SOURCE_DIR}/Resources/Toolbox.lua
  FONT_UBUNTU_MONO_BOLD_16    ${CMAKE_CURRENT_SOURCE_DIR}/Resources/Fonts/UbuntuMonoBold-16.json
  )



#####################################################################
## Inclusion of third-party dependencies
#####################################################################

include(${CMAKE_SOURCE_DIR}/Resources/CMake/JsonCppConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibCurlConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibPngConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibJpegConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/LuaConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/MongooseConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/PugixmlConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/SQLiteConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/ZlibConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/GoogleTestConfiguration.cmake)

# These are the two most heavyweight dependencies. We put them as the
# last includes to quickly spot problems when configuring static
# builds.
include(${CMAKE_SOURCE_DIR}/Resources/CMake/BoostConfiguration.cmake)
include(${CMAKE_SOURCE_DIR}/Resources/CMake/DcmtkConfiguration.cmake)


if (ENABLE_SSL)
  add_definitions(-DORTHANC_ENABLE_SSL=1)
  include(${CMAKE_SOURCE_DIR}/Resources/CMake/OpenSslConfiguration.cmake)
else()
  add_definitions(-DORTHANC_ENABLE_SSL=0)
endif()


if (ENABLE_JPEG)
  add_definitions(-DORTHANC_ENABLE_JPEG=1)
else()
  add_definitions(-DORTHANC_ENABLE_JPEG=0)
endif()


if (ENABLE_JPEG_LOSSLESS)
  add_definitions(-DORTHANC_ENABLE_JPEG_LOSSLESS=1)
else()
  add_definitions(-DORTHANC_ENABLE_JPEG_LOSSLESS=0)
endif()


if (ENABLE_PLUGINS)
  add_definitions(-DORTHANC_ENABLE_PLUGINS=1)
else()
  add_definitions(-DORTHANC_ENABLE_PLUGINS=0)
endif()


if (ENABLE_PKCS11)
  if (ENABLE_SSL)
    include(${CMAKE_SOURCE_DIR}/Resources/CMake/LibP11Configuration.cmake)

    add_definitions(-DORTHANC_ENABLE_PKCS11=1)
    list(APPEND ORTHANC_CORE_SOURCES Core/Pkcs11.cpp)
  else()
    message(FATAL_ERROR "OpenSSL is required to enable PKCS#11")
  endif()
else()
  add_definitions(-DORTHANC_ENABLE_PKCS11=0)  
endif()



#####################################################################
## Autogeneration of files
#####################################################################

if (STANDALONE_BUILD)
  # We embed all the resources in the binaries for standalone builds
  add_definitions(-DORTHANC_STANDALONE=1)
  EmbedResources(
    ${ORTHANC_EMBEDDED_FILES}
    ORTHANC_EXPLORER ${CMAKE_CURRENT_SOURCE_DIR}/OrthancExplorer
    ${DCMTK_DICTIONARIES}
    )
else()
  add_definitions(
    -DORTHANC_STANDALONE=0
    -DORTHANC_PATH=\"${CMAKE_SOURCE_DIR}\"
    )
  EmbedResources(
    ${ORTHANC_EMBEDDED_FILES}
    )
endif()

if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
  execute_process(
    COMMAND 
    ${PYTHON_EXECUTABLE} ${ORTHANC_ROOT}/Resources/WindowsResources.py
    ${ORTHANC_VERSION} Orthanc Orthanc.exe "Lightweight, RESTful DICOM server for medical imaging"
    ERROR_VARIABLE Failure
    OUTPUT_FILE ${AUTOGENERATED_DIR}/Orthanc.rc
    )

  if (Failure)
    message(FATAL_ERROR "Error while computing the version information: ${Failure}")
  endif()

  list(APPEND ORTHANC_RESOURCES ${AUTOGENERATED_DIR}/Orthanc.rc)
endif()



#####################################################################
## Configuration of the C/C++ macros
#####################################################################

if (UNIT_TESTS_WITH_HTTP_CONNEXIONS)
  add_definitions(-DUNIT_TESTS_WITH_HTTP_CONNEXIONS=1)
else()
  add_definitions(-DUNIT_TESTS_WITH_HTTP_CONNEXIONS=0)
endif()

include_directories(${CMAKE_SOURCE_DIR}/Plugins/Include)

add_definitions(
  -DORTHANC_VERSION="${ORTHANC_VERSION}"
  -DORTHANC_DATABASE_VERSION=${ORTHANC_DATABASE_VERSION}
  -DORTHANC_BUILD_UNIT_TESTS=1
  -DORTHANC_ENABLE_BASE64=1
  -DORTHANC_ENABLE_LOGGING=1
  -DORTHANC_ENABLE_MD5=1
  -DORTHANC_MAXIMUM_TAG_LENGTH=256
  -DORTHANC_SANDBOXED=0

  # Macros for the plugins
  -DHAS_ORTHANC_EXCEPTION=0
  -DMODALITY_WORKLISTS_VERSION="${ORTHANC_VERSION}"
  -DSERVE_FOLDERS_VERSION="${ORTHANC_VERSION}"
  )


# Setup precompiled headers for Microsoft Visual Studio

# WARNING: There must be NO MORE "add_definitions()", "include()" or
# "include_directories()" below, otherwise the generated precompiled
# headers might get broken!

if (MSVC)
  add_definitions(-DORTHANC_USE_PRECOMPILED_HEADERS=1)

  ADD_VISUAL_STUDIO_PRECOMPILED_HEADERS(
    "PrecompiledHeaders.h" "Core/PrecompiledHeaders.cpp" ORTHANC_CORE_SOURCES)

  ADD_VISUAL_STUDIO_PRECOMPILED_HEADERS(
    "PrecompiledHeadersServer.h" "OrthancServer/PrecompiledHeadersServer.cpp" ORTHANC_SERVER_SOURCES)

  ADD_VISUAL_STUDIO_PRECOMPILED_HEADERS(
    "PrecompiledHeadersUnitTests.h" "UnitTestsSources/PrecompiledHeadersUnitTests.cpp" ORTHANC_UNIT_TESTS_SOURCES)
endif()



#####################################################################
## Build the core of Orthanc
#####################################################################

list(LENGTH OPENSSL_SOURCES OPENSSL_SOURCES_LENGTH)
if (${OPENSSL_SOURCES_LENGTH} GREATER 0)
  add_library(OpenSSL STATIC ${OPENSSL_SOURCES})
endif()

# "CodeLibrary" contains all the third-party dependencies and the
# content of the "Core" folder, but not OpenSSL, nor DCMTK.
add_library(CoreLibrary
  STATIC
  ${ORTHANC_CORE_SOURCES}
  ${AUTOGENERATED_SOURCES}

  ${BOOST_SOURCES}
  ${CURL_SOURCES}
  ${JSONCPP_SOURCES}
  ${LIBPNG_SOURCES}
  ${LIBJPEG_SOURCES}
  ${LUA_SOURCES}
  ${MONGOOSE_SOURCES}
  ${PUGIXML_SOURCES}
  ${SQLITE_SOURCES}
  ${ZLIB_SOURCES}
  ${LIBP11_SOURCES}

  ${CMAKE_SOURCE_DIR}/Resources/ThirdParty/md5/md5.c
  ${CMAKE_SOURCE_DIR}/Resources/ThirdParty/base64/base64.cpp

  # This is the minizip distribution to create ZIP files using zlib
  ${ORTHANC_ROOT}/Resources/ThirdParty/minizip/ioapi.c
  ${ORTHANC_ROOT}/Resources/ThirdParty/minizip/zip.c
  )  


#####################################################################
## Build the Orthanc server
#####################################################################

# "ServerLibrary" contains DCMTK
add_library(ServerLibrary
  STATIC
  ${DCMTK_SOURCES}
  ${ORTHANC_SERVER_SOURCES}
  )

# Ensure autogenerated code is built before building ServerLibrary
add_dependencies(ServerLibrary CoreLibrary)

add_executable(Orthanc
  OrthancServer/main.cpp
  ${ORTHANC_RESOURCES}
  )

target_link_libraries(Orthanc ServerLibrary CoreLibrary ${DCMTK_LIBRARIES})

if (${OPENSSL_SOURCES_LENGTH} GREATER 0)
  target_link_libraries(Orthanc OpenSSL)
endif()

install(
  TARGETS Orthanc
  RUNTIME DESTINATION sbin
  )



#####################################################################
## Build the unit tests
#####################################################################

add_executable(UnitTests
  ${GTEST_SOURCES}
  ${ORTHANC_UNIT_TESTS_SOURCES}
  )

target_link_libraries(UnitTests ServerLibrary CoreLibrary ${DCMTK_LIBRARIES})

if (${OPENSSL_SOURCES_LENGTH} GREATER 0)
  target_link_libraries(UnitTests OpenSSL)
endif()



#####################################################################
## Build the "ServeFolders" plugin
#####################################################################

if (ENABLE_PLUGINS AND BUILD_SERVE_FOLDERS)
  if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
    execute_process(
      COMMAND 
      ${PYTHON_EXECUTABLE} ${ORTHANC_ROOT}/Resources/WindowsResources.py
      ${ORTHANC_VERSION} ServeFolders ServeFolders.dll "Orthanc plugin to serve additional folders"
      ERROR_VARIABLE Failure
      OUTPUT_FILE ${AUTOGENERATED_DIR}/ServeFolders.rc
      )

    if (Failure)
      message(FATAL_ERROR "Error while computing the version information: ${Failure}")
    endif()

    list(APPEND SERVE_FOLDERS_RESOURCES ${AUTOGENERATED_DIR}/ServeFolders.rc)
  endif()  

  add_library(ServeFolders SHARED 
    ${BOOST_SOURCES}
    ${JSONCPP_SOURCES}
    Plugins/Samples/ServeFolders/Plugin.cpp
    Plugins/Samples/Common/OrthancPluginCppWrapper.cpp
    ${SERVE_FOLDERS_RESOURCES}
    )

  set_target_properties(
    ServeFolders PROPERTIES 
    VERSION ${ORTHANC_VERSION} 
    SOVERSION ${ORTHANC_VERSION}
    )

  install(
    TARGETS ServeFolders
    RUNTIME DESTINATION lib    # Destination for Windows
    LIBRARY DESTINATION share/orthanc/plugins    # Destination for Linux
    )
endif()



#####################################################################
## Build the "ModalityWorklists" plugin
#####################################################################

if (ENABLE_PLUGINS AND BUILD_MODALITY_WORKLISTS)
  if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
    execute_process(
      COMMAND 
      ${PYTHON_EXECUTABLE} ${ORTHANC_ROOT}/Resources/WindowsResources.py
      ${ORTHANC_VERSION} ModalityWorklists ModalityWorklists.dll "Sample Orthanc plugin to serve modality worklists"
      ERROR_VARIABLE Failure
      OUTPUT_FILE ${AUTOGENERATED_DIR}/ModalityWorklists.rc
      )

    if (Failure)
      message(FATAL_ERROR "Error while computing the version information: ${Failure}")
    endif()

    list(APPEND MODALITY_WORKLISTS_RESOURCES ${AUTOGENERATED_DIR}/ModalityWorklists.rc)
  endif()

  add_library(ModalityWorklists SHARED 
    ${BOOST_SOURCES}
    ${JSONCPP_SOURCES}
    Plugins/Samples/Common/OrthancPluginCppWrapper.cpp
    Plugins/Samples/ModalityWorklists/Plugin.cpp
    ${MODALITY_WORKLISTS_RESOURCES}
    )

  set_target_properties(
    ModalityWorklists PROPERTIES 
    VERSION ${ORTHANC_VERSION} 
    SOVERSION ${ORTHANC_VERSION}
    )

  install(
    TARGETS ModalityWorklists
    RUNTIME DESTINATION lib    # Destination for Windows
    LIBRARY DESTINATION share/orthanc/plugins    # Destination for Linux
    )
endif()



#####################################################################
## Build the companion tool to recover files compressed using Orthanc
#####################################################################

if (BUILD_RECOVER_COMPRESSED_FILE)
  set(RECOVER_COMPRESSED_SOURCES
    Resources/Samples/Tools/RecoverCompressedFile.cpp
    )

  if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
    execute_process(
      COMMAND 
      ${PYTHON_EXECUTABLE} ${ORTHANC_ROOT}/Resources/WindowsResources.py
      ${ORTHANC_VERSION} OrthancRecoverCompressedFile OrthancRecoverCompressedFile.exe
      "Lightweight, RESTful DICOM server for medical imaging"
      ERROR_VARIABLE Failure
      OUTPUT_FILE ${AUTOGENERATED_DIR}/OrthancRecoverCompressedFile.rc
      )

    if (Failure)
      message(FATAL_ERROR "Error while computing the version information: ${Failure}")
    endif()

    list(APPEND RECOVER_COMPRESSED_SOURCES
      ${AUTOGENERATED_DIR}/OrthancRecoverCompressedFile.rc
      )
  endif()

  add_executable(OrthancRecoverCompressedFile ${RECOVER_COMPRESSED_SOURCES})

  target_link_libraries(OrthancRecoverCompressedFile CoreLibrary)

  install(
    TARGETS OrthancRecoverCompressedFile
    RUNTIME DESTINATION bin
    )
endif()



#####################################################################
## Generate the documentation if Doxygen is present
#####################################################################

find_package(Doxygen)
if (DOXYGEN_FOUND)
  configure_file(
    ${CMAKE_SOURCE_DIR}/Resources/Orthanc.doxygen
    ${CMAKE_CURRENT_BINARY_DIR}/Orthanc.doxygen
    @ONLY)

  configure_file(
    ${CMAKE_SOURCE_DIR}/Resources/OrthancPlugin.doxygen
    ${CMAKE_CURRENT_BINARY_DIR}/OrthancPlugin.doxygen
    @ONLY)

  add_custom_target(doc
    ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Orthanc.doxygen
    COMMENT "Generating internal documentation with Doxygen" VERBATIM
    )

  add_custom_command(TARGET Orthanc
    POST_BUILD
    COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/OrthancPlugin.doxygen
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    COMMENT "Generating plugin documentation with Doxygen" VERBATIM
    )

  install(
    DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/OrthancPluginDocumentation/doc/
    DESTINATION share/doc/orthanc/OrthancPlugin
    )
else()
  message("Doxygen not found. The documentation will not be built.")
endif()



#####################################################################
## Install the plugin SDK
#####################################################################

if (ENABLE_PLUGINS)
  install(
    FILES
    Plugins/Include/orthanc/OrthancCPlugin.h 
    Plugins/Include/orthanc/OrthancCDatabasePlugin.h 
    Plugins/Include/orthanc/OrthancCppDatabasePlugin.h 
    DESTINATION include/orthanc
    )
endif()



#####################################################################
## Prepare the "uninstall" target
## http://www.cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F
#####################################################################

configure_file(
    "${CMAKE_CURRENT_SOURCE_DIR}/Resources/CMake/Uninstall.cmake.in"
    "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
    IMMEDIATE @ONLY)

add_custom_target(uninstall
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
