##-----------------------------------------------------------------------------
##  Welcome to the Plastimatch CMakeLists.txt file
##-----------------------------------------------------------------------------
##  See COPYRIGHT.TXT and LICENSE.TXT for copyright and license information
##-----------------------------------------------------------------------------
project (src_plastimatch)

##-----------------------------------------------------------------------------
##  Local options
##-----------------------------------------------------------------------------

# Plastimatch software configuration options
option (PLM_CONFIG_ALT_DCOS "Use alternative direction cosines rules" OFF)
option (PLM_CONFIG_KEYHOLIZE "Enable RT structure keyholization" OFF)
option (PLM_CONFIG_PREFER_DCMTK 
  "Use DCMTK instead of GDCM for DICOM operations" OFF)
option (PLM_CONFIG_USE_SS_IMAGE_VEC
  "Save structure sets as ITK UCHAR VEC images (in development)" ON)
option (PLM_CONFIG_CLANG_COMPLETE "Generate .clang_complete for hipster Vim-ers" OFF)
option (PLM_CONFIG_DISABLE_VISCOUS "Disable experimental viscous fluid registration algorithm" ON)
option (PLM_CONFIG_ENABLE_PLASTIMATCH_QT
  "Enable experimental plastimatch_qt executable" OFF)

##-----------------------------------------------------------------------------
##  Figure out if we should use gdcm or dcmtk
##-----------------------------------------------------------------------------
set (PLM_DCM_USE_DCMTK 0)
if (PLM_CONFIG_DEBIAN_BUILD)
  set (PLM_CONFIG_DISABLE_DCMTK FALSE)
  set (PLM_CONFIG_PREFER_DCMTK TRUE)
endif ()
if (PLM_CONFIG_DISABLE_DCMTK)
  set (DCMTK_FOUND FALSE)
endif ()
if (DCMTK_FOUND)
  if (PLM_CONFIG_PREFER_DCMTK)
    # User requested dcmtk
    set (PLM_DCM_USE_DCMTK 1)
  elseif (GDCM_VERSION_2)
    # Gdcm 2.x
    set (PLM_DCM_USE_DCMTK 1)
  else ()
    # Gdcm 1.x
    set (PLM_DCM_USE_DCMTK 0)
  endif ()
endif ()

# If the user only has gdcm 2.x, give a warning
if (GDCM_VERSION_2 AND NOT PLM_DCM_USE_DCMTK)
  message (WARNING "Plastimatch will be built with GDCM 2.X.  This means DICOM-RT functions are disabled; if possible, please use DCMTK or GDCM 1.X instead.")
endif ()

##-----------------------------------------------------------------------------
##  Include directories
##-----------------------------------------------------------------------------
include_directories (BEFORE ${CMAKE_BINARY_DIR})
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
# JAS 2012.04.25 !!!!!!!!!!! TEMPORARY !!!!!!!!!!!!!!!!!!!!!!
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/base)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/cli)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/clp)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/dose)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/cuda)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/opencl)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/qt)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/reconstruct)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/reconstruct/cuda)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/register)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/register/cuda)
# GCS 2013-09-11.  Disable scripting, because it doesn't yet support 
#   smart pointers for registration.
# include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/script)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/segment)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/sys)
include_directories (BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/util)
#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
include_directories (BEFORE ${CMAKE_CURRENT_BINARY_DIR})
include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/itk-3.20.0)
include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/demons_itk_insight)
include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/demons_itk_insight/DiffeomorphicDemons)
include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/demons_itk_insight/FastSymmetricForces)
include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/demons_itk_insight/LOGDomainDemons)
include_directories (AFTER ${CMAKE_SOURCE_DIR}/libs/nSIFT)
include_directories (AFTER ${BSTRLIB_INCLUDE_DIR})
include_directories (AFTER ${DLIB_INCLUDE_DIR})
include_directories (AFTER ${LIBLBFGS_INCLUDE_DIR})
include_directories (AFTER ${MSINTTYPES_INCLUDE_DIR})
include_directories (AFTER ${RANSAC_INCLUDE_DIRS})

if (CUDA_FOUND)
  include_directories (AFTER ${CUDA_INCLUDE_DIRS})
endif ()
if (DCMTK_FOUND)
  include_directories (AFTER ${DCMTK_INCLUDE_DIR})
endif ()
if (FFTW_FOUND)
  include_directories (BEFORE ${FFTW_INCLUDE_DIR})
  link_directories (${FFTW_DIR})
endif ()
if (NOT HAVE_GETOPT_LONG)
  include_directories (AFTER "${CMAKE_SOURCE_DIR}/libs/getopt")
endif ()
if (MATLAB_FOUND)
  include_directories (AFTER ${MATLAB_INCLUDE_DIRS})
endif ()
if (NLOPT_FOUND)
  include_directories (AFTER ${NLOPT_INCLUDE_DIR})
endif ()
if (OPENCL_FOUND)
  include_directories (BEFORE ${OPENCL_INCLUDE_DIRS})
endif ()
if (PANTHEIOS_FOUND)
  include_directories (AFTER ${STLSOFT_INCLUDE_DIR})
  include_directories (AFTER ${PANTHEIOS_INCLUDE_DIR})
endif ()
if (QT4_FOUND)
  if (QT_QTGUI_FOUND)
    include_directories (AFTER ${QT_QTGUI_INCLUDE_DIR})
  endif ()
  if (QT_QTSQL_FOUND)
    include_directories (AFTER ${QT_QTSQL_INCLUDE_DIR})
  endif ()
endif ()
if (SQLITE_FOUND)
  include_directories (AFTER ${SQLITE_INCLUDE_DIR})
endif ()

##-----------------------------------------------------------------------------
##  CONFIGURE INCLUDE FILES
##-----------------------------------------------------------------------------
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/sys/plm_config.h.in
  ${PLM_BUILD_ROOT}/plm_config.h)

if (NOT PLM_PREFER_NO_FORTRAN_NO_F2C)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/sys/plm_fortran.h.in
  ${PLM_BUILD_ROOT}/plm_fortran.h)
endif ()

##-----------------------------------------------------------------------------
## Option to generate .clang_complete for hip Vim users using clang_complete
##-----------------------------------------------------------------------------
if (PLM_CONFIG_CLANG_COMPLETE)
    get_property(inc_dirs DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
    set (file_clang_complete "${PLM_SRC_ROOT}/src/plastimatch/.clang_complete")
    foreach (arg ${inc_dirs})
        set (inc_args "${inc_args} -I${arg}\n")
    endforeach ()
    file (WRITE "${file_clang_complete}" "${inc_args}")
    message (STATUS "Generated ${file_clang_complete}")
endif ()

##-----------------------------------------------------------------------------
##  Do we have prerequisites for viscous code?
##-----------------------------------------------------------------------------
set (PLM_BUILD_VISCOUS FALSE)
if (NOT PLM_CONFIG_DISABLE_VISCOUS
    AND CUDA_FOUND AND CUDA_SDK_ROOT_DIR AND THRUST_FOUND)
  set (PLM_BUILD_VISCOUS TRUE)
endif ()


##-----------------------------------------------------------------------------
##  OLD BUILD SYSTEM REMNANTS
##-----------------------------------------------------------------------------
# JAS 2012.05.15 -- needs to be merged then removed for new build system
#if (FULL_PLASTIMATCH_BUILD)
#  # Ugh.  ITK is stupid.  They quietly dropped support for cygwin. 
#  # However, you can still get 3.20.0 to work.  You need to run 
#  # "make ITKFEM" after running "make" to workaround ITK's broken CMake 
#  # script:
#  #  http://old.nabble.com/compile-error-using-cygwin-td30879187.html
#  # See also:
#  #  http://public.kitware.com/Bug/view.php?id=11659
#  if (CYGWIN)
#    set (PLASTIMATCH1_LIBRARY_DEPENDENCIES 
#      ${PLASTIMATCH1_LIBRARY_DEPENDENCIES} gdi32)
#  endif ()
#endif ()

##-----------------------------------------------------------------------------
##  PLASTIMATCH MODULES
##-----------------------------------------------------------------------------
if (PLM_CONFIG_LIBRARY_BUILD)
else ()
  set (PLMLIB_CONFIG_ENABLE_CLI true)
  set (PLMLIB_CONFIG_ENABLE_CLP true)
  set (PLMLIB_CONFIG_ENABLE_DOSE true)
  set (PLMLIB_CONFIG_ENABLE_QT true)
  set (PLMLIB_CONFIG_ENABLE_RECONSTRUCT true)
  set (PLMLIB_CONFIG_ENABLE_REGISTER true)
#  set (PLMLIB_CONFIG_ENABLE_SCRIPT true)
  set (PLMLIB_CONFIG_ENABLE_SEGMENT true)
  set (PLMLIB_CONFIG_ENABLE_STANDALONE true)
  set (PLMLIB_CONFIG_ENABLE_TEST true)
endif ()

if (PLMLIB_CONFIG_ENABLE_REGISTER OR PLMLIB_CONFIG_ENABLE_RECONSTRUCT)
  set (PLMLIB_CONFIG_ENABLE_CUDA true)
  set (PLMLIB_CONFIG_ENABLE_OPENCL true)
endif ()

# Core
add_subdirectory(base)
add_subdirectory(sys)
add_subdirectory(util)

# Optional
if (PLMLIB_CONFIG_ENABLE_CLI)
  add_subdirectory(cli)
endif ()
if (PLMLIB_CONFIG_ENABLE_CLP)
  add_subdirectory(clp)
endif ()
if (CUDA_FOUND AND PLMLIB_CONFIG_ENABLE_CUDA)
  add_subdirectory(cuda)
endif ()
if (PLMLIB_CONFIG_ENABLE_DOSE)
  add_subdirectory(dose)
endif ()
if (OPENCL_FOUND AND PLMLIB_CONFIG_ENABLE_OPENCL)
  add_subdirectory(opencl)
endif ()
if (PLMLIB_CONFIG_ENABLE_QT)
  add_subdirectory(qt)
endif ()
if (PLMLIB_CONFIG_ENABLE_RECONSTRUCT)
  add_subdirectory(reconstruct)
endif ()
if (PLMLIB_CONFIG_ENABLE_REGISTER)
  add_subdirectory(register)
endif ()
#if (PLMLIB_CONFIG_ENABLE_SCRIPT)
#  add_subdirectory(script)
#endif ()
if (PLMLIB_CONFIG_ENABLE_SEGMENT)
  add_subdirectory(segment)
endif ()
if (PLMLIB_CONFIG_ENABLE_STANDALONE)
  add_subdirectory(standalone)
endif ()
if (PLMLIB_CONFIG_ENABLE_TEST)
  add_subdirectory(test)
endif ()

##-----------------------------------------------------------------------------
##  Set up configuration for external projects using plastimatch API
##-----------------------------------------------------------------------------
# Add targets to build tree export set
set (EXPORT_TARGET_LIST bstrlib plmsys plmbase devillard nkidecompress plmutil)
if (PLMLIB_CONFIG_ENABLE_DOSE)
  set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} specfun plmdose)
endif ()
if (PLMLIB_CONFIG_ENABLE_REGISTER)
  if (NOT PLM_PREFER_NO_FORTRAN_NO_F2C)
    set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} nocedal)
  endif ()
  set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} lbfgs plmregister)
endif ()
if (PLMLIB_CONFIG_ENABLE_RECONSTRUCT)
  set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} plmreconstruct)
endif ()
if (NOT PLM_PREFER_NO_FORTRAN_NO_F2C)
  if (PLM_USE_INCLUDED_F2C)
    set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} f2c1)
  endif ()
endif ()
if (CUDA_FOUND)
  if (PLMLIB_CONFIG_ENABLE_REGISTER OR PLMLIB_CONFIG_ENABLE_RECONSTRUCT)
    set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} plmcuda)
  endif ()
  if (PLMLIB_CONFIG_ENABLE_REGISTER)
    set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} plmregistercuda)
  endif ()
  if (PLMLIB_CONFIG_ENABLE_RECONSTRUCT)
    set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} plmreconstructcuda)
  endif ()
endif ()
if (OPENCL_FOUND)
  if (PLMLIB_CONFIG_ENABLE_REGISTER OR PLMLIB_CONFIG_ENABLE_RECONSTRUCT)
    set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} plmopencl)
  endif ()
endif ()
if (PLMLIB_CONFIG_ENABLE_SEGMENT)
  set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} plmsegment)
endif ()
#if (PLMLIB_CONFIG_ENABLE_SCRIPT)
#  set (EXPORT_TARGET_LIST ${EXPORT_TARGET_LIST} lua plmscript)
#endif ()
export (TARGETS 
  ${EXPORT_TARGET_LIST}
  FILE "${CMAKE_BINARY_DIR}/PlastimatchLibraryDepends.cmake")

# Help cmake find the PlastimatchConfig.cmake in the build directory
if (NOT ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_LESS 2.8)
  export (PACKAGE Plastimatch)
endif ()

# Create PlastimatchBuildTreeSettings.cmake for the use from the build tree
file (RELATIVE_PATH CONF_REL_INCLUDE_DIR "${PLM_INSTALL_CMAKE_DIR}"
  "${PLM_INSTALL_INCLUDE_DIR}")
configure_file (
  "${PROJECT_SOURCE_DIR}/cmake/PlastimatchConfig.cmake.in" 
  "${CMAKE_BINARY_DIR}/PlastimatchConfig.cmake" 
  @ONLY)
configure_file (
  "${PROJECT_SOURCE_DIR}/cmake/PlastimatchBuildTreeSettings.cmake.in"
  "${CMAKE_BINARY_DIR}/PlastimatchBuildTreeSettings.cmake" @ONLY)

# Install the PlastimatchConfig.cmake file
install (FILES 
  "${CMAKE_BINARY_DIR}/PlastimatchConfig.cmake" 
  DESTINATION "${PLM_INSTALL_CMAKE_DIR}"
  # COMPONENT dev
  )

# Install the export set for use with the install-tree
install (EXPORT PlastimatchLibraryDepends 
  DESTINATION "${PLM_INSTALL_CMAKE_DIR}"
  # COMPONENT dev
  )

##-----------------------------------------------------------------------------
##  DOXYGEN
##-----------------------------------------------------------------------------
if (DOXYGEN_FOUND)
  file (MAKE_DIRECTORY "${PLM_BUILD_ROOT}/doc")
  configure_file (
    ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in 
    ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 
    @ONLY)
  add_custom_target (doc
    ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
    WORKING_DIRECTORY "${PLM_BUILD_ROOT}/doc"
    COMMENT "Generating API documentation with Doxygen" VERBATIM
    )
endif ()
