#############################################################
#############################################################
# CMake configuration
cmake_minimum_required(VERSION 3.18.4)

############################################################
############################################################
# Basic information about project

project(massXpert2
  DESCRIPTION "A program to model and simulate mass spectra on linear (bio-)polymers"
  HOMEPAGE_URL "http://wwww.msxpertsuite.org/massxpert2")

set(LOWCASE_PROJECT_NAME massxpert2)

set(VERSION 8.5.0)

# Set additional project information
set(COMPANY "msXpertSuite.org")
set(COPYRIGHT "Copyright (c) 2008-2024 Filippo Rusconi. Licensed under GPLv3+")
set(IDENTIFIER "org.msxpertsuite")


include(GNUInstallDirs)

# Add folder where are supportive functions
set(CMAKE_UTILS_PATH ${CMAKE_SOURCE_DIR}/CMakeStuff)
set(CMAKE_TOOLCHAINS_PATH ${CMAKE_UTILS_PATH}/toolchains)
set(CMAKE_MODULE_PATH ${CMAKE_UTILS_PATH}/modules)

# This include must come before all the others
# It must include the config-generated config.h file
# before the others.
include_directories(${CMAKE_BINARY_DIR})

# And now the source directory contains the .h|.hpp files for its .cpp files.
include_directories(${CMAKE_SOURCE_DIR})

# For the config.h file.
set(CMAKE_INCLUDE_CURRENT_DIR ON)

# Include the system's uname that fills in SYSTEM_UNAME_S.
# Sets WIN32 if SYSTEM_UNAME_S is "^.*MING64.*"
# Note that WIN32 is set even on 64 bits systems.
include(${CMAKE_UTILS_PATH}/systemUname.cmake)

# Include the various colors we want to use in the output
include(${CMAKE_UTILS_PATH}/outputColors.cmake)

set(CMAKE_COLOR_MAKEFILE ON)
set(CMAKE_VERBOSE_MAKEFILE ON)

message("\n${BoldRed}Configuring build for project ${CMAKE_PROJECT_NAME}${ColourReset}\n")

# This export will allow using the flags to be used by
# youcompleteme (vim plugin).
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)

if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json" )
  execute_process( COMMAND cmake -E copy_if_different
    ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json
    ${CMAKE_SOURCE_DIR}/compile_commands.json
  )
endif()


# We want C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}")

#############################################################
# We do not want warnings for unknown pragmas:
message(STATUS "Setting definition -Wno-unknown-pragmas.")
add_definitions(-Wno-unknown-pragmas)

# Enable warnings and possibly treat them as errors
message(STATUS "Setting definition -Wall -pedantic.")
add_definitions(-Wall -pedantic)
message(STATUS "Setting definition -Wextra.")
add_definitions(-Wextra)

if(WARN_AS_ERROR)
  message(STATUS "Setting definition -Werror.")
  add_definitions(-Werror)
endif()

message("CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")

option(MXE OFF)

option(PAPPSO_LOCAL_DEV OFF)
option(XPERTMASS_LOCAL_DEV OFF)
# Same as both above
option(LOCAL_DEV OFF)

if(LOCAL_DEV)
set(PAPPSO_LOCAL_DEV ON)
set(XPERTMASS_LOCAL_DEV ON)
endif()

message(STATUS "LOCAL_DEV: ${LOCAL_DEV}")
message(STATUS "PAPPSO_LOCAL_DEV: ${PAPPSO_LOCAL_DEV}")
message(STATUS "XPERTMASS_LOCAL_DEV: ${XPERTMASS_LOCAL_DEV}")

#############################################################
#############################################################
# Platform-specific CMake configuration
if(WIN32 OR _WIN32)

  if(MXE)

    # Run the following cmake command line:
    # x86_64-w64-mingw32.shared-cmake -DCMAKE_BUILD_TYPE=Release -DMXE=1 ../../development
    include(${CMAKE_TOOLCHAINS_PATH}/mxe-toolchain.cmake)

    # Set the name to the systemUname variable because in this situation that name
    # is not found, it it passed as a flag in the command line.
    set(SYSTEM_UNAME_S "mxe")

  elseif(WIN10MINGW64)
    include(${CMAKE_TOOLCHAINS_PATH}/win10-mingw64-toolchain.cmake)
  endif()

elseif(UNIX)

  message("UNIX toolchain being selected")

  include(${CMAKE_TOOLCHAINS_PATH}/unix-toolchain-common.cmake)

endif()

message("")
message(STATUS "${BoldGreen}Starting configuration of ${CMAKE_PROJECT_NAME}${ColourReset}")
message("")
message(STATUS "${BoldYellow}The build toolchain is: ${SYSTEM_UNAME_S}${ColourReset}")
message("")


#############################################################
#############################################################
# Essential software configuration
message(STATUS "CMAKE_CURRENT_BINARY_DIR: " ${CMAKE_CURRENT_BINARY_DIR})

if(NOT CMAKE_BUILD_TYPE)
  set(CMAKE_BUILD_TYPE Release CACHE STRING
    "Type of build, options are: None, Debug, Release, RelWithDebInfo, MinSizeRel."
    FORCE)
endif(NOT CMAKE_BUILD_TYPE)

if(CMAKE_BUILD_TYPE MATCHES "Release")
  message(STATUS "Compiling in release mode.")
  add_definitions("-DQT_NO_DEBUG_OUTPUT")
endif()

if(CMAKE_BUILD_TYPE MATCHES "Debug")
  message(STATUS "Compiling in debug mode.")
  message(STATUS "Add definition -ggdb3 to format debug output for GDB.")
  add_definitions(-ggdb3)
endif()

if(CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")
  message(STATUS "Compiling in release with debug info mode.")
endif( CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo" )

message(STATUS "${BoldYellow}CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}.${ColourReset}")


if(PROFILE)
  message(STATUS "${BoldYellow}Profiling is requested, adding -pg flag.${ColourReset}")
  add_definitions(-pg)
endif()

message(STATUS "${BoldYellow}Main CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}${ColourReset}")
message(STATUS "${BoldYellow}CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}${ColourReset}")

# It is essential to run these config steps before delving into the massxpert
# directory, because at that moment they will need what are
# going to prepare right now.
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/CMakeStuff/splashscreen.svg.in
  ${CMAKE_SOURCE_DIR}/images/svg/splashscreen.svg @ONLY)

# Make the conversion of the svg file into a png, but only on GNU/Linux
if(UNIX)
  execute_process(COMMAND inkscape
    ${CMAKE_SOURCE_DIR}/images/svg/splashscreen.svg -o
    ${CMAKE_SOURCE_DIR}/images/splashscreen.png -w 600)
endif()

#############################################################
######################
# BUILD OF THE PROGRAM

message(STATUS "Adding subdirectory src for TARGET: ${TARGET}")
add_subdirectory(src)

#############################################################
###################
# BUILD OF THE DATA
message(STATUS "Adding subdirectory data for project: ${TARGET}")
add_subdirectory(data)

#############################################################
################################
# BUILD OF THE DOC / USER MANUAL
option(BUILD_USER_MANUAL "Build the user manual, on UNIX only." OFF)
message(STATUS "Adding subdirectory doc for project: ${TARGET}")
add_subdirectory(doc)

#############################################################
####################
# BUILD OF THE TESTS
option(BUILD_TESTS "Build the test suite." OFF)
  if(BUILD_TESTS)
  message(STATUS "Adding subdirectory tests for building tests for project: ${TARGET}")
  add_subdirectory(tests)
endif()

# Use all the configured paths to create the config.h file.
# The config file is binary directory-specific !!!
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/CMakeStuff/config.h.in
  ${CMAKE_CURRENT_BINARY_DIR}/src/config.h @ONLY)


#############################################################
#############################################################
# Installation prefix
if (NOT CMAKE_INSTALL_PREFIX)
  SET (CMAKE_INSTALL_PREFIX /usr/local)
endif (NOT CMAKE_INSTALL_PREFIX)


####################################################
# Installation directories depending on the platform
####################################################

# See the CMakeStuff/toolchains platform-specific files.
message(STATUS "CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}")
message(STATUS "BIN_DIR: ${BIN_DIR}")
message(STATUS "DATA_DIR: ${DATA_DIR}")
message(STATUS "DOC_DIR: ${DOC_DIR}")


#############################################################
###########################
# CREATE THE SOURCE PACKAGE
include(${CMAKE_UTILS_PATH}/targz-source-package-creation.cmake)

add_custom_target(archive
  cpack -G TGZ --config CPackSourceConfig.cmake && mv
  ${CMAKE_BINARY_DIR}/${LOWCASE_PROJECT_NAME}-${VERSION}.tar.gz
  ${CMAKE_SOURCE_DIR}/../tarballs && ln -sf
  ${CMAKE_SOURCE_DIR}/../tarballs/${LOWCASE_PROJECT_NAME}-${VERSION}.tar.gz
  ${CMAKE_SOURCE_DIR}/../${LOWCASE_PROJECT_NAME}_${VERSION}.orig.tar.gz && ln -sf
  ${CMAKE_SOURCE_DIR}/../tarballs/${LOWCASE_PROJECT_NAME}-${VERSION}.tar.gz
  ${CMAKE_SOURCE_DIR}/../tarballs/${LOWCASE_PROJECT_NAME}_${VERSION}.orig.tar.gz

  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
  COMMENT "Creating .tar.gz" VERBATIM
)


#############################################################
# summary
message("")
message(STATUS "${BoldRed}~~~~~~~~~~~~~~~~~~~~~~~~ SUMMARY ~~~~~~~~~~~~~~~~~~~~~~~~${ColourReset}")
message(STATUS "${BoldRed}   General configuration of the ${CMAKE_PROJECT_NAME} project ${ColourReset}")
message("")

message(STATUS "${BoldYellow}System is detected by CMake as ${SYSTEM_UNAME_S}${ColourReset}")
message(STATUS "${BoldYellow}CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}${ColourReset}")
message(STATUS "${BoldYellow}CMAKE_CXX_STANDARD: ${CMAKE_CXX_STANDARD}${ColourReset}")

message("")

message(STATUS "${BoldYellow}CMAKE_INSTALL_PREFIX: ${CMAKE_INSTALL_PREFIX}${ColourReset}")
message(STATUS "${BoldYellow}TARGET: ${TARGET}${ColourReset}")
message(STATUS "${BoldYellow}BIN_DIR: ${BIN_DIR}${ColourReset}")
message(STATUS "${BoldYellow}DOC_DIR: ${DOC_DIR}${ColourReset}")

if(PROFILE)
  message(STATUS "${BoldYellow}Profiling is requested (-DPROFILE=1)${ColourReset}")
else()
  message(STATUS "${BoldYellow}Profiling is NOT requested (-DPROFILE=0)${ColourReset}")
endif()

if(WARNASERR)
  message(STATUS "${BoldYellow}Warnings ARE treated as errors (-DWARNASERR=1)${ColourReset}")
else()
  message(STATUS "${BoldYellow}Warnings NOT treated as errors (-DWARNASERR=0)${ColourReset}")
endif()

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
  message(STATUS "${BoldYellow}Debug support IS requested.${ColourReset}")
else()
  message(STATUS "${BoldYellow}Debug support NOT requested.${ColourReset}")
endif()

message("")
message(STATUS "${BoldYellow}The typical cmake invocation on Debian GNU/Linux would be: cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_USER_MANUAL=1 ../../development${ColourReset}")
message(STATUS "${BoldYellow}The typical cmake invocation on win10-mingw64 would be: cmake -DCMAKE_BUILD_TYPE=Release  ../../development${ColourReset}")
message(STATUS "${BoldYellow}The typical cmake invocation on MXE would be: x86_64-w64-mingw32.shared-cmake -DCMAKE_BUILD_TYPE=Release -DMXE=1 ../../development${ColourReset}")
message("")

if(LOCAL_DEV OR PAPPSO_LOCAL_DEV)
  message("")
  message("${BoldGreen}USING LOCAL DEVELOPMENT CONFIG FOR PAPPSOMS libraries")
  message("")
endif()

if(LOCAL_DEV OR XPERTMASS_LOCAL_DEV)
  message("")
  message("${BoldGreen}USING LOCAL DEVELOPMENT CONFIG FOR XPERTMASS libraries")
  message("")
endif()

message("")
message(STATUS "${BoldRed}~~~~~~~~~~~~~~~~~~~~~~~~ SUMMARY ~~~~~~~~~~~~~~~~~~~~~~~~${ColourReset}")
message("")

