#*******************************************************************************
#**  This file is part of Pecunia.                                           ***
#**                                                                          ***
#**  Copyright (C) 2017, 2018, 2019, 2020, 2021, 2023, 2024                  ***
#**  John Schneiderman <Licencing _AT_ Schneiderman _DOT_ me>                ***
#**                                                                          ***
#**  This program is free software: you can redistribute it and/or modify it ***
#**  under the terms of the GNU Lesser General Public License as published   ***
#**  by the Free Software Foundation, either version 3 of the License, or    ***
#**  (at your option) any later version.                                     ***
#**                                                                          ***
#**  This program is distributed in the hope that it will be useful, but     ***
#**  WITHOUT ANY WARRANTY; without even the implied warranty of              ***
#**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                    ***
#**  See the GNU Lesser General Public License for more details.             ***
#**                                                                          ***
#**  You should have received a copy of the GNU Lesser General Public License***
#**  along with this program. If not, see <http://www.gnu.org/licenses/>.    ***
#*******************************************************************************
cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
project(
	pecunia
	DESCRIPTION ${Pecunia_DESCRIPTION}
	VERSION ${Pecunia_VERSION}
	HOMEPAGE_URL ${Pecunia_HOMEPAGE_URL}
	LANGUAGES CXX
)

configure_file(
	"${CMAKE_CURRENT_SOURCE_DIR}/config.hpp.in"
	"${PROJECT_BINARY_DIR}/internal/config.hpp"
)
configure_file(
	"${CMAKE_CURRENT_SOURCE_DIR}/Sizes.hpp.in"
	"${PROJECT_BINARY_DIR}/external/${PROJECT_NAME}/Sizes.hpp"
)
configure_file(
	"${CMAKE_CURRENT_SOURCE_DIR}/SizesInternal.hpp.in"
	"${PROJECT_BINARY_DIR}/internal/Sizes.hpp"
)

set(${PROJECT_NAME}_PUBLIC_DECLARATIONS
	external/${PROJECT_NAME}/Algorithm.hpp
	external/${PROJECT_NAME}/Codes.h
	external/${PROJECT_NAME}/Conversion.h
	external/${PROJECT_NAME}/Errors.h
	external/${PROJECT_NAME}/Expected.hpp
	external/${PROJECT_NAME}/FloatingPoint.h
	external/${PROJECT_NAME}/Manip.h
	external/${PROJECT_NAME}/Math.h
	external/${PROJECT_NAME}/Money.h
	"${PROJECT_BINARY_DIR}/external/${PROJECT_NAME}/${PROJECT_NAME}_export.h"
	external/${PROJECT_NAME}/Rounders.h
	external/${PROJECT_NAME}/Information.h
	external/${PROJECT_NAME}/SetUp.h
	external/${PROJECT_NAME}/Splitter.h
	"${PROJECT_BINARY_DIR}/external/${PROJECT_NAME}/Sizes.hpp"
	external/${PROJECT_NAME}/Types.h
)
set(${PROJECT_NAME}_PUBLIC_DEFINITIONS
	external/${PROJECT_NAME}/Algorithm.hpp
	external/${PROJECT_NAME}/Codes.cpp
	external/${PROJECT_NAME}/Conversion.cpp
	external/${PROJECT_NAME}/Errors.cpp
	external/${PROJECT_NAME}/Expected.hpp
	external/${PROJECT_NAME}/FloatingPoint.cpp
	external/${PROJECT_NAME}/Information.cpp
	external/${PROJECT_NAME}/Manip.cpp
	external/${PROJECT_NAME}/Math.cpp
	external/${PROJECT_NAME}/Money.cpp
	"${PROJECT_BINARY_DIR}/external/${PROJECT_NAME}/${PROJECT_NAME}_export.h"
	external/${PROJECT_NAME}/Rounders.cpp
	external/${PROJECT_NAME}/SetUp.cpp
	external/${PROJECT_NAME}/Splitter.cpp
	"${PROJECT_BINARY_DIR}/external/${PROJECT_NAME}/Sizes.hpp"
	external/${PROJECT_NAME}/Types.cpp
)
set(${PROJECT_NAME}_PRIVATE_DECLARATIONS
	internal/Adjustments.h
	internal/Attributes.hpp
	internal/BackTrace.h
	internal/config.hpp
	internal/ManipIndex.h
	internal/TraceCapture.h
	internal/Verification.h
)
set(${PROJECT_NAME}_PRIVATE_DEFINITIONS
	internal/Adjustments.cpp
	internal/Attributes.hpp
	internal/config.hpp
	internal/ManipIndex.cpp
	internal/TraceCapture.cpp
	internal/Verification.cpp
)

if (LINUX)
	message(STATUS "Using GNU/Linux specific source code.")
	set(${PROJECT_NAME}_OS_PRIVATE_DECLARATIONS
	)
	set(${PROJECT_NAME}_OS_PRIVATE_DEFINITIONS
		internal/linux/BackTrace.cpp
	)
elseif (WIN32)
	message(STATUS "Using Microsoft Windows specific source code.")
	set(${PROJECT_NAME}_OS_PRIVATE_DECLARATIONS
		internal/windows/DebugSymbols.h
	)
	set(${PROJECT_NAME}_OS_PRIVATE_DEFINITIONS
		internal/windows/BackTrace.cpp
		internal/windows/DebugSymbols.cpp
	)
else ()
	message(FATAL_ERROR "OS specific files not specified.")
endif ()

add_library(${PROJECT_NAME}
	${Pecunia_LIBRARY_TYPE}
	${${PROJECT_NAME}_PUBLIC_DEFINITIONS}
	${${PROJECT_NAME}_PRIVATE_DEFINITIONS}
	${${PROJECT_NAME}_PUBLIC_DECLARATIONS}
	${${PROJECT_NAME}_PRIVATE_DECLARATIONS}
	${${PROJECT_NAME}_OS_PUBLIC_DECLARATIONS}
	${${PROJECT_NAME}_OS_PRIVATE_DEFINITIONS}
)
target_include_directories(${PROJECT_NAME}
	PUBLIC
		$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external>
	PRIVATE
		$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
		$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
		$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/external>
)
if (WIN32)
	message(STATUS "Using Microsoft Windows specific libraries.")
	target_link_libraries(${PROJECT_NAME}
		PUBLIC Dbghelp
	)
endif ()

set_target_properties(${PROJECT_NAME} PROPERTIES
	VERSION ${PROJECT_VERSION}
	SOVERSION ${PROJECT_VERSION_MAJOR}
	LINKER_LANGUAGE CXX
	COMPATIBLE_INTERFACE_STRING ${PROJECT_VERSION_MAJOR}
)
set_property(TARGET ${PROJECT_NAME} PROPERTY INTERFACE_${PROJECT_NAME}_MAJOR_VERSION ${PROJECT_VERSION_MAJOR})

include(GenerateExportHeader)
generate_export_header(${PROJECT_NAME}
	EXPORT_FILE_NAME "${PROJECT_BINARY_DIR}/external/${PROJECT_NAME}/${PROJECT_NAME}_export.h"
)

if (Pecunia_ENABLE_TESTS)
	add_subdirectory(unit-tests)
endif (Pecunia_ENABLE_TESTS)

install(
	TARGETS ${PROJECT_NAME}
	EXPORT ${PROJECT_NAME}Targets
	RUNTIME DESTINATION bin
	COMPONENT Library
	LIBRARY DESTINATION ${Pecunia_LIBRARY_INSTALL_DIR}
	COMPONENT Library
	ARCHIVE DESTINATION ${Pecunia_LIBRARY_INSTALL_DIR}
	COMPONENT Devel
	INCLUDES DESTINATION include
	COMPONENT Devel
)
install(
	FILES ${${PROJECT_NAME}_PUBLIC_DECLARATIONS}
	DESTINATION include/${PROJECT_NAME}
	COMPONENT Devel
)
if (WIN32)
	install(
		FILES $<TARGET_PDB_FILE:${PROJECT_NAME}>
		DESTINATION bin
		COMPONENT Debug
	)
endif(WIN32)

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
	${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Version.cmake
	VERSION ${PROJECT_VERSION}
	COMPATIBILITY SameMajorVersion
)
export(EXPORT ${PROJECT_NAME}Targets
	FILE ${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Targets.cmake
)
configure_file(
	${PROJECT_NAME}Config.cmake.in
	"${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake"
	@ONLY
)
install(
	EXPORT ${PROJECT_NAME}Targets
	FILE ${PROJECT_NAME}Targets.cmake
	DESTINATION ${Pecunia_LIBRARY_INSTALL_DIR}/cmake/${PROJECT_NAME}
	COMPONENT Devel
)
install(
	FILES
		${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake
		${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Version.cmake
	DESTINATION ${Pecunia_LIBRARY_INSTALL_DIR}/cmake/${PROJECT_NAME}
	COMPONENT Devel
)

if (NOT TARGET uninstall)
	configure_file(
		"${CMAKE_CURRENT_SOURCE_DIR}/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
	)
endif()

set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README")
set(CPACK_PACKAGE_CHECKSUM SHA256)
set(CPACK_PACKAGE_VENDOR "John M. Schneiderman")
set(CPACK_PACKAGE_CONTACT "John Schneiderman <packaging@schneiderman.me>")
set(CPACK_THREADS 6)
set(PACKAGE_DESCRIPTION "C++ library for working with currencies using the ISO-4217 currency codes.\nThe monetary representation is stored as a fixed memory size. Every\nmaths operation is validated to be safe, and any operation between different\ncurrencies is seamlessly convertible."
)
set(CPACK_COMPONENT_Devel_DEPENDS Library)
set(CPACK_COMPONENT_Debug_DEPENDS Library)

if (LINUX)
	set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/pkg/icon.png")
	set(CPACK_RPM_PACKAGE_DESCRIPTION "${PACKAGE_DESCRIPTION}")
	set(CPACK_RPM_PACKAGE_RELEASE "${Pecunia_PACKAGE_RELEASE}")
	set(CPACK_RPM_PACKAGE_GROUP "Development/C++")
	set(CPACK_RPM_PACKAGE_LICENSE "LGPLv3+")
	set(CPACK_RPM_COMPONENT_INSTALL ON)
	set(CPACK_RPM_PACKAGE_RELEASE_DIST ON)
	set(CPACK_RPM_PACKAGE_AUTOREQPROV ON)
	set(CPACK_RPM_CHANGELOG_FILE "${CMAKE_SOURCE_DIR}/ChangeLog")
	set(CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX "/usr/${PROJECT_NAME}")
	set(CPACK_RPM_Runtime_DEBUGINFO_PACKAGE ON)
	set(CPACK_RPM_Development_PACKAGE_REQUIRES "${PROJECT_NAME}-Runtime")

	set(CPACK_DEBIAN_PACKAGE_RELEASE "${Pecunia_PACKAGE_RELEASE}")
	set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "${PACKAGE_DESCRIPTION}")
	set(CPACK_DEB_COMPONENT_INSTALL ON)
	set(CPACK_DEBIAN_ENABLE_COMPONENT_DEPENDS ON)
	set(CPACK_DEBIAN_PACKAGE_SECTION "libs")
	set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
	set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON)
	set(CPACK_DEBIAN_ENABLE_COMPONENT_DEPENDS ON)
	set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
	set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON)
	set(CPACK_DEBIAN_Development_PACKAGE_DEPENDS "${PROJECT_NAME}-runtime")
	set(CPACK_DEBIAN_Development_PACKAGE_ARCHITECTURE "all")
elseif (WIN32)
	set(CPACK_PACKAGE_INSTALL_DIRECTORY "Pecunia")
	set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/pkg\\\\${PROJECT_NAME}.ico")
	set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/pkg\\\\${PROJECT_NAME}.ico")
endif ()
include(CPack)

#{ Set-up package dependencies

cpack_add_component_group(Runtime
	DISPLAY_NAME "Runtime Files"
	DESCRIPTION "All files needed to run an application using Pecunia."
	EXPANDED
)
cpack_add_component_group(Development
	DISPLAY_NAME "Development Files"
	DESCRIPTION "All files supporting development with Pecunia."
)
cpack_add_component(Library
	DISPLAY_NAME "C++ Libraries"
	DESCRIPTION "${PACKAGE_DESCRIPTION}"
	REQUIRED
	GROUP Runtime
)
cpack_add_component(Devel
	DISPLAY_NAME "C++ Headers"
	DESCRIPTION "All the development header files for C++. Also, provides the files for\nusing Pecunia with CMake."
	DEPENDS Library
	DISABLED
	GROUP Development
)
cpack_add_component(Debug
	DISPLAY_NAME "Debug Symbols"
	DESCRIPTION "Files needed for debugging and, on Windows, generating stack-traces."
	DEPENDS Library
	DISABLED
	GROUP Development
)

#}

