#SPDX-License-Identifier: GPL-3.0-or-later
CMAKE_MINIMUM_REQUIRED(VERSION 3.1.0)
SET(CMAKE_OSX_DEPLOYMENT_TARGET 10.13)
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/tools/cmake/")

SET(VERSION_MAJOR 2 CACHE INTERNAL "")
SET(VERSION_MINOR 0 CACHE INTERNAL "")
SET(VERSION_PATCH 7 CACHE INTERNAL "")
PROJECT(inishell VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/src/main/config.h.in ${PROJECT_SOURCE_DIR}/src/main/config.h)

###########################################################
# Set language compatibility and qt tools
SET(CMAKE_CXX_STANDARD 11)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
INCLUDE("${CMAKE_SOURCE_DIR}/tools/cmake/SetCompilerOptions.cmake")
SET_COMPILER_OPTIONS()

# Specific QT settings
SET(CMAKE_AUTOMOC ON)
SET(CMAKE_AUTORCC ON)
SET(CMAKE_AUTOUIC ON)
IF(CMAKE_VERSION VERSION_LESS "3.7.0")
    SET(CMAKE_INCLUDE_CURRENT_DIR ON)
ENDIF()

FIND_PACKAGE(Qt5 COMPONENTS Widgets Xml XmlPatterns REQUIRED)
SET(QT5_LIBRARIES Qt5::Widgets Qt5::Xml Qt5::XmlPatterns)
MARK_AS_ADVANCED(FORCE Qt5Core_DIR Qt5Gui_DIR Qt5Network_DIR Qt5Widgets_DIR Qt5XmlPatterns_DIR Qt5Xml_DIR Qt5_DIR)

#finally, SET compile flags
SET(CMAKE_CXX_FLAGS "${ARCH} ${EXTRA}" CACHE STRING "" FORCE)
SET(CMAKE_CXX_FLAGS_RELEASE "${OPTIM}" CACHE STRING "" FORCE)
SET(CMAKE_CXX_FLAGS_DEBUG "${DEBUG} ${WARNINGS} ${EXTRA_WARNINGS}" CACHE STRING "" FORCE)
SET(CMAKE_CXX_FLAGS_CXXFLAGS "$ENV{CXXFLAGS}" CACHE STRING "" FORCE)
MARK_AS_ADVANCED(FORCE CMAKE_CXX_FLAGS_CXXFLAGS)

IF(NOT CMAKE_BUILD_TYPE)
	SET(CMAKE_BUILD_TYPE "release" CACHE STRING "Choose the type of build, options are: debug release coverage cxxflags" FORCE)
	SET(CMAKE_CONFIGURATION_TYPES ${CMAKE_BUILD_TYPE})
ENDIF(NOT CMAKE_BUILD_TYPE)

SET(EXTRA_LIBS_SRC ./lib/tinyexpr.c)
SET(RESOURCES resources/inishell.qrc)
INCLUDE("${PROJECT_SOURCE_DIR}/src/CMakeLists.txt")

SET(TARGET ${CMAKE_PROJECT_NAME})
SET(TARGET_TYPE "")
SET(INSTALL_OSX "")
SET(DLL_EXT "so")

IF(WIN32)
	SET(TARGET_TYPE "WIN32")
	SET(DLL_EXT "dll")
ENDIF(WIN32)
IF(APPLE)
	SET(TARGET_TYPE "MACOSX_BUNDLE")
	SET(INSTALL_OSX BUNDLE DESTINATION bin)
	SET(DLL_EXT "dylib")
ENDIF(APPLE)

ADD_EXECUTABLE(${TARGET} ${TARGET_TYPE} ${EXTRA_LIBS_SRC} ${SOURCES} ${RESOURCES})

INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/")
TARGET_LINK_LIBRARIES(${TARGET} ${QT5_LIBRARIES})
SET_TARGET_PROPERTIES(${TARGET} PROPERTIES
	RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin"
	CLEAN_DIRECT_OUTPUT 1
	OUTPUT_NAME ${TARGET})
INSTALL(TARGETS ${TARGET} RUNTIME DESTINATION bin ${INSTALL_OSX} COMPONENT exe)

# Retrieve the absolute path to qmake and then use that path to find
# the binaries
GET_TARGET_PROPERTY(_qmake_executable Qt5::qmake IMPORTED_LOCATION)
GET_FILENAME_COMPONENT(_qt_bin_dir "${_qmake_executable}" DIRECTORY)

IF(WIN32)
	FIND_PROGRAM(WINDEPLOYQT_EXECUTABLE windeployqt HINTS "${_qt_bin_dir}")
	ADD_CUSTOM_COMMAND(TARGET ${TARGET} POST_BUILD
	COMMAND "${CMAKE_COMMAND}" -E
		env PATH="${_qt_bin_dir}" "${WINDEPLOYQT_EXECUTABLE}"
			"$<TARGET_FILE:${TARGET}>"
	COMMENT "Running windeployqt...")
ENDIF(WIN32)
IF(APPLE)
	FIND_PROGRAM(MACDEPLOYQT_EXECUTABLE macdeployqt HINTS "${_qt_bin_dir}")
	ADD_CUSTOM_COMMAND(TARGET ${TARGET} POST_BUILD
		COMMAND "${MACDEPLOYQT_EXECUTABLE}" "bin/inishell.app" -always-overwrite
		COMMENT "Running macdeployqt..."
	)
ENDIF(APPLE)

# Generate the qm translation files
SET(GENERATE_TRANSLATION_FILES OFF CACHE BOOL "Generate the translations files? (this may require the qttools5-dev package)")
IF(GENERATE_TRANSLATION_FILES)
	FIND_PACKAGE(Qt5LinguistTools REQUIRED)	#requires package qttools5-dev on Ubuntu
	MARK_AS_ADVANCED(FORCE Qt5LinguistTools_DIR)
	SET(TS_FILES ./resources/languages/inishell_de.ts)
	SET_SOURCE_FILES_PROPERTIES(${TS_FILES} PROPERTIES OUTPUT_LOCATION "./resources/l10n")
	qt5_add_translation(qmFiles ${TS_FILES})
ENDIF(GENERATE_TRANSLATION_FILES)

###########################################################
# Custom targets
ADD_CUSTOM_TARGET(distclean make clean
	COMMAND cmake -E remove CMakeCache.txt CPackSourceConfig.cmake CPackConfig.cmake CTestTestfile.cmake DartConfiguration.tcl cmake_install.cmake cmake_uninstall.cmake install_manifest.txt Makefile
	COMMAND cmake -E remove bin/inishell bin/inishell.*
	COMMAND cmake -E remove */CMakeCache.txt */CTestTestfile.cmake */cmake_install.cmake
	COMMAND cmake -E remove */*/CMakeCache.txt */*/CTestTestfile.cmake */*/cmake_install.cmake
	COMMAND cmake -E remove_directory CMakeFiles
	COMMAND cmake -E remove_directory build/tmp/obj tmp/obj inishell_autogen
)

#for the uninstall target
CONFIGURE_FILE(
	"${PROJECT_SOURCE_DIR}/tools/cmake/cmake_uninstall.cmake.in"
	"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
	IMMEDIATE @ONLY
)
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")

#for the install target
SET(XML_DEST inishell-apps)
IF((UNIX) AND (NOT APPLE))
	SET(XML_DEST share/inishell-apps)
ENDIF()

FILE(GLOB xmlfiles "inishell-apps/*.xml")
INSTALL(FILES ${xmlfiles} DESTINATION ${XML_DEST} COMPONENT resources)
FILE(GLOB pngfiles "inishell-apps/*.png")
INSTALL(FILES ${pngfiles} DESTINATION ${XML_DEST} COMPONENT resources)
IF(WIN32)
	FILE(GLOB dlls "bin/*.dll")
	INSTALL(FILES ${dlls} DESTINATION bin COMPONENT exe)
	INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/bin/bearer DESTINATION bin COMPONENT exe)
	INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/bin/iconengines DESTINATION bin COMPONENT exe)
	INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/bin/imageformats DESTINATION bin COMPONENT exe)
	INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/bin/platforms DESTINATION bin COMPONENT exe)
	INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/bin/styles DESTINATION bin COMPONENT exe)
	INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/bin/translations DESTINATION bin COMPONENT exe)
ENDIF(WIN32)

###########################################################
## CPACK section
###########################################################
SET(CPACK_BUNDLE_METEOIO ON CACHE BOOL "Pack a MeteoIO converter application")
IF(CPACK_BUNDLE_METEOIO)
	#bundle MeteoIO
	FIND_PACKAGE(MeteoIO REQUIRED)
	SET(ALL_RX_PERM OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
	FILE(GLOB meteoio_libs "${METEOIO_ROOT}/lib/libmeteo*.${DLL_EXT}")
	IF(WIN32)
		INSTALL(FILES ${meteoio_libs} DESTINATION bin COMPONENT meteoio)
	ELSE(WIN32)
		INSTALL(FILES ${meteoio_libs} DESTINATION lib COMPONENT meteoio)
	ENDIF(WIN32)
	FILE(GLOB meteoio_bins "${METEOIO_ROOT}/bin/meteoio_timeserie*")
	INSTALL(FILES ${meteoio_bins} DESTINATION bin PERMISSIONS ${ALL_RX_PERM} COMPONENT meteoio)
ENDIF(CPACK_BUNDLE_METEOIO)

SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Inishell Graphical User Interface dynamic generator for numerical models")
SET(CPACK_PACKAGE_DESCRIPTION "An XML description of the input fields necessary to configure a given numerical model is used to generate on the fly a Graphical User Interface that lets the user configure the numerical model and even run it if so configured")
SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/Welcome.txt")
SET(CPACK_PACKAGE_NAME "Inishell")
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}")
SET(CPACK_PACKAGE_CONTACT "Mathias Bavay <Mathias.Bavay@wsl.ch>")
SET(CPACK_PACKAGE_VENDOR "WSL Institute for Snow and Avalanche Research")
SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/resources/icons\\\\inishell_192.ico")
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE.txt")
SET(CPACK_RESOURCE_FILE_WELCOME "${CMAKE_SOURCE_DIR}/Welcome.txt")
SET(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/Readme.txt")

SET(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}")
SET(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}")
SET(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PATCH}")
SET(VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}")
SET(CPACK_ARCH "${CMAKE_SYSTEM_PROCESSOR}")
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${VERSION}-${CPACK_ARCH}")

#installation by components for formats that support it
#SET(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE 1)
SET(CPACK_COMPONENTS_ALL exe resources meteoio)
SET(CPACK_COMPONENT_EXE_DISPLAY_NAME "Inishell application")
SET(CPACK_COMPONENT_EXE_DESCRIPTION "The Inishell applications itself with what it needs to run")
SET(CPACK_COMPONENT_EXE_REQUIRED ON)
SET(CPACK_COMPONENT_RESOURCES_DISPLAY_NAME "Inishell resources")
SET(CPACK_COMPONENT_RESOURCES_DESCRIPTION "Additional files to use Inishell")
IF(CPACK_BUNDLE_METEOIO)
	SET(CPACK_COMPONENT_METEOIO_DISPLAY_NAME "MeteoIO converter application")
	SET(CPACK_COMPONENT_METEOIO_DESCRIPTION "A MeteoIO based application to read/convert/output timeseries")
ENDIF(CPACK_BUNDLE_METEOIO)

IF(UNIX)
	IF(APPLE)	#OsX packages: IMG
		SET(CPACK_GENERATOR "DragNDrop")
		SET(CPACK_PACKAGING_INSTALL_PREFIX "/${CPACK_PACKAGE_NAME}")
		SET(CPACK_DMG_FORMAT "UDBZ")
		#SET(CPACK_GENERATOR "Bundle")
		SET(CPACK_BUNDLE_PLIST "${CMAKE_SOURCE_DIR}/tools/inishell.plist")
		SET(MACOSX_BUNDLE_INFO_STRING "${CPACK_PACKAGE_DESCRIPTION_SUMMARY}")
		SET(CPACK_BUNDLE_ICON "${CMAKE_SOURCE_DIR}/resources/icons/inishell_192.icns")
		SET(MACOSX_BUNDLE_ICON_FILE "${CPACK_BUNDLE_ICON}")
		SET(MACOSX_BUNDLE_GUI_IDENTIFIER "${CPACK_PACKAGE_DESCRIPTION}")
		SET(MACOSX_BUNDLE_LONG_VERSION_STRING "${VERSION}")
		SET(CPACK_BUNDLE_NAME "${CPACK_PACKAGE_NAME}")
		SET(MACOSX_BUNDLE_BUNDLE_NAME "${CPACK_PACKAGE_NAME}")
		SET(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VERSION}")
		SET(MACOSX_BUNDLE_BUNDLE_VERSION "0")
		SET(MACOSX_BUNDLE_COPYRIGHT "${CPACK_PACKAGE_VENDOR}")
		#SET(CPACK_PACKAGING_INSTALL_PREFIX "/Applications/${CPACK_PACKAGE_NAME}")
		SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/resources/icons/inishell_192.icns")
		SET_SOURCE_FILES_PROPERTIES(${CPACK_BUNDLE_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
	ELSE(APPLE)	#Linux packages: rmp, deb and tgz
		SET(CPACK_GENERATOR "DEB;RPM;TGZ")
		SET(CPACK_PACKAGING_INSTALL_PREFIX "/usr")
		SET(CPACK_DEBIAN_PACKAGE_NAME "inishell")
		SET(CPACK_DEBIAN_PACKAGE_SECTION "Education/Science")
		SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libQt5Widgets5,libQt5Xml5,libQt5XmlPatterns5,libQt5Gui5,libQt5Network5,libQt5Core5a") #objdump -p lib/libmeteoio.so | grep NEEDED | tr -s ' ' | cut -d' ' -f3 | tr '\n' ','
		SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION}")
		#SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "i386") #dpkg --print-architecture
		IF("${CPACK_ARCH}" STREQUAL "x86_64")
			SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
		ELSE("${CPACK_ARCH}" STREQUAL "x86_64")
			SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CPACK_ARCH}")
		ENDIF("${CPACK_ARCH}" STREQUAL "x86_64")
		SET(CPACK_RPM_PACKAGE_NAME "inishell")
		SET(CPACK_RPM_PACKAGE_LICENSE "GPLv3")
		SET(CPACK_RPM_PACKAGE_REQUIRES "libstdc++") #simply libproj for OpenSuse
		SET(CPACK_RPM_PACKAGE_ARCHITECTURE "${CPACK_ARCH}")
		SET(CPACK_RPM_PACKAGE_GROUP "Education/Science")
	ENDIF(APPLE)
ELSE(UNIX)
	IF(WIN32)	#Windows packages
		SET(CPACK_GENERATOR "NSIS")
		SET(CPACK_NSIS_MUI_ICON "${CPACK_PACKAGE_ICON}")
		SET(CPACK_PACKAGE_ICON "${CPACK_PACKAGE_ICON}")
		SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CPACK_PACKAGE_NAME}")
		
		#Main links (they can get overwritten later)
		SET(MENU_LINKS_INISHELL "bin/inishell.exe" "Inishell")
		SET(MENU_LINKS_INISHELL_APPS ${XML_DEST} "Inishell XML files")
		SET(MENU_LINKS_INISHELL_HOME "https://models.slf.ch/p/inishell-ng" "Inishell's home page" )
		SET(MENU_LINKS_INISHELL_SRC "https://code.wsl.ch/snow-models/inishell" "Inishell's repository")
		
		SET(CPACK_NSIS_MENU_LINKS ${MENU_LINKS_INISHELL} ${MENU_LINKS_INISHELL_APPS} ${MENU_LINKS_INISHELL_HOME} ${MENU_LINKS_INISHELL_SRC})
		
		#info for the add/uninstall software administration
		SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_NAME}-${VERSION}")
		SET(CPACK_NSIS_INSTALLED_ICON_NAME "${CMAKE_SOURCE_DIR}/resources/icons\\\\inishell_192.ico")
		SET(CPACK_NSIS_URL_INFO_ABOUT "https://www.slf.ch")
		SET(CPACK_NSIS_HELP_LINK "https://models.slf.ch/p/inishell-ng")
		SET(CPACK_NSIS_CONTACT "${CPACK_PACKAGE_CONTACT}")
		SET(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL "ON")
	ENDIF(WIN32)
ENDIF(UNIX)

#Source packages
SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${VERSION}" CACHE INTERNAL "tarball basename")
SET(CPACK_SOURCE_GENERATOR TGZ)
# The following components are regex's to match anywhere (unless anchored)
# in absolute path + filename to find files or directories to be excluded
# from source tarball.
SET(CPACK_SOURCE_IGNORE_FILES
	"~$"
	"\\\\.svn/"
	"/CMakeFiles/"
	"/CMakeCache*"
	"/cmake_install\\\\.cmake$"
	"/cmake_uninstall\\\\.cmake$"
	"^_CPack_.*/"
	"/CPack*"
	"\\\\.o$"
	"/m4/"
)

INCLUDE(CPack)

