# Domino-Chain
#
# Domino-Chain is the legal property of its developers, whose
# names are listed in the AUTHORS file, which is included
# within the source distribution.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA

PREFIX = /usr
BINDIR = $(PREFIX)/bin
DATADIR = $(PREFIX)/share
DESTDIR =
CROSS =

BOOST_TAGS := $(if $(filter %-w64-mingw32.static-,$(CROSS)),-mt,)
CONVERT = convert
CXX = $(CROSS)$(CXX_NATIVE)
CXX_NATIVE = g++
CXXFLAGS = -Wall -Wextra -g -O2 -std=c++17
EXEEXT = $(if $(filter %-w64-mingw32.static-,$(CROSS)),.exe,)
INSTALL = install
LDFLAGS =
MSGFMT = msgfmt
MSGMERGE = msgmerge
PKG_CONFIG = $(CROSS)$(PKG_CONFIG_NATIVE)
PKG_CONFIG_NATIVE = pkg-config
PKG_LUA := $(shell $(PKG_CONFIG) --exists lua-5.2 && echo lua-5.2 || echo lua)
POVRAY = povray
XGETTEXT = xgettext

MSGID_BUGS_ADDRESS := roever@users.sf.net

.DELETE_ON_ERROR:

.PHONY: default
default: all

VERSION := $(shell cat src/version)
ALL_SOURCES := $(wildcard src/* src/*/* src/*/*/* src/*/*/*/*)

PKGS += $(PKG_LUA)
PKGS += SDL2_mixer
PKGS += SDL2_ttf
PKGS += fribidi
PKGS += libpng
PKGS += sdl2
PKGS += zlib

LIBS += -lboost_filesystem$(BOOST_TAGS)
LIBS += -lboost_system$(BOOST_TAGS)

DEFS += -DVERSION='"$(VERSION)"'
DEFS += -DDATADIR='"$(DATADIR)"'

FILES_H := $(wildcard src/domino-chain/*.h src/domino-chain/linebreak/*.h src/domino-chain/sha1/*.hpp)
FILES_CPP := $(wildcard src/domino-chain/*.cpp src/domino-chain/linebreak/*.c src/domino-chain/sha1/*.cpp)
FILES_O := $(patsubst src/domino-chain/%,_tmp/$(CROSS)domino-chain/%.o,$(FILES_CPP))
.SECONDARY: $(FILES_O)
_tmp/$(CROSS)domino-chain/%.o: src/domino-chain/% src/version $(FILES_H)
	@mkdir -p $(dir $@)
	$(CXX) $(CXXFLAGS) $$($(PKG_CONFIG) --cflags $(PKGS)) $(DEFS) -c -o $@ $<

FILES_BINDIR += $(CROSS)domino-chain$(EXEEXT)
$(CROSS)domino-chain$(EXEEXT): $(FILES_O)
	$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(FILES_O) $$($(PKG_CONFIG) --libs $(PKGS)) $(LIBS)

ASSEMBLER_PKGS += SDL2_image
ASSEMBLER_PKGS += libpng
ASSEMBLER_PKGS += sdl2

ASSEMBLER_SOURCES := src/dominoes/assembler.cpp src/dominoes/pngsaver.h
.SECONDARY: _tmp/dominoes/assembler
_tmp/dominoes/assembler: $(ASSEMBLER_SOURCES)
	@mkdir -p $(dir $@)
	$(CXX_NATIVE) $(CXXFLAGS) $(LDFLAGS) $$($(PKG_CONFIG_NATIVE) --cflags $(ASSEMBLER_PKGS)) -o $@ $< $$($(PKG_CONFIG_NATIVE) --libs $(ASSEMBLER_PKGS))

DOMINOES_SOURCES := src/dominoes/domino.ini $(wildcard src/dominoes/*.pov)
.SECONDARY: _tmp/dominoes/povray_done
_tmp/dominoes/povray_done: $(DOMINOES_SOURCES)
	@mkdir -p $(dir $@)
	$(POVRAY) $< 2>&1 | grep 'Output file'
	touch $@

ASSEMBLED_DOMINOES_SOURCES := src/dominoes/dominoes.lst $(wildcard src/dominoes/*/*.png)
FILES_DATADIR += data/domino-chain/images/dominoes.png
data/domino-chain/images/dominoes.png: _tmp/dominoes/assembler _tmp/dominoes/povray_done $(ASSEMBLED_DOMINOES_SOURCES)
	@mkdir -p $(dir $@)
	_tmp/dominoes/assembler $@ 58 2 200 src/dominoes/dominoes.lst

FILES_IMAGES_SRC := $(wildcard src/images/*.png)
FILES_DATADIR += $(patsubst src/images/%,data/domino-chain/images/%,$(FILES_IMAGES_SRC))
data/domino-chain/images/%: src/images/%
	@mkdir -p $(dir $@)
	cp $< $@

FILES_SOUNDS_SRC := $(wildcard src/sounds/*.ogg)
FILES_DATADIR += $(patsubst src/sounds/%,data/domino-chain/sounds/%,$(FILES_SOUNDS_SRC))
data/domino-chain/sounds/%: src/sounds/%
	@mkdir -p $(dir $@)
	cp $< $@

FILES_THEMES_SRC := $(wildcard src/themes/*)
FILES_DATADIR += $(patsubst src/themes/%,data/domino-chain/themes/%,$(FILES_THEMES_SRC))
data/domino-chain/themes/%: src/themes/%
	@mkdir -p $(dir $@)
	cp $< $@

FILES_PO := $(wildcard src/po/*.po)
FILES_DATADIR += $(patsubst src/po/%.po,data/locale/%/LC_MESSAGES/domino-chain.mo,$(FILES_PO))
data/locale/%/LC_MESSAGES/domino-chain.mo: src/po/%.po
	@mkdir -p $(dir $@)
	$(MSGFMT) -c -o $@ $<

FILES_DATADIR += data/icons/hicolor/16x16/apps/domino-chain.png
FILES_DATADIR += data/icons/hicolor/32x32/apps/domino-chain.png
FILES_DATADIR += data/icons/hicolor/48x48/apps/domino-chain.png
FILES_DATADIR += data/icons/hicolor/64x64/apps/domino-chain.png
data/icons/hicolor/%/apps/domino-chain.png: src/doc/domino-chain.ico
	@mkdir -p $(dir $@)
	$(CONVERT) +set date:create +set date:modify $<[$(shell expr substr $* 1 2 / 16 - 1)] $@

DOC_INCLUDES += src/doc/upload-url-dist-windows

FILES_DATADIR += data/metainfo/domino-chain.metainfo.xml
data/metainfo/domino-chain.metainfo.xml: src/doc/doc.sh $(DOC_INCLUDES)
	@mkdir -p $(dir $@)
	$< metainfo >$@

FILES_DATADIR += data/applications/domino-chain.desktop
data/applications/domino-chain.desktop: src/doc/doc.sh $(DOC_INCLUDES)
	@mkdir -p $(dir $@)
	$< desktop >$@

FILES_DATADIR += data/doc/domino-chain/html/index.html
data/doc/domino-chain/html/index.html: src/doc/doc.sh $(DOC_INCLUDES)
	@mkdir -p $(dir $@)
	$< html >$@

FILES_DATADIR += data/man/man6/domino-chain.6.gz
data/man/man6/domino-chain.6.gz: src/doc/doc.sh $(DOC_INCLUDES)
	@mkdir -p $(dir $@)
	$< man | gzip -9n >$@

README.md: src/doc/doc.sh $(DOC_INCLUDES)
	@mkdir -p $(dir $@)
	shellcheck -f gcc $<
	$< readme >$@

AUTHORS: src/doc/doc.sh $(DOC_INCLUDES)
	@mkdir -p $(dir $@)
	$< authors >$@

FILES_DATADIR += data/doc/domino-chain/html/assets/style.css
data/doc/domino-chain/html/assets/style.css: src/doc/style.css
	@mkdir -p $(dir $@)
	cp $< $@

FILES_DATADIR += data/doc/domino-chain/html/assets/domino-chain-header.jpg
data/doc/domino-chain/html/assets/domino-chain-header.jpg: src/doc/domino-chain-header.png
	@mkdir -p $(dir $@)
	$(CONVERT) -quality 85 $< $@

FILES_LEVELS_SRCDIRS := $(wildcard src/levels/*)
FILES_DATADIR += $(patsubst src/levels/%,data/domino-chain/levels/%.gz,$(FILES_LEVELS_SRCDIRS))
data/domino-chain/levels/%.gz: src/levels/%/*.level
	@mkdir -p $(dir $@)
	cat src/levels/$*/*.level | gzip -9n >$@

_tmp/po/leveltexts.cpp: src/levels/*/*.level
	@mkdir -p $(dir $@)
	sed -n '/^\(Description\|Hint\|Name\|Tutorial\)$$/,/^[^|]/ s,^| \(.*\)$$,_("\1"),p' src/levels/*/*.level | LC_ALL=C sort -u >$@

FILES_DATADIR_SYS += data/fonts/FreeSans.ttf
data/fonts/FreeSans.ttf:
	@mkdir -p $(dir $@)
	if [ -e /usr/share/fonts/truetype/freefont/FreeSans.ttf ]; then cp /usr/share/fonts/truetype/freefont/$(notdir $@) $@; \
	elif [ -e /usr/share/fonts/FreeSans.ttf ]; then cp /usr/share/fonts/$(notdir $@) $@; \
	elif [ -e /usr/share/fonts/freefont/FreeSans.ttf ]; then cp /usr/share/fonts/freefont/$(notdir $@) $@; \
	else echo 'Unable to find $(notdir $@)'; exit 1; \
	fi

.PHONY: all
all: README.md AUTHORS $(FILES_BINDIR) $(FILES_DATADIR) $(FILES_DATADIR_SYS)

.PHONY: check
check: all
	./domino-chain -c src/recordings/finish/*
	./domino-chain -y src/recordings/fail
	./domino-chain -x src/recordings/crash
	@echo OK

DIST_WINDOWS := Domino-Chain_$(VERSION)_for_Windows.zip
TARGET_WINDOWS = x86_64-w64-mingw32.static
DIST_CLEAN_FILES += $(TARGET_WINDOWS)-domino-chain.exe $(BIN_WINDOWS) $(DIST_WINDOWS)

$(DIST_WINDOWS): $(ALL_SOURCES)
	[ -e _tmp/mxe ] || git clone https://github.com/mxe/mxe.git _tmp/mxe
	cd _tmp/mxe && git pull --ff-only
	$(MAKE) -C _tmp/mxe MXE_TARGETS=$(TARGET_WINDOWS) MXE_PLUGIN_DIRS=plugins/gcc9 boost fribidi lua sdl2_mixer sdl2_ttf
	PATH=$$(pwd)/_tmp/mxe/usr/bin:$$PATH $(MAKE) -j 4 CROSS=$(TARGET_WINDOWS)-
	rm -rf _tmp/$(basename $@)
	mkdir -p _tmp/$(basename $@)
	cp $(TARGET_WINDOWS)-domino-chain.exe _tmp/$(basename $@)/Domino-Chain.exe
	PATH=$$(pwd)/_tmp/mxe/usr/bin:$$PATH $(TARGET_WINDOWS)-strip -s _tmp/$(basename $@)/Domino-Chain.exe
	tar c $(FILES_DATADIR) $(FILES_DATADIR_SYS) | tar x -C _tmp/$(basename $@)
	sed 's,assets/,data/doc/domino-chain/html/assets/,' <_tmp/$(basename $@)/data/doc/domino-chain/html/index.html >_tmp/$(basename $@)/README.html
	rm -f $@
	cd _tmp && zip -r9 ../$@ $(basename $@)
	rm -rf _tmp/$(basename $@)

.PHONY: dist
dist: $(DIST_WINDOWS)

FILES_INSTALL += $(patsubst %,$(DESTDIR)$(BINDIR)/%,$(FILES_BINDIR))
$(DESTDIR)$(BINDIR)/%: %
	$(INSTALL) -m 755 -d $(dir $@)
	$(INSTALL) -m 755 $< $@

FILES_INSTALL += $(patsubst data/%,$(DESTDIR)$(DATADIR)/%,$(FILES_DATADIR))
$(DESTDIR)$(DATADIR)/%: data/%
	$(INSTALL) -m 755 -d $(dir $@)
	$(INSTALL) -m 644 $< $@

.PHONY: install
install: $(FILES_INSTALL)

PUBLIC_SOURCES = $(filter data/doc/domino-chain/html/%,$(FILES_DATADIR))
PUBLIC_FILES = $(patsubst data/doc/domino-chain/html/%,%,$(PUBLIC_SOURCES))

.PHONY: public
public: $(PUBLIC_SOURCES)
	rm -rf $@
	$(INSTALL) -m 755 -d $(patsubst %,$@/%,$(sort $(dir $(PUBLIC_FILES))))
	for PUBLIC_FILE in $(PUBLIC_FILES); do $(INSTALL) -m 644 data/doc/domino-chain/html/$$PUBLIC_FILE public/$$PUBLIC_FILE; done

.PHONY: release
release:
	[ -e gitlab-token ]
	[ "$$(git diff | wc -c)" = 0 ]
	sed 's/~dev$$//' -i src/version
	$(MAKE) -j 4
	$(MAKE) dist
	curl --request POST --header "PRIVATE-TOKEN: $$(cat gitlab-token)" \
	  --form "file=@Domino-Chain_$$(cat src/version)_for_Windows.zip" \
	  https://gitlab.com/api/v4/projects/domino-chain%2Fdomino-chain.gitlab.io/uploads \
	  | sed -n 's/^.*"url": *"\([^"]\+\)".*$$/\1/p' \
	  >src/doc/upload-url-dist-windows
	$(MAKE) -j 4
	git commit -am "Release $$(cat src/version)"
	git tag -sm "$$(cat src/version)" "$$(cat src/version)"
	echo "1.$$(($$(sed 's/^1\.//' src/version)+1))~dev" >src/version.new
	mv src/version.new src/version
	$(MAKE) -j 4
	git commit -am "Set version to $$(cat src/version)"
	git push --tags

.PHONY: clean
clean:
	rm -f domino-chain *-domino-chain *-domino-chain.exe Domino-Chain*.zip _tmp/dominoes/assembler
	rm -rf data/ public/ _tmp/domino-chain/ _tmp/*-domino-chain/
	@echo 'Hint: Refusing to remove rendered dominoes and MXE. To remove everything, please use "make clean-all".'

.PHONY: clean-all
clean-all:
	rm -f domino-chain *-domino-chain *-domino-chain.exe Domino-Chain*.zip
	rm -rf data/ public/ _tmp/

.PHONY: update-po
update-po: _tmp/po/messages.pot
	for PO_FILE in src/po/*.po; do $(MSGMERGE) -Uq --backup=none $$PO_FILE $<; done

_tmp/po/messages.pot: _tmp/po/leveltexts.cpp src/domino-chain/*.cpp
	@mkdir -p $(dir $@)
	$(XGETTEXT) --msgid-bugs-address=$(MSGID_BUGS_ADDRESS) -cTRANSLATORS: -k_ -kN_ -o $@ $^
