cmake_minimum_required(VERSION 3.16)
project(animia LANGUAGES CXX)
set(SRC_FILES
	# any non-platform-specific files go here
	src/animia.cc
	src/player.cc
	src/util.cc
	src/strategist.cc
	src/fd.cc
	src/win.cc
)

include(CheckLanguage)

set(LIBRARIES)
set(INCLUDE_DIRS)
set(DEFINES)

if(APPLE)
	list(APPEND DEFINES MACOSX)
	list(APPEND SRC_FILES
		# xnu stuff
		src/fd/xnu.cc
		src/util/osx.cc
	)

	include(CheckIncludeFile)
	check_include_file("CoreFoundation/CoreFoundation.h" HAVE_COREFOUNDATION)
	# If you're building on OS X, you most likely do have this file, but we
	# check anyway.
	if(HAVE_COREFOUNDATION)
		list(APPEND DEFINES HAVE_COREFOUNDATION)
		find_library(OBJC_LIBRARY objc)

		if(NOT OBJC_LIBRARY)
			message(STATUS "Found CoreFoundation/CoreFoundation.h, but not the Objective-C runtime. How?")
		endif()

		list(APPEND SRC_FILES src/win/quartz.cc)

		find_library(FOUNDATION_LIBRARY Foundation)
		find_library(COREGRAPHICS_LIBRARY CoreGraphics)
		find_library(APPKIT_LIBRARY AppKit)
		list(APPEND LIBRARIES ${FOUNDATION_LIBRARY} ${COREGRAPHICS_LIBRARY} ${APPKIT_LIBRARY} ${OBJC_LIBRARY})
	else() # NOT HAVE_COREFOUNDATION
		message(STATUS "You don't have Core Foundation. How? What kind of voodoo magic did you do to cause this?")
		message(WARNING "LaunchServices support will not be compiled.")
	endif() # HAVE_COREFOUNDATION
elseif(WIN32)
	list(APPEND DEFINES WIN32)
	list(APPEND SRC_FILES
		# win32
		src/fd/win32.cc
		src/win/win32.cc
		src/util/win32.cc
	)
else() # NOT WIN32 AND NOT APPLE
	find_library(LIBUTIL_LIBRARY util)
	find_library(LIBKVM_LIBRARY kvm)

	if(LINUX)
		list(APPEND DEFINES LINUX)
		list(APPEND SRC_FILES src/fd/proc.cc)
	elseif(LIBUTIL_LIBRARY) # FreeBSD's libutil
		get_filename_component(LIBUTIL_DIR ${LIBUTIL_LIBRARY} DIRECTORY)

		include(CheckLibraryExists)
		check_library_exists(util kinfo_getfile ${LIBUTIL_DIR} LIBUTIL_GOOD)

		if(LIBUTIL_GOOD)
			list(APPEND LIBRARIES ${LIBUTIL_LIBRARY})
			list(APPEND DEFINES LIBUTIL)
			list(APPEND SRC_FILES src/fd/libutil.cc)
		endif() # LIBUTIL_GOOD
	elseif(LIBKVM_LIBRARY) # OpenBSD kvm
		list(APPEND LIBRARIES ${LIBKVM_LIBRARY})
		list(APPEND DEFINES LIBKVM)
		list(APPEND SRC_FILES src/fd/kvm.cc)

		get_filename_component(LIBKVM_DIR ${LIBKVM_LIBRARY} DIRECTORY)

		include(CheckLibraryExists)
		check_library_exists(kvm kvm_getfiles ${LIBKVM_DIR} LIBKVM_HAS_GETFILES)

		if(LIBKVM_HAS_GETFILES)
			list(APPEND DEFINES HAVE_KVM_GETFILES)
		endif() # LIBKVM_HAS_GETFILES
	endif() # LINUX

	# X11
	find_package(X11 COMPONENTS X11 XRes)

	if(X11_FOUND)
		# Getting PIDs from windows...
		if (X11_XRes_FOUND)
			list(APPEND DEFINES HAVE_XRES)
		else() # NOT X11_XRes_FOUND
			message(WARNING "libXRes could not be found! Finding PIDs in X11 windows may not work correctly!")
		endif() # X11_XRes_FOUND

		list(APPEND DEFINES X11)
		list(APPEND SRC_FILES src/win/x11.cc)
		list(APPEND INCLUDE_DIRS ${X11_INCLUDE_DIRS})
		list(APPEND LIBRARIES ${X11_LIBRARIES}) # This will include Xres, I think..
	else() # NOT X11_FOUND
		# For some systems, i.e. Debian, FindX11 fails to find X11, so we have
		# to use pkg_config as a fallback
		find_package(PkgConfig)
		if(PKG_CONFIG_FOUND)
			pkg_check_modules(X11 x11)
			if(X11_FOUND)
				# Check for XRes the hard way
				find_path(X11_XRes_HEADER "X11/extensions/XRes.h" PATHS ${X11_INCLUDE_DIRS})
				find_library(X11_XRes_LIB XRes PATHS ${X11_LIBRARY_DIRS})

				if(X11_XRes_HEADER AND X11_XRes_LIB)
					# TODO: We should REALLY check for XResQueryClientIds here...
					list(APPEND DEFINES HAVE_XRES)
					list(APPEND LIBRARIES ${X11_XRes_LIB})
				else()
					message(WARNING "libXRes could not be found! Finding PIDs in X11 windows may not work correctly!")
				endif()

				list(APPEND DEFINES X11)
				list(APPEND SRC_FILES src/win/x11.cc)
				list(APPEND INCLUDE_DIRS ${X11_INCLUDE_DIRS})
				list(APPEND LIBRARIES ${X11_LINK_LIBRARIES})
			endif() # X11_FOUND
		endif() # PKG_CONFIG_FOUND
	endif() # X11_FOUND

	find_package(PkgConfig)
	if(PKG_CONFIG_FOUND)
		pkg_check_modules(WAYLAND wayland-client)
		if(WAYLAND_FOUND)
			enable_language(C)
			list(APPEND DEFINES WAYLAND)
			list(APPEND SRC_FILES
				src/win/wayland.cc
				src/win/wayland/ext-foreign-toplevel-list-v1.c
			)
			list(APPEND INCLUDE_DIRS ${WAYLAND_INCLUDE_DIRS})
			list(APPEND LIBRARIES ${WAYLAND_LINK_LIBRARIES})
		endif() # WAYLAND_FOUND
	endif() # PKG_CONFIG_FOUND
endif() # WIN32 AND APPLE

add_library(animia SHARED ${SRC_FILES})
set_target_properties(animia PROPERTIES
	PUBLIC_HEADER include/animia.h
	CXX_STANDARD 17
)

target_compile_definitions(animia PRIVATE ${DEFINES})
target_include_directories(animia PUBLIC include PRIVATE ${INCLUDE_DIRS})
target_link_libraries(animia PUBLIC ${LIBRARIES})
