# ==============================================================================
# DIRECTORIES
# ==============================================================================
DIR_ROOT       := $(dir $(abspath $(MAKEFILE_LIST)))
DIR_SOURCES    := $(addprefix $(DIR_ROOT), source/)
DIR_BIN        := $(DIR_ROOT)

# ==============================================================================
# TARGET NAMES
# ==============================================================================
ifeq ($(OS),Windows_NT)
    TARGET_NAME    := $(shell powershell -Command "$$line = Get-Content CMakeLists.txt | Where-Object {$$_ -match '^project'}; if ($$line -match 'project\s*\x28(\w+)') { $$matches[1] }")
    LONG_NAME      := $(shell powershell -Command "$$line = Get-Content CMakeLists.txt | Where-Object {$$_ -match 'PROJECT_LONG_NAME'}; if ($$line -match '\"(.+)\"') { $$matches[1] }")
else
    TARGET_NAME    := $(shell awk '/^project/ {gsub(/[)(]/, " "); print $$2}' CMakeLists.txt)
    LONG_NAME      := $(shell grep 'PROJECT_LONG_NAME' CMakeLists.txt | sed 's/.*"\(.*\)".*/\1/')
endif

TARGET_FILE    := $(DIR_BIN)$(TARGET_NAME)
RELEASE_FOLDER := $(TARGET_NAME)_release
RELEASE_FILE   := $(RELEASE_FOLDER)/$(TARGET_NAME)

# ==============================================================================
# VERSION
# ==============================================================================
ifeq ($(OS),Windows_NT)
    VERSION := v$(shell powershell -Command "$$line = Get-Content CMakeLists.txt | Where-Object {$$_ -match '^project'}; if ($$line -match 'VERSION\s+([0-9.]+)') { $$matches[1] }")
else
    VERSION := v$(shell grep "^project" CMakeLists.txt | tr -cd 0-9.)
endif

# ==============================================================================
# SOURCE FILES
# ==============================================================================
APP_SOURCES := \
    source/main.cpp \
    source/core/system/director.cpp \
    source/core/system/global_events.cpp \
    source/core/rendering/sdl_manager.cpp \
    source/core/rendering/line_renderer.cpp \
    source/core/rendering/color_oscillator.cpp \
    source/core/rendering/polygon_renderer.cpp \
    source/core/rendering/primitives.cpp \
    source/core/rendering/shape_renderer.cpp \
    source/core/graphics/shape.cpp \
    source/core/graphics/shape_loader.cpp \
    source/core/graphics/vector_text.cpp \
    source/game/options.cpp \
    source/game/escenes/escena_logo.cpp \
    source/game/escenes/escena_joc.cpp \
    source/game/entities/nau.cpp \
    source/game/entities/bala.cpp \
    source/game/entities/enemic.cpp \
    source/game/effects/debris_manager.cpp

# ==============================================================================
# INCLUDES
# ==============================================================================
INCLUDES := -Isource -Ibuild

# ==============================================================================
# COMPILER FLAGS (OS-specific)
# ==============================================================================
CPP_STANDARD := c++20

ifeq ($(OS),Windows_NT)
    # Windows (MinGW)
    FixPath         = $(subst /,\\,$1)
    CXX             := g++
    CXXFLAGS        := -std=$(CPP_STANDARD) -Wall -O2 -ffunction-sections -fdata-sections \
                       -Wl,--gc-sections -static-libstdc++ -static-libgcc \
                       -Wl,-subsystem,windows -DWINDOWS_BUILD
    CXXFLAGS_DEBUG  := -std=$(CPP_STANDARD) -Wall -g -D_DEBUG -DWINDOWS_BUILD
    LDFLAGS         := -lmingw32 -lSDL3
    WINDRES         := windres
    RESOURCE_FILE   := release/orni.res
    RM              := del /Q
    RMDIR           := rmdir /S /Q
    MKDIR           := mkdir
else
    # Unix-like systems (Linux/macOS)
    FixPath         = $1
    CXX             := g++
    CXXFLAGS        := -std=$(CPP_STANDARD) -Wall -O2
    CXXFLAGS_DEBUG  := -std=$(CPP_STANDARD) -Wall -g -D_DEBUG
    LDFLAGS         := -lSDL3
    RMFILE          := rm -f
    RMDIR           := rm -rf
    MKDIR           := mkdir -p

    UNAME_S         := $(shell uname -s)
    ifeq ($(UNAME_S),Linux)
        CXXFLAGS    += -DLINUX_BUILD
        CXXFLAGS_DEBUG += -DLINUX_BUILD
    endif
    ifeq ($(UNAME_S),Darwin)
        CXXFLAGS    += -arch arm64 -Wno-deprecated -DMACOS_BUILD
        CXXFLAGS_DEBUG += -arch arm64 -Wno-deprecated -DMACOS_BUILD
    endif
endif

# ==============================================================================
# TARGETS
# ==============================================================================
.PHONY: all clean debug help backup

# Default target
all: $(TARGET_FILE)

# Generate build/project.h from template
.PHONY: generate_project_h
generate_project_h:
	@$(MKDIR) build 2>/dev/null || true
	@echo "Generating build/project.h..."
ifeq ($(OS),Windows_NT)
	@powershell -Command \
		"$$name = '$(TARGET_NAME)'; \
		$$long = '$(LONG_NAME)'; \
		$$ver = '$(VERSION)'.TrimStart('v'); \
		$$copy = (Get-Content CMakeLists.txt | Where-Object {$$_ -match 'PROJECT_COPYRIGHT'} | ForEach-Object {if ($$_ -match '\"(.+)\"') {$$matches[1]}}); \
		$$hash = try {git rev-parse --short=7 HEAD 2>$$null} catch {'unknown'}; \
		(Get-Content source/project.h.in) -replace '@PROJECT_NAME@', $$name -replace '@PROJECT_LONG_NAME@', $$long -replace '@PROJECT_VERSION@', $$ver -replace '@PROJECT_COPYRIGHT@', $$copy -replace '@GIT_HASH@', $$hash | Set-Content build/project.h"
else
	@PROJECT_COPYRIGHT=$$(grep 'PROJECT_COPYRIGHT' CMakeLists.txt | sed 's/.*"\(.*\)".*/\1/'); \
	PROJECT_VERSION=$$(echo $(VERSION) | sed 's/^v//'); \
	GIT_HASH=$$(git rev-parse --short=7 HEAD 2>/dev/null || echo "unknown"); \
	sed -e "s/@PROJECT_NAME@/$(TARGET_NAME)/g" \
	    -e "s/@PROJECT_LONG_NAME@/$(LONG_NAME)/g" \
	    -e "s/@PROJECT_VERSION@/$${PROJECT_VERSION}/g" \
	    -e "s/@PROJECT_COPYRIGHT@/$${PROJECT_COPYRIGHT}/g" \
	    -e "s/@GIT_HASH@/$${GIT_HASH}/g" \
	    source/project.h.in > build/project.h
endif
	@echo "build/project.h generated successfully"

# Compile executable
$(TARGET_FILE): generate_project_h $(APP_SOURCES)
ifeq ($(OS),Windows_NT)
	@if not exist build $(MKDIR) build
	@if not exist release\\orni.res $(WINDRES) release\\orni.rc -O coff -o release\\orni.res
	$(CXX) $(CXXFLAGS) $(INCLUDES) $(APP_SOURCES) $(RESOURCE_FILE) $(LDFLAGS) -o $(TARGET_FILE).exe
else
	@$(MKDIR) build
	$(CXX) $(CXXFLAGS) $(INCLUDES) $(APP_SOURCES) $(LDFLAGS) -o $(TARGET_FILE)
endif
	@echo Compilation successful: $(TARGET_FILE)

# Debug build
debug: generate_project_h $(APP_SOURCES)
ifeq ($(OS),Windows_NT)
	@if not exist build $(MKDIR) build
	$(CXX) $(CXXFLAGS_DEBUG) $(INCLUDES) $(APP_SOURCES) $(LDFLAGS) -o $(TARGET_FILE)_debug.exe
else
	@$(MKDIR) build
	$(CXX) $(CXXFLAGS_DEBUG) $(INCLUDES) $(APP_SOURCES) $(LDFLAGS) -o $(TARGET_FILE)_debug
endif
	@echo Debug build successful: $(TARGET_FILE)_debug

# Clean build artifacts
clean:
ifeq ($(OS),Windows_NT)
	@if exist $(call FixPath,$(TARGET_FILE).exe) $(RM) $(call FixPath,$(TARGET_FILE).exe)
	@if exist $(call FixPath,$(TARGET_FILE)_debug.exe) $(RM) $(call FixPath,$(TARGET_FILE)_debug.exe)
	@if exist build $(RMDIR) build
	@if exist $(RELEASE_FOLDER) $(RMDIR) $(RELEASE_FOLDER)
else
	@$(RMFILE) $(TARGET_FILE)
	@$(RMFILE) $(TARGET_FILE)_debug
	@$(RMDIR) build
	@$(RMDIR) $(RELEASE_FOLDER)
endif
	@echo Clean complete

# Backup to remote server
backup:
	@echo "Backing up project to maverick:/home/sergio/git-backup/asteroids..."
	rsync -a --delete \
		--exclude='build/' \
		--exclude='*.o' \
		--exclude='*.exe' \
		--exclude='orni' \
		--exclude='orni_debug' \
		--exclude='*_release/' \
		$(DIR_ROOT) maverick:/home/sergio/git-backup/asteroids/
	@echo "Backup completed successfully"

# Help target
help:
	@echo "Available targets:"
	@echo "  all           - Build the game (default)"
	@echo "  debug         - Build with debug symbols"
	@echo "  clean         - Remove build artifacts"
	@echo "  backup        - Backup project to remote server"
	@echo "  help          - Show this help message"
	@echo ""
	@echo "Current configuration:"
	@echo "  Target:       $(TARGET_NAME)"
	@echo "  Version:      $(VERSION)"
	@echo "  Platform:     $(UNAME_S)"
	@echo "  C++ Standard: $(CPP_STANDARD)"
