# ArtCube - Production Makefile

RGB_LIB_DISTRIBUTION := ../rpi-rgb-led-matrix
RGB_INCDIR           := $(RGB_LIB_DISTRIBUTION)/include
RGB_LIBDIR           := $(RGB_LIB_DISTRIBUTION)/lib
RGB_LIBRARY_NAME     := rgbmatrix

CXX                  := g++
STD                  := -std=c++17

# ---- Version stamping ----
VERSION              ?= 1.0.0
GIT_COMMIT           := $(shell git rev-parse --short HEAD 2>/dev/null || echo "nogit")
BUILD_DATE           := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")

DEFINES              := -DINFOCUBE_VERSION=\"$(VERSION)\" \
                        -DINFOCUBE_GIT_COMMIT=\"$(GIT_COMMIT)\" \
                        -DINFOCUBE_BUILD_DATE=\"$(BUILD_DATE)\"

# ---- Common flags ----
WARNFLAGS            := -Wall -Wextra -Wshadow -Wconversion -Wno-psabi
INCLUDES             := -I$(RGB_INCDIR)

# libs used by most apps
LIBS_COMMON          := -L$(RGB_LIBDIR) -l$(RGB_LIBRARY_NAME) -lrt -lm -lpthread

# extra libs used by specific apps
LIBS_JPEG            := -ljpeg
LIBS_CURL            := -lcurl

# ---- Build modes ----
MODE                 ?= release

ifeq ($(MODE),debug)
  OPTFLAGS           := -O0 -g3 -DDEBUG
  STRIP              :=
  OUTDIR             := build/debug
else
  OPTFLAGS           := -Ofast -fomit-frame-pointer -DNDEBUG
  STRIP              := strip
  OUTDIR             := build/release
endif

CXXFLAGS             := $(STD) $(WARNFLAGS) $(OPTFLAGS) $(INCLUDES) $(DEFINES)

BIN_DIR              := bin

# ---- Apps ----
#APPS                 := infocube globe life matrixcube faceid solarcube
APPS                 := infocube globe solarcube galaxycube matrixcube life faceid bannercube

all: prep $(APPS)

prep:
	@mkdir -p $(OUTDIR) $(BIN_DIR)

# ---- Pattern rule for objects ----
# Ensure output directories exist even when building a single target like: make faceid
$(OUTDIR)/%.o: %.cc | prep
	$(CXX) $(CXXFLAGS) -c $< -o $@

# ---- InfoCube ----
# InfoCube now uses the shared cube_orientation module, so link it in here.
INFOCUBE_SRCS := infocube.cc cube_orientation.cc weather.cc calendar.cc
INFOCUBE_OBJS := $(patsubst %.cc,$(OUTDIR)/%.o,$(INFOCUBE_SRCS))

infocube: $(INFOCUBE_OBJS) $(OUTDIR)/cube_orientation.o
	$(CXX) $(CXXFLAGS) $^ -o $(BIN_DIR)/$@ $(LIBS_COMMON) $(LIBS_CURL)
	@if [ -n "$(STRIP)" ]; then $(STRIP) $(BIN_DIR)/$@; fi
	@echo "Built $(BIN_DIR)/$@ ($(MODE))"

# ---- Globe ----
globe: $(OUTDIR)/globe.o
	$(CXX) $(CXXFLAGS) $^ -o $(BIN_DIR)/$@ $(LIBS_COMMON) $(LIBS_JPEG)
	@if [ -n "$(STRIP)" ]; then $(STRIP) $(BIN_DIR)/$@; fi
	@echo "Built $(BIN_DIR)/$@ ($(MODE))"

# ---- Life ----
life: $(OUTDIR)/life.o
	$(CXX) $(CXXFLAGS) $^ -o $(BIN_DIR)/$@ $(LIBS_COMMON)
	@if [ -n "$(STRIP)" ]; then $(STRIP) $(BIN_DIR)/$@; fi
	@echo "Built $(BIN_DIR)/$@ ($(MODE))"

# ---- SolarCube ----
solarcube: $(OUTDIR)/solarcube.o $(OUTDIR)/cube_orientation.o
	$(CXX) $(CXXFLAGS) $^ -o $(BIN_DIR)/$@ $(LIBS_COMMON)
	@if [ -n "$(STRIP)" ]; then $(STRIP) $(BIN_DIR)/$@; fi
	@echo "Built $(BIN_DIR)/$@ ($(MODE))"

# ---- GalaxyCube ----
galaxycube: $(OUTDIR)/galaxycube.o $(OUTDIR)/cube_orientation.o
	$(CXX) $(CXXFLAGS) $^ -o $(BIN_DIR)/$@ $(LIBS_COMMON)
	@if [ -n "$(STRIP)" ]; then $(STRIP) $(BIN_DIR)/$@; fi
	@echo "Built $(BIN_DIR)/$@ ($(MODE))"

# ---- MatrixCube ----
# If your matrix source file name is matrixcube.cc, this works as-is.
# If it's matrix_polar_cube.cc or something else, change the source name here.
matrixcube: $(OUTDIR)/matrixcube.o $(OUTDIR)/cube_orientation.o
	$(CXX) $(CXXFLAGS) $^ -o $(BIN_DIR)/$@ $(LIBS_COMMON)
	@if [ -n "$(STRIP)" ]; then $(STRIP) $(BIN_DIR)/$@; fi
	@echo "Built $(BIN_DIR)/$@ ($(MODE))"

# ---- BannerCube ----
# If your matrix source file name is bannercube.cc, this works as-is.
# If it's matrix_polar_cube.cc or something else, change the source name here.
bannercube: $(OUTDIR)/bannercube.o $(OUTDIR)/cube_orientation.o
	$(CXX) $(CXXFLAGS) $^ -o $(BIN_DIR)/$@ $(LIBS_COMMON) -ljpeg
	@if [ -n "$(STRIP)" ]; then $(STRIP) $(BIN_DIR)/$@; fi
	@echo "Built $(BIN_DIR)/$@ ($(MODE))"

# ---- FaceID ----
# If your face ID program is named faceid.cc, this works as-is.
# If it's face_id.cc, rename the file or change the rule accordingly.
faceid: $(OUTDIR)/face_id.o $(OUTDIR)/cube_orientation.o
	$(CXX) $(CXXFLAGS) $^ -o $(BIN_DIR)/$@ $(LIBS_COMMON)
	@if [ -n "$(STRIP)" ]; then $(STRIP) $(BIN_DIR)/$@; fi
	@echo "Built $(BIN_DIR)/$@ ($(MODE))"

# Alias: allow 'make face_id' (prevents implicit link rule without libs)
face_id: faceid
	@true

clean:
	rm -rf build bin

.PHONY: all prep clean $(APPS)
