# Project paths
PROJECT_ROOT := $(CURDIR)
SRC_DIR := src
SHADERS_DIR := shaders
WEB_DIR := web
THIRD_PARTY_DIR := third_party
TOOLS_DIR := tools
BUILD_DIR := build

# Tools
CC ?= cc
EMCC ?= emcc
SHDC ?= $(TOOLS_DIR)/sokol-shdc

# Sources and includes
# All C sources under src/
SOURCES := $(shell find $(SRC_DIR) -name '*.c')
INCLUDES := -I$(PROJECT_ROOT) -I$(SRC_DIR) -I$(THIRD_PARTY_DIR) -I$(THIRD_PARTY_DIR)/flecs/include

# Common C flags
CFLAGS_COMMON := -std=c99 -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers

# Shader codegen
SHADER_SRC := $(SHADERS_DIR)/triangle-sapp.glsl
SHADER_H := $(SHADERS_DIR)/triangle-sapp.glsl.h
# Generate a header supporting multiple backends so one header works everywhere
SHDC_LANGS := glsl300es

# Flecs sources/objects
FLECS_SRC := $(shell find $(THIRD_PARTY_DIR)/flecs/src -name '*.c')
FLECS_NATIVE_OBJ := $(patsubst $(THIRD_PARTY_DIR)/flecs/src/%.c,$(BUILD_DIR)/flecs_native/%.o,$(FLECS_SRC))
FLECS_WASM_OBJ := $(patsubst $(THIRD_PARTY_DIR)/flecs/src/%.c,$(BUILD_DIR)/flecs_wasm/%.o,$(FLECS_SRC))

# Default goal
.DEFAULT_GOAL := wasm

.PHONY: all wasm linux-gles3 linux-glcore macos-metal macos-glcore clean dirs check-emcc check-shdc

all: wasm

dirs:
	@mkdir -p $(BUILD_DIR)

check-emcc:
	@command -v $(EMCC) >/dev/null 2>&1 || (echo "Emscripten 'emcc' not found. Run emsdk_env.sh" && exit 1)

check-shdc:
	@test -x $(SHDC) || (echo "sokol-shdc not found at $(SHDC)" && exit 1)

$(SHADER_H): $(SHADER_SRC) | check-shdc
	@echo "[shdc] $< -> $@ (langs: $(SHDC_LANGS))"
	$(SHDC) -i $< -f sokol -o $@ -l $(SHDC_LANGS)

# Build Flecs (native)
$(BUILD_DIR)/flecs_native/%.o: $(THIRD_PARTY_DIR)/flecs/src/%.c
	@mkdir -p $(dir $@)
	$(CC) -c $< $(INCLUDES) -std=c99 -O2 -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -o $@

# Build Flecs (wasm)
$(BUILD_DIR)/flecs_wasm/%.o: $(THIRD_PARTY_DIR)/flecs/src/%.c | check-emcc
	@mkdir -p $(dir $@)
	$(EMCC) -c $< $(INCLUDES) -std=c99 -O2 -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -o $@

# ==================== WASM (WebGL2) ====================
WASM_OUT := $(BUILD_DIR)/triangle.html
WASM_CFLAGS := $(CFLAGS_COMMON) -DSOKOL_GLES3
WASM_LDFLAGS := \
	-sUSE_WEBGL2=1 -sMIN_WEBGL_VERSION=2 -sMAX_WEBGL_VERSION=2 \
	-sWASM=1 -sALLOW_MEMORY_GROWTH=1 -sASSERTIONS=1 -sNO_EXIT_RUNTIME=1 \
	-sINITIAL_MEMORY=67108864 -sMAXIMUM_MEMORY=536870912 -sSTACK_SIZE=1048576

wasm: dirs $(WASM_OUT)

$(WASM_OUT): $(SOURCES) $(SHADER_H) $(FLECS_WASM_OBJ) | check-emcc
	@echo "[emcc] $@"
	$(EMCC) $(SOURCES) $(FLECS_WASM_OBJ) $(INCLUDES) $(WASM_CFLAGS) \
		--shell-file $(WEB_DIR)/shell_fullscreen.html \
		-o $@ \
		$(WASM_LDFLAGS)
	@echo "WASM built: $@ (open with emrun or http server)"

# ==================== Linux: GLES3 ====================
LINUX_GLES3_OUT := $(BUILD_DIR)/triangle-linux-gles3
LINUX_GLES3_CFLAGS := $(CFLAGS_COMMON) -DSOKOL_GLES3 -D_POSIX_C_SOURCE=199309L -pthread
LINUX_GLES3_LDFLAGS := -lGLESv2 -lEGL -lX11 -lXi -lXcursor -ldl -pthread -lm

linux-gles3: dirs $(LINUX_GLES3_OUT)

$(LINUX_GLES3_OUT): $(SOURCES) $(SHADER_H) $(FLECS_NATIVE_OBJ)
	@echo "[cc] $@"
	$(CC) $(SOURCES) $(FLECS_NATIVE_OBJ) $(INCLUDES) $(LINUX_GLES3_CFLAGS) -o $@ $(LINUX_GLES3_LDFLAGS)
	@echo "Linux GLES3 built: $@"

# ==================== Linux: GL Core 3.3 ====================
LINUX_GLCORE_OUT := $(BUILD_DIR)/triangle-linux-glcore
LINUX_GLCORE_CFLAGS := $(CFLAGS_COMMON) -DSOKOL_GLCORE33 -D_POSIX_C_SOURCE=199309L -pthread
LINUX_GLCORE_LDFLAGS := -lGL -lX11 -lXi -lXcursor -ldl -pthread -lm

linux-glcore: dirs $(LINUX_GLCORE_OUT)

$(LINUX_GLCORE_OUT): $(SOURCES) $(SHADER_H) $(FLECS_NATIVE_OBJ)
	@echo "[cc] $@"
	$(CC) $(SOURCES) $(FLECS_NATIVE_OBJ) $(INCLUDES) $(LINUX_GLCORE_CFLAGS) -o $@ $(LINUX_GLCORE_LDFLAGS)
	@echo "Linux GLCore built: $@"

# ==================== macOS: Metal ====================
MACOS_METAL_OUT := $(BUILD_DIR)/triangle-macos-metal
MACOS_METAL_CFLAGS := $(CFLAGS_COMMON) -DSOKOL_METAL -x objective-c -fobjc-arc
MACOS_METAL_LDFLAGS := -framework Cocoa -framework QuartzCore -framework Metal -framework MetalKit

macos-metal: dirs $(MACOS_METAL_OUT)

$(MACOS_METAL_OUT): $(SOURCES) $(SHADER_H) $(FLECS_NATIVE_OBJ)
	@echo "[cc] $@"
	$(CC) $(SOURCES) $(FLECS_NATIVE_OBJ) $(INCLUDES) $(MACOS_METAL_CFLAGS) -o $@ $(MACOS_METAL_LDFLAGS)
	@echo "macOS Metal built: $@"

# ==================== macOS: GL Core 3.3 ====================
MACOS_GLCORE_OUT := $(BUILD_DIR)/triangle-macos-glcore
MACOS_GLCORE_CFLAGS := $(CFLAGS_COMMON) -DSOKOL_GLCORE33 -x objective-c -fobjc-arc
MACOS_GLCORE_LDFLAGS := -framework Cocoa -framework QuartzCore -framework OpenGL

macos-glcore: dirs $(MACOS_GLCORE_OUT)

$(MACOS_GLCORE_OUT): $(SOURCES) $(SHADER_H) $(FLECS_NATIVE_OBJ)
	@echo "[cc] $@"
	$(CC) $(SOURCES) $(FLECS_NATIVE_OBJ) $(INCLUDES) $(MACOS_GLCORE_CFLAGS) -o $@ $(MACOS_GLCORE_LDFLAGS)
	@echo "macOS GLCore built: $@"

clean:
	@rm -rf $(BUILD_DIR)
	@rm -f triangle triangle-linux-gles3 triangle.html triangle.js triangle.wasm
	@echo "Cleaned $(BUILD_DIR) and old root artifacts"
