cmake_minimum_required(VERSION 3.23)
project(minori LANGUAGES CXX VERSION 0.1.0)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")

option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
option(USE_QT6 "Force build with Qt 6" OFF)
option(USE_QT5 "Force build with Qt 5" OFF)
option(UPDATE_TRANSLATIONS "Update *.ts translation files" OFF)

add_subdirectory(dep/animone)
add_subdirectory(dep/anitomy)

# Fix for mingw64
list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".a")

if(USE_QT6 AND USE_QT5)
	message(FATAL_ERROR "Can't build with Qt 5 and Qt 6 at the same time...")
elseif(USE_QT6)
	set(QT_VERSION_MAJOR 6)
elseif(USE_QT5)
	set(QT_VERSION_MAJOR 5)
else()
	find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
endif()

find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets LinguistTools Xml)

# find_package(CURL) is dysfunctional
find_package(PkgConfig REQUIRED)
pkg_check_modules(CURL REQUIRED libcurl)
pkg_check_modules(UTF8PROC libutf8proc)
pkg_check_modules(FMT fmt)

message("${FMT_LINK_LIBRARIES}")

if(NOT UTF8PROC_FOUND)
	add_subdirectory(dep/utf8proc)
endif()

if(NOT FMT_FOUND)
	add_subdirectory(dep/fmt)
endif()

set(LIBRARIES
	${Qt${QT_VERSION_MAJOR}Widgets_LIBRARIES}
	${Qt${QT_VERSION_MAJOR}Xml_LIBRARIES}
	${CURL_LINK_LIBRARIES}
	anitomy
	animia
)

if(UTF8PROC_FOUND)
	list(APPEND LIBRARIES ${UTF8PROC_LINK_LIBRARIES})
else()
	list(APPEND LIBRARIES utf8proc)
endif()

if(FMT_FOUND)
	list(APPEND LIBRARIES ${FMT_LINK_LIBRARIES})
else()
	list(APPEND LIBRARIES fmt)
endif()

set(QT_MOC_FILES
	include/core/http.h
	include/core/session.h
	include/gui/dialog/about.h
	include/gui/dialog/dialog.h
	include/gui/dialog/licenses.h
	include/gui/dialog/information.h
	include/gui/dialog/settings.h
	include/gui/pages/anime_list.h
	include/gui/pages/history.h
	include/gui/pages/now_playing.h
	include/gui/pages/search.h
	include/gui/pages/seasons.h
	include/gui/pages/statistics.h
	include/gui/pages/torrents.h
	include/gui/translate/anilist.h
	include/gui/translate/anime.h
	include/gui/translate/config.h
	include/gui/widgets/anime_button.h
	include/gui/widgets/anime_info.h
	include/gui/widgets/clickable_label.h
	include/gui/widgets/drop_list_widget.h
	include/gui/widgets/graph.h
	include/gui/widgets/optional_date.h
	include/gui/widgets/poster.h
	include/gui/widgets/sidebar.h
	include/gui/widgets/text.h
	include/gui/widgets/elided_label.h
	include/gui/locale.h
	include/gui/theme.h
	include/gui/window.h
)

set(SRC_FILES
	# Main entrypoint
	src/main.cc

	# Core files and datatype declarations...
	src/core/anime.cc
	src/core/anime_db.cc
	src/core/anime_season.cc
	src/core/byte_stream.cc
	src/core/config.cc
	src/core/date.cc
	src/core/filesystem.cc
	src/core/http.cc
	src/core/json.cc
	src/core/session.cc
	src/core/strings.cc
	src/core/time.cc

	# Main window
	src/gui/window.cc
	src/gui/theme.cc
	src/gui/locale.cc

	# Main window pages
	src/gui/pages/anime_list.cc
	src/gui/pages/now_playing.cc
	src/gui/pages/statistics.cc
	src/gui/pages/search.cc
	src/gui/pages/seasons.cc
	src/gui/pages/torrents.cc
	src/gui/pages/history.cc

	# Custom widgets
	src/gui/widgets/anime_button.cc
	src/gui/widgets/anime_info.cc
	src/gui/widgets/clickable_label.cc
	src/gui/widgets/drop_list_widget.cc
	src/gui/widgets/elided_label.cc
	src/gui/widgets/poster.cc
	src/gui/widgets/sidebar.cc
	src/gui/widgets/text.cc
	src/gui/widgets/optional_date.cc

	# Dialogs
	src/gui/dialog/about.cc
	src/gui/dialog/dialog.cc
	src/gui/dialog/licenses.cc
	src/gui/dialog/information.cc
	src/gui/dialog/settings.cc
	src/gui/dialog/settings/application.cc
	src/gui/dialog/settings/services.cc
	src/gui/dialog/settings/torrents.cc
	src/gui/dialog/settings/recognition.cc
	src/gui/dialog/settings/library.cc

	# Translate
	src/gui/translate/anime.cc
	src/gui/translate/anilist.cc
	src/gui/translate/config.cc

	# Services
	src/services/services.cc
	src/services/anilist.cc
	src/services/kitsu.cc

	# Library
	src/library/library.cc

	# Tracking
	src/track/media.cc

	# Qt resources
	rc/icons/icons.qrc
	rc/sys/win32/dark/dark.qrc
	rc/animone.qrc
	rc/licenses.qrc
)

set(INCLUDE
	${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS}
	${Qt${QT_VERSION_MAJOR}Xml_INCLUDE_DIRS}
	${CURL_INCLUDE_DIRS}
	include
	dep/animia/include
	dep/anitomy
	dep
)

if(UTF8PROC_FOUND)
	list(APPEND INCLUDE ${UTF8PROC_INCLUDE_DIRS})
else()
	list(APPEND INCLUDE dep/utf8proc)
endif()

if(FMT_FOUND)
	list(APPEND INCLUDE ${FMT_INCLUDE_DIRS})
else()
	list(APPEND INCLUDE dep/fmt/include)
endif()

set(TS_FILES
	rc/locale/en_GB.ts
)

set(DEFINES)

list(APPEND DEFINES MINORI_VERSION_MAJOR=${minori_VERSION_MAJOR})
list(APPEND DEFINES MINORI_VERSION_MINOR=${minori_VERSION_MINOR})
list(APPEND DEFINES MINORI_VERSION_PATCH=${minori_VERSION_PATCH})

###########################################################################
# moc

cmake_language(CALL qt${QT_VERSION_MAJOR}_wrap_cpp SRC_FILES ${QT_MOC_FILES})

###########################################################################
# Translations

set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/rc/locale")

if(UPDATE_TRANSLATIONS)
	cmake_language(CALL qt${QT_VERSION_MAJOR}_create_translation ${SRC_FILES} ${TS_FILES} OPTIONS "-tr-function-alias tr+=Translate -I${CMAKE_CURRENT_SOURCE_DIR}/include")
endif()
cmake_language(CALL qt${QT_VERSION_MAJOR}_add_translation QM_FILES ${TS_FILES})
list(APPEND SRC_FILES ${QM_FILES})

set(LOCALE_QRC_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/rc/locale.qrc")
set(QRC "<!DOCTYPE rcc><RCC version=\"1.0\">\n\t<qresource>\n")
get_filename_component(DIR "${LOCALE_QRC_LOCATION}" DIRECTORY)
foreach (qm ${QM_FILES})
	file(RELATIVE_PATH name ${DIR} ${qm})
	string(APPEND QRC "\t\t<file>${name}</file>\n")
endforeach()
string(APPEND QRC "\t</qresource>\n</RCC>\n")
file(WRITE "${LOCALE_QRC_LOCATION}" ${QRC})

list(APPEND SRC_FILES "${LOCALE_QRC_LOCATION}")

###########################################################################
# Platform specific stuff

# Endianness
include (TestBigEndian)
TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
if(IS_BIG_ENDIAN)
	list(APPEND DEFINES BYTE_ORDER_BIG)
else()
	list(APPEND DEFINES BYTE_ORDER_LITTLE)
endif()

# This is also used in the Win32 rc file
set(RC_INFO_STRING "A lightweight anime tracker built with Qt.")

if(APPLE) # Mac OS X (or OS X (or macOS))
	set(MACOSX_BUNDLE_BUNDLE_NAME "Minori")
	set(MACOSX_BUNDLE_BUNDLE_VERSION ${minori_VERSION})
	set(MACOSX_BUNDLE_COPYRIGHT "Copyright (C) Paper 2023-2024")
	set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.eu.us.paper.minori")
	set(MACOSX_BUNDLE_INFO_STRING ${RC_INFO_STRING})

	find_library(FOUNDATION_LIBRARY Foundation)
	find_library(APPKIT_LIBRARY AppKit)
	list(APPEND SRC_FILES src/sys/osx/dark_theme.cc src/sys/osx/permissions.cc)
	list(APPEND LIBRARIES ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY})
	list(APPEND DEFINES MACOSX)
elseif(WIN32) # Windows
	configure_file(
		${CMAKE_CURRENT_SOURCE_DIR}/rc/sys/win32/version.rc.in
		${CMAKE_CURRENT_BINARY_DIR}/rc/version.rc
		@ONLY
	)
	list(APPEND SRC_FILES
		src/sys/win32/dark_theme.cc
		${CMAKE_CURRENT_BINARY_DIR}/rc/version.rc
	)
	list(APPEND DEFINES WIN32)
else()
	include(CheckSymbolExists)

	find_package(PkgConfig)
	if (PKG_CONFIG_FOUND)
		pkg_check_modules(GLIB gio-2.0 glib-2.0)
		if (GLIB_FOUND)
			list(APPEND SRC_FILES src/sys/glib/dark_theme.cc)
			list(APPEND INCLUDE ${GLIB_INCLUDE_DIRS})
			list(APPEND LIBRARIES ${GLIB_LINK_LIBRARIES})
			list(APPEND DEFINES GLIB) # XXX rename HAVE_GLIB or something
		endif()

		pkg_check_modules(XCB xcb)
		if (XCB_FOUND)
			list(APPEND SRC_FILES src/sys/x11/settings.cc src/sys/x11/dark_theme.cc)
			list(APPEND INCLUDE ${XCB_INCLUDE_DIRS})
			list(APPEND LIBRARIES ${XCB_LINK_LIBRARIES})
			list(APPEND DEFINES HAVE_XCB)
		endif()
	endif()

	check_symbol_exists(inotify_init1 "sys/inotify.h" HAVE_INOTIFY_INIT1)
	if(HAVE_INOTIFY_INIT1)
		list(APPEND DEFINES HAVE_INOTIFY_INIT1)
	endif()
	check_symbol_exists(inotify_init "sys/inotify.h" HAVE_INOTIFY)
	if(HAVE_INOTIFY)
		list(APPEND DEFINES HAVE_INOTIFY)
	endif()
endif()

###########################################################################

add_executable(minori WIN32 MACOSX_BUNDLE ${SRC_FILES})
set_property(TARGET minori PROPERTY CXX_STANDARD 17)
set_property(TARGET minori PROPERTY AUTORCC ON)

target_include_directories(minori PRIVATE ${INCLUDE})
target_link_libraries(minori PRIVATE ${LIBRARIES})
target_compile_options(minori PRIVATE -Wall -Wpedantic -Wextra -Wsuggest-override -Wold-style-cast)
target_compile_definitions(minori PRIVATE ${DEFINES})

if(APPLE)
	set_target_properties(minori PROPERTIES MACOSX_BUNDLE TRUE)
elseif(WIN32)
	install(FILES $<TARGET_RUNTIME_DLLS:minori> TYPE BIN)
endif()
