#
# menger - visualization of the Menger sponge
# Copyright (C) 1995-2026  Joachim Reichel <joachim.reichel@posteo.de>
#
# 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 2 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 Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

# USE_DEBUG := 1
USE_GLEW    := 1
USE_PNG     := 1
USE_JPEG    := 1

ifdef USE_DEBUG
  CXXFLAGS  +=-g
else
  CXXFLAGS  +=-O3 -DNDEBUG
endif

CXXFLAGS    += -std=c++20 -fPIC
CXXFLAGS    += -Wall -Wextra -Wformat-security -Wlogical-op -Wold-style-cast -Wno-deprecated-enum-enum-conversion
CXXFLAGS    += -DMENGER_PACKAGE=\"$(NAME)\" -DMENGER_VERSION=\"$(VERSION)\"
LDFLAGS     += -fPIC

QT_MOC = qtchooser -run-tool=moc -qt=5
CXXFLAGS    += -I/usr/include/qt5 -I/usr/include/x86_64-linux-gnu/qt5 -DHAVE_QT
LDFLAGS     += -lQt5Widgets -lQt5Gui -lQt5OpenGL -lQt5Core -lGLU -lGL

ifdef USE_GLEW
  CXXFLAGS  += -DHAVE_GLEW
  LDFLAGS   += -lGLEW
endif

ifdef USE_PNG
  CXXFLAGS  += -DHAVE_PNG
  LDFLAGS   += -lpng
endif

ifdef USE_JPEG
  CXXFLAGS  += -DHAVE_JPEG
  LDFLAGS   += -ljpeg
endif

CLANG_TIDY_CHECKS     = bugprone-*,cppcoreguidelines-*,misc-*,modernize-*,performance-*,readability-*
CLANG_TIDY_EXCEPTIONS += -cppcoreguidelines-pro-bounds-array-to-pointer-decay
CLANG_TIDY_EXCEPTIONS += -cppcoreguidelines-pro-bounds-constant-array-index
CLANG_TIDY_EXCEPTIONS += -cppcoreguidelines-pro-bounds-pointer-arithmetic
CLANG_TIDY_EXCEPTIONS += -readability-braces-around-statements
CLANG_TIDY_EXCEPTIONS += -readability-else-after-return
CLANG_TIDY_EXCEPTIONS += -readability-implicit-bool-conversion
# False positives
CLANG_TIDY_EXCEPTIONS += -cppcoreguidelines-pro-type-member-init
CLANG_TIDY_EXCEPTIONS += -misc-unused-parameters

.SUFFIXES:

.SECONDARY:

.PHONY: default check clean

SOURCES_C = $(wildcard *.c)

SOURCES_CXX = $(wildcard *.cpp)

HEADERS = $(wildcard *.h)

CHECK_HEADERS = $(HEADERS)

TARGETS = \
  menger \

OBJECTS = \
  menger.cpp.o \
  glwidget.cpp.o \
  glwidget.moc.cpp.o \
  mainwindow.cpp.o \
  mainwindow.moc.cpp.o \
  tile_rendering.cpp.o \
  renderer.cpp.o

QUIET = $(if $(quiet),@echo "  $1	$(if $2,$2,$@)";,)
VERY_QUIET = $(if $(quiet),@,)

NULL  =
SPACE = $(NULL) #
COMMA = ,

default: $(TARGETS)

all: $(TARGETS) check

menger: $(OBJECTS)
	$(call QUIET,LD)$(CXX) -o $@ $^ $(LDFLAGS)

%.c.o: %.c Makefile
	$(call QUIET,CC)$(CC) -o $@ -c $< $(CFLAGS) -MD -MF $@.d

%.cpp.o: %.cpp Makefile
	$(call QUIET,CXX)$(CXX) -o $@ -c $< $(CXXFLAGS) -MD -MF $@.d

%.moc.cpp: %.h
	$(QT_MOC) -o $@ $<

-include $(SOURCES_C:.c=.c.o.d)
-include $(SOURCES_CXX:.cpp=.cpp.o.d)

STANDALONE_HEADER_TEST_SOURCES := \
  $(addprefix test_standalone_header_, $(addsuffix .cpp, $(CHECK_HEADERS)))

MINMAX_HEADER_TEST_SOURCES := \
  $(addprefix test_minmax_header_, $(addsuffix .cpp, $(CHECK_HEADERS)))

$(STANDALONE_HEADER_TEST_SOURCES):test_standalone_header_%.cpp:
	@echo "#include <$*>" >$@

$(MINMAX_HEADER_TEST_SOURCES):test_minmax_header_%.cpp:
	@echo "#define min(a,b) dummy_min" > $@
	@echo "#define max(a,b) dummy_max" >>$@
	@echo "#include <$*>" >>$@

STANDALONE_HEADER_TEST_OBJECTS := $(STANDALONE_HEADER_TEST_SOURCES:.cpp=.o)

MINMAX_HEADER_TEST_OBJECTS := $(MINMAX_HEADER_TEST_SOURCES:.cpp=.o)

$(STANDALONE_HEADER_TEST_OBJECTS):%.o:%.cpp
	$(call QUIET,CXX)$(CXX) -o $@ -c $< $(CXXFLAGS) -I.
	$(call VERY_QUIET)rm -f $@ $<

$(MINMAX_HEADER_TEST_OBJECTS):%.o:%.cpp
	$(call QUIET,CXX)$(CXX) -o $@ -c $< $(CXXFLAGS) -I.
	$(call VERY_QUIET)rm -f $@ $<

check: default $(STANDALONE_HEADER_TEST_OBJECTS) $(MINMAX_HEADER_TEST_OBJECTS)

clean::
	rm -f test_standalone_header_* test_minmax_header_*

tidy:
	clang-tidy --checks=$(CLANG_TIDY_CHECKS),$(subst $(SPACE),$(COMMA),$(CLANG_TIDY_EXCEPTIONS)) \
	  $(filter-out %.moc.cpp, $(filter-out tile_rendering.cpp, $(wildcard *.cpp))) -- \
	  -I. $(CXXFLAGS) -x cpp -std=c++20 >clang-tidy.out || /bin/true
	grep -Eo "\[[a-zA-Z0-9\.,-]+\]" clang-tidy.out | grep -- - | sort | uniq -c | sort -n -r

clean::
	rm -f clang-tidy.out

clean::
	rm -f *~ *.o *.d $(TARGETS) *.moc.cpp
