# gKeyMapper - Build
# Dependencies: g++, pkg-config, msgfmt, libgtk-4-dev, libusb-1.0-0-dev, libxkbcommon-dev
# Installation: sudo apt install build-essential gettext libgtk-4-dev libusb-1.0-0-dev libxkbcommon-dev

CXX ?= g++
CXXFLAGS ?= -std=c++17 -O2 -Wall -Wextra -Wpedantic
PKG_CONFIG ?= pkg-config
MSGFMT ?= msgfmt

GTK_CFLAGS := $(shell $(PKG_CONFIG) --cflags gtk4)
GTK_LIBS   := $(shell $(PKG_CONFIG) --libs gtk4)
USB_CFLAGS := $(shell $(PKG_CONFIG) --cflags libusb-1.0)
USB_LIBS   := $(shell $(PKG_CONFIG) --libs libusb-1.0)
XKB_CFLAGS := $(shell $(PKG_CONFIG) --cflags xkbcommon)
XKB_LIBS   := $(shell $(PKG_CONFIG) --libs xkbcommon)

PACKAGE    := gkeymapper
TARGET     := gkeymapper
DAEMON     := gkeymapper-daemon
SRC_DIR    := src
SHARED_DIR := shared
DAEMON_DIR := daemon
GUI_SOURCES    := $(wildcard $(SRC_DIR)/*.cpp) $(wildcard $(SHARED_DIR)/*.cpp)
GUI_HEADERS    := $(wildcard $(SRC_DIR)/*.h) $(wildcard $(SHARED_DIR)/*.h)
DAEMON_SOURCES := $(wildcard $(DAEMON_DIR)/*.cpp) $(wildcard $(SHARED_DIR)/*.cpp)
DAEMON_HEADERS := $(wildcard $(DAEMON_DIR)/*.h) $(wildcard $(SHARED_DIR)/*.h)
PREFIX     ?= /usr/local
BINDIR     := $(PREFIX)/bin
LOCALEDIR  := $(PREFIX)/share/locale
ASSETS_DIR := $(PREFIX)/share/$(PACKAGE)/assets
UDEV_DIR   := $(PREFIX)/lib/udev/rules.d
MODULES_DIR := $(PREFIX)/lib/modules-load.d
UNIT_DIR   := $(PREFIX)/lib/systemd/user

CXXFLAGS += -DPACKAGE=\"$(PACKAGE)\" -DLOCALEDIR=\"$(LOCALEDIR)\" -DASSETS_DIR=\"$(ASSETS_DIR)\"
CXXFLAGS += -I$(SHARED_DIR)

# Translations
PO_FILES := $(wildcard po/*.po)
LANGS    := $(patsubst po/%.po,%,$(PO_FILES))
MO_FILES := $(patsubst %,locale/%/LC_MESSAGES/$(PACKAGE).mo,$(LANGS))

.PHONY: all clean run install translations daemon

all: $(TARGET) translations $(DAEMON)

$(TARGET): $(GUI_SOURCES) $(GUI_HEADERS)
	$(CXX) $(CXXFLAGS) $(GTK_CFLAGS) $(XKB_CFLAGS) -o $@ $(GUI_SOURCES) $(GTK_LIBS) $(XKB_LIBS)

daemon: $(DAEMON)

$(DAEMON): $(DAEMON_SOURCES) $(DAEMON_HEADERS)
	$(CXX) $(CXXFLAGS) $(USB_CFLAGS) $(XKB_CFLAGS) -o $@ $(DAEMON_SOURCES) $(USB_LIBS) $(XKB_LIBS)

translations: $(MO_FILES)

locale/%/LC_MESSAGES/$(PACKAGE).mo: po/%.po
	@mkdir -p $(@D)
	$(MSGFMT) -o $@ $<

run: $(TARGET) translations
	GKEYMAPPER_LOCALEDIR=$(CURDIR)/locale GKEYMAPPER_ASSETS_DIR=$(CURDIR)/assets ./$(TARGET)

clean:
	rm -f $(TARGET) $(DAEMON)
	rm -rf locale

install: $(TARGET) $(DAEMON) translations
	install -d $(DESTDIR)$(BINDIR)
	install -m 755 $(TARGET) $(DESTDIR)$(BINDIR)/$(TARGET)
	install -m 755 $(DAEMON) $(DESTDIR)$(BINDIR)/$(DAEMON)
	install -d $(DESTDIR)$(ASSETS_DIR)
	install -m 644 assets/* $(DESTDIR)$(ASSETS_DIR)/
	install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/256x256/apps
	install -m 644 assets/icon.png $(DESTDIR)$(PREFIX)/share/icons/hicolor/256x256/apps/$(PACKAGE).png
	install -d $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps
	install -m 644 assets/icon.svg $(DESTDIR)$(PREFIX)/share/icons/hicolor/scalable/apps/$(PACKAGE).svg
	-command -v gtk-update-icon-cache >/dev/null && gtk-update-icon-cache -q -t $(DESTDIR)$(PREFIX)/share/icons/hicolor 2>/dev/null || true
	install -d $(DESTDIR)$(PREFIX)/share/applications
	install -m 644 data/gkeymapper.desktop $(DESTDIR)$(PREFIX)/share/applications/$(PACKAGE).desktop
	-command -v update-desktop-database >/dev/null && update-desktop-database $(DESTDIR)$(PREFIX)/share/applications 2>/dev/null || true
	for lang in $(LANGS); do \
		install -d $(DESTDIR)$(LOCALEDIR)/$$lang/LC_MESSAGES; \
		install -m 644 locale/$$lang/LC_MESSAGES/$(PACKAGE).mo \
			$(DESTDIR)$(LOCALEDIR)/$$lang/LC_MESSAGES/$(PACKAGE).mo; \
	done
	# udev: access to the vendor interface and /dev/uinput without root.
	install -d $(DESTDIR)$(UDEV_DIR)
	install -m 644 data/60-gkeymapper.rules $(DESTDIR)$(UDEV_DIR)/60-gkeymapper.rules
	# Kernel module needed for the virtual keyboard.
	install -d $(DESTDIR)$(MODULES_DIR)
	install -m 644 data/gkeymapper-uinput.conf $(DESTDIR)$(MODULES_DIR)/$(PACKAGE).conf
	# systemd user unit (@BINDIR@ is substituted with the configured PREFIX).
	install -d $(DESTDIR)$(UNIT_DIR)
	sed 's|@BINDIR@|$(BINDIR)|g' data/$(DAEMON).service > $(DESTDIR)$(UNIT_DIR)/$(DAEMON).service
	chmod 644 $(DESTDIR)$(UNIT_DIR)/$(DAEMON).service
	-command -v udevadm >/dev/null && udevadm control --reload-rules 2>/dev/null || true
	-systemctl --user daemon-reload 2>/dev/null || true
	@echo
	@echo "Installed. Enable the daemon in your user session with:"
	@echo "  systemctl --user daemon-reload"
	@echo "  systemctl --user enable --now $(DAEMON)"
