find_headers = $(shell find src/$(1) -type f -name '*.h' )
find_assets = $(shell find src/$(1) -type f \(  -name "*.vert" -o -name "*.frag" -o -name "*.geom" -o -name "*.comp" \) )

HEADERS_src_l1 := $(call find_headers,l1)
#HEADERS_gen_l1 := $(HEADERS_src_l1) gen/l1/dorothy.txt
HEADERS_gen_l1 := gen/l1/dorothy.txt

HEADERS_src_l1_5 = $(HEADERS_gen_l1) $(call find_headers,l1_5)
#HEADERS_gen_l1_5 := $(HEADERS_src_l1_5) gen/l1_5/dorothy.txt
HEADERS_gen_l1_5 := gen/l1_5/dorothy.txt

ASSETS_src_l_adele = $($call find_assets,l_adele)
ASSETS_gen_l_adele = gen/l_adele/dorothy.txt

HEADERS_src_l2 := $(HEADERS_gen_l1_5) $(call find_headers,l2)
#HEADERS_gen_l2 := $(HEADERS_src_l2) gen/l2/dorothy.txt
HEADERS_gen_l2 := gen/l2/dorothy.txt

cflags := -Wall -Wextra -Werror=implicit-function-declaration -Werror=return-type -Wno-unused-parameter \
				--std=c99 -g -ggdb -O0 \
				-fno-trapping-math -D_POSIX_C_SOURCE=200112L -D_GNU_SOURCE
cc := gcc

wl_protocols := $(shell pkg-config --variable=pkgdatadir wayland-protocols)
libpipewire_flags := $(shell pkg-config --cflags --libs libpipewire-0.3)

xdg_shell_private_c := gen/l_wl_protocols/xdg-shell-private.c
xdg_shell_client_h := gen/l_wl_protocols/xdg-shell-client.h
xdg_shell_private_o := out/l_wl_protocols/xdg-shell-private.o

l_wl_protocols := $(xdg_shell_client_h) $(xdg_shell_private_c)

$(xdg_shell_private_o): $(l_wl_protocols)
	mkdir -p out/l_wl_protocols
	$(cc) $(cflags) -o $@ -c $(xdg_shell_private_c) -lwayland-client

out/l1/codegen: src/l1/anne/codegen.c $(HEADERS_src_l1)
	mkdir -p out/l1
	$(cc) $(cflags) -D PROTOTYPE1_L1_CODEGEN_BOOTSTRAP_USE_CHICKEN_VECU8 -o $@ $<

gen/l1/dorothy.txt: out/l1/codegen
	mkdir -p gen
	cd gen && ../out/l1/codegen

out/l1_4/t0: src/l1_4/tests/t0.c $(HEADERS_gen_l1)
	mkdir -p out/l1_4
	$(cc) $(cflags) -o $@ $<

out/l1_4/t1: src/l1_4/tests/t1.c $(HEADERS_gen_l1)
	mkdir -p out/l1_4
	$(cc) $(cflags) -o $@ $<


out/l1_5/codegen: src/l1_5/anne/codegen.c $(HEADERS_src_l1_5)
	mkdir -p out/l1_5
	$(cc) $(cflags) -o $@ $<

gen/l1_5/dorothy.txt: out/l1_5/codegen
	mkdir -p gen
	cd gen && ../out/l1_5/codegen

gen/l_wl_protocols/xdg-shell-client.h: $(wl_protocols)/stable/xdg-shell/xdg-shell.xml
	mkdir -p gen/l_wl_protocols
	wayland-scanner client-header $< $@

gen/l_wl_protocols/xdg-shell-private.c: $(wl_protocols)/stable/xdg-shell/xdg-shell.xml
	mkdir -p gen/l_wl_protocols
	wayland-scanner private-code $< $@

.PHONY: gen/l_wl_protocols
gen/l_wl_protocols : $(l_wl_protocols)

out/l2/codegen: src/l2/anne/codegen.c $(HEADERS_src_l2)
	mkdir -p out/l2
	$(cc) $(cflags) -o $@ $< -lm -lpng

gen/l2/dorothy.txt: out/l2/codegen
	mkdir -p gen
	cd gen && ../out/l2/codegen

# First argument is path (relative to src/l_adele), second argument is a name of shader files in shader folder
compile_vert_shader = glslc -o gen/l_adele/$(1)/vert.spv src/l_adele/$(1)/$(2).vert
compile_frag_shader = glslc -o gen/l_adele/$(1)/frag.spv src/l_adele/$(1)/$(2).frag

define compile_shader
mkdir -p gen/l_adele/$(1)
$(call compile_vert_shader,$(1),$(2))
$(call compile_frag_shader,$(1),$(2))
endef

gen/l_adele/dorothy.txt: $(ASSETS_src_l_adele)
	$(call compile_shader,lucy,lucy)
	$(call compile_shader,alice/0gen,0gen)
	$(call compile_shader,alice/0sh,0sh)
	$(call compile_shader,alice/1,1)
	touch gen/l_adele/dorothy.txt

out/l2/t0: src/l2/tests/data_structures/t0.c $(HEADERS_gen_l1_5)
	mkdir -p out/l2
	$(cc) $(cflags) -o $@ $<

.PHONY: run_l2_t0
run_l2_t0: out/l2/t0
	cd src/l2/tests/data_structures && ../../../../out/l2/t0


out/l2/r1: src/l2/tests/r1/r1.c $(HEADERS_src_l2) $(l_wl_protocols)
	mkdir -p out/l2
	$(cc) $(cflags) -o $@ $< $(xdg_shell_private_c) -lwayland-client -lrt -lxkbcommon -lm

.PHONY: run_r1
run_r1: out/l2/r1
	./out/l2/r1


out/l2/r2: src/l2/tests/r2/r2a.c $(HEADERS_src_l2) $(l_wl_protocols)
	mkdir -p out/l2
	$(cc) $(cflags) -o $@ $< $(xdg_shell_private_c) -lwayland-client -lrt -lxkbcommon -lm $(libpipewire_flags)

.PHONY: run_r2
run_r2: out/l2/r2
	./out/l2/r2

out/l2/r3: src/l2/tests/r3/r3.c $(HEADERS_src_l2) $(l_wl_protocols)
	mkdir -p out/l2
	$(cc) $(cflags) -o $@ $< $(xdg_shell_private_c) -lwayland-client -lrt -lxkbcommon -lm -lvulkan

.PHONY: run_r3
run_r3: out/l2/r3
	./out/l2/r3

# Whoever needs this will also need out/l_wl_protocols
out/l2/allie.o: src/l2/allie/allie.c $(HEADERS_src_l2) $(xdg_shell_client_h) gen/l_adele/dorothy.txt $(HEADERS_gen_l2)
	mkdir -p out/l2
	$(cc) $(cflags) -o $@ -c $< -lvulkan -lm -lxkbcommon -lwayland-client -lpng -lfreetype

full_allie_obj := out/l2/allie.o $(xdg_shell_private_o)

out/l3/r4: src/l3/r4/R4.hs src/l2/allie/Allie.hs $(full_allie_obj)
	mkdir -p out/l3
	ghc -isrc/l2/allie -hidir out/l3/ -odir out/l3 -o $@ $< $(full_allie_obj) \
	-lvulkan -lm -lxkbcommon -lwayland-client -lpng -lfreetype

.PHONY: run_r4
run_r4: out/l3/r4
	./out/l3/r4

.PHONY: clean
clean:
	rm -rf gen out