# Makefile — MDL Modcomp Diagnostic Loader
#
# Targets:
#   make              Build with ncurses and (if found) GTK4 + VTE
#   make NCURSES=0    Build without ncurses (terminal + CLI only)
#   make GTK=0        Build without GTK
#   make clean        Remove build artefacts
#   make install      Install binary, mdl.conf, diagnostic images, manual
#   make manual       Build doc/mdl_manual.pdf (needs latexmk)
#   make dist         Build mdl-VERSION.tar.bz2, a complete source distribution
#   make test         Smoke test (list files, no hardware needed)
#
# Installation directories (use the same PREFIX for make and make install;
# the data directory is compiled in as the last place mdl.conf is sought):
#   PREFIX=/usr/local  DESTDIR=  BINDIR=$(PREFIX)/bin
#   DATADIR=$(PREFIX)/share/mdl  DOCDIR=$(PREFIX)/share/doc/mdl
#

CC      = gcc
CFLAGS  = -Wall -Wextra -O2 -std=c11 -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE -MMD -MP
LDLIBS  =
PROGNAME  = mdl

PREFIX  ?= /usr/local
BINDIR  ?= $(PREFIX)/bin
DATADIR ?= $(PREFIX)/share/mdl
DOCDIR  ?= $(PREFIX)/share/doc/mdl
CFLAGS  += -DMDL_DATADIR='"$(DATADIR)"'

VERSION  = $(shell sed -n 's/.*VERSION[ \t]*"\(.*\)".*/\1/p' version.h)
DISTDIR  = $(PROGNAME)-$(VERSION)

NCURSES ?= 1
GTK     ?= 1

# Report the build configuration only when something is being built; targets
# that do not compile anything (dist, clean, manual, clangd) stay quiet
QUIET_GOALS = dist clean manual clangd
say = $(if $(filter-out $(QUIET_GOALS),$(or $(MAKECMDGOALS),all)),$(info $(1)))

ifeq ($(GTK),1)
    GTK_CFLAGS  := $(shell pkg-config --cflags gtk4 vte-2.91-gtk4 2>/dev/null)
    GTK_LIBS    := $(shell pkg-config --libs   gtk4 vte-2.91-gtk4 2>/dev/null)
    ifneq ($(GTK_CFLAGS),)
        CFLAGS  += -DHAVE_GTK $(GTK_CFLAGS)
        LDLIBS  += $(GTK_LIBS) -lm
        GTK_SRCS = ui_gtk.c
        $(call say,Building with GTK4 + VTE support)
    else
        $(call say,GTK4/VTE not found — building without GTK)
        GTK_SRCS =
    endif
else
    $(call say,Building without GTK)
    GTK_SRCS =
endif

ifeq ($(NCURSES),1)
    CFLAGS  += -DHAVE_NCURSES -DHAVE_NCURSESW $(shell pkg-config --cflags ncursesw 2>/dev/null || echo -I/usr/include/ncursesw)
    LDLIBS  += $(shell pkg-config --libs ncursesw 2>/dev/null || echo -lncursesw)
    NCURSES_SRCS = ui_interactive.c
    $(call say,Building with ncursesw support)
else
    NCURSES_SRCS =
    $(call say,Building WITHOUT ncurses)
endif

SRCS = main.c \
       ini.c \
       serial.c \
       diag.c \
       log.c \
       color.c \
       transfer.c \
       session.c \
       terminal.c \
       ui_cli.c \
       mdl_logo.c \
       $(NCURSES_SRCS) \
       $(GTK_SRCS)

# Everything a source distribution needs, whatever this build's configuration
ALL_SRCS  = $(sort $(SRCS) ui_interactive.c ui_gtk.c)
HDRS      = mdl.h version.h ui_gtk.h mdl_logo.h
DATA      = mdl.conf mdl_logo.png $(wildcard diags/*)
DOCS      = doc/mdl_manual.tex doc/diag_table.tex doc/mdl_manual.pdf
DISTFILES = Makefile $(ALL_SRCS) $(HDRS) $(DATA) $(DOCS)

OBJS = $(SRCS:.c=.o)
DEPS = $(OBJS:.o=.d)

.PHONY: all clean clangd dist install manual test FORCE

all: $(PROGNAME)

$(PROGNAME): $(OBJS)
	$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)

%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<

-include $(DEPS)

# ini.o has DATADIR compiled in: rebuild it whenever DATADIR changes
.datadir: FORCE
	@echo '$(DATADIR)' | cmp -s - $@ || echo '$(DATADIR)' > $@
ini.o: .datadir

# mdl_logo.c is generated from the PNG, but is kept under version control so
# that building does not need xxd
mdl_logo.c: mdl_logo.png
	xxd -i mdl_logo.png > mdl_logo.c

clean:
	rm -f $(OBJS) $(DEPS) $(PROGNAME) .datadir

clangd:
	bear -- make

# Only the files named in DISTFILES are copied, so .svn and build products
# never get in.  --parents keeps doc/ and diags/; -p keeps timestamps.
# mdl_logo.c is touched last so it is newer than mdl_logo.png, and
# building from the distribution never needs xxd.
dist: $(DISTFILES)
	@test -n "$(VERSION)" || { echo "Cannot read MDL_VERSION from version.h"; exit 1; }
	@rm -rf $(DISTDIR)
	@rm -f $(DISTDIR).tar.bz2
	@mkdir $(DISTDIR)
	@cp -p --parents $(DISTFILES) $(DISTDIR)
	@touch $(DISTDIR)/mdl_logo.c
	@tar -cjf $(DISTDIR).tar.bz2 $(DISTDIR)
	@rm -rf $(DISTDIR)
	@echo Distribution file $(DISTDIR).tar.bz2 created.

# The installed mdl.conf finds the images in DATADIR and logs to ~/mdl.log.
# Preferences saved from the GTK UI go to ~/.config/mdl/mdl.conf.
install: $(PROGNAME)
	install -d $(DESTDIR)$(BINDIR) $(DESTDIR)$(DATADIR)/diags $(DESTDIR)$(DOCDIR)
	install -m 0755 $(PROGNAME) $(DESTDIR)$(BINDIR)/$(PROGNAME)
	install -m 0644 diags/* $(DESTDIR)$(DATADIR)/diags/
	sed -e 's|^DiagDir=.*|DiagDir=$(DATADIR)/diags|' \
	    -e 's|^SessionLog=.*|SessionLog=~/mdl.log|' mdl.conf > $(DESTDIR)$(DATADIR)/mdl.conf
	chmod 0644 $(DESTDIR)$(DATADIR)/mdl.conf
	if [ -f doc/mdl_manual.pdf ]; then install -m 0644 doc/mdl_manual.pdf $(DESTDIR)$(DOCDIR)/; fi
	@echo "Installed $(PROGNAME) to $(DESTDIR)$(BINDIR), data to $(DESTDIR)$(DATADIR)"

manual: doc/mdl_manual.pdf

doc/mdl_manual.pdf: doc/mdl_manual.tex doc/diag_table.tex
	cd doc && latexmk -pdf -interaction=nonstopmode mdl_manual.tex

test: $(PROGNAME)
	@echo "--- List mode (no hardware needed) ---"
	./$(PROGNAME) --list
	@echo "--- Done ---"
