# Define the Fortran compiler
FC = nagfor

# Compiler Options
FFLAGS_DEBUG := -g -gline -C
FFLAGS_RELEASE := -O2

# Linker Options
# examples
# LDFLAGS_DEBUG := -L/path/to/debug/libs -lmylibd
# LDFLAGS_RELEASE := -L/path/to/release/libs -lmylib
LDFLAGS_DEBUG :=
LDFLAGS_RELEASE :=

# Source directory
SRC_DIR := src

# Read project name from settings
PROJECT_NAME := $(shell python scripts/read_settings.py projectName NagFortranProjectTemplate)

# Read build mode from settings
BUILD_MODE := $(shell python scripts/read_settings.py buildMode release)

# Set build directory, executable name, and flags based on build mode
ifeq ($(BUILD_MODE),debug)
    BUILD_DIR := build_debug
    DEP_FILE := $(BUILD_DIR)/dependencies.mk
    EXE := $(BUILD_DIR)/$(PROJECT_NAME)Debug.exe
    FFLAGS := $(FFLAGS_DEBUG)
    LDFLAGS := $(LDFLAGS_DEBUG)
else
    BUILD_DIR := build_release
    DEP_FILE := $(BUILD_DIR)/dependencies.mk
    EXE := $(BUILD_DIR)/$(PROJECT_NAME)Release.exe
    FFLAGS := $(FFLAGS_RELEASE)
    LDFLAGS := $(LDFLAGS_RELEASE)
endif

# Set directory commands based on the operating system
ifeq ($(OS),Windows_NT)
    MKDIR = mkdir
    RMDIR = rmdir /S /Q
else
    MKDIR = mkdir -p
    RMDIR = rm -rf
endif

# Find source files
SRCS_F90 := $(wildcard $(SRC_DIR)/*.f90)
SRCS_F := $(wildcard $(SRC_DIR)/*.f)

# Generate object file names from source files
OBJS := $(patsubst $(SRC_DIR)/%.f90, $(BUILD_DIR)/%.o, $(SRCS_F90))
OBJS += $(patsubst $(SRC_DIR)/%.f, $(BUILD_DIR)/%.o, $(SRCS_F))

# Declare phony targets
.PHONY: all clean run depend

# Dependency file
DEP_FILE := $(BUILD_DIR)/dependencies.mk

# Set conditional commands based on the operating system
ifeq ($(OS),Windows_NT)
    DEP_CHECK_CMD := if not exist "$(DEP_FILE)" "$(MAKE)" depend
    CREATE_BUILD_DIR_CMD := if not exist "$(BUILD_DIR)" $(MKDIR) "$(BUILD_DIR)"
    REMOVE_BUILD_DIR_CMD := if exist "$(BUILD_DIR)" $(RMDIR) "$(BUILD_DIR)"
else
    DEP_CHECK_CMD := test -f $(DEP_FILE) || $(MAKE) depend
    CREATE_BUILD_DIR_CMD := test -d $(BUILD_DIR) || $(MKDIR) $(BUILD_DIR)
    REMOVE_BUILD_DIR_CMD := if [ -d "$(BUILD_DIR)" ]; then $(RMDIR) "$(BUILD_DIR)"; fi

endif

dep-all:
	@$(DEP_CHECK_CMD)
	$(MAKE) all

# Build the main executable
all: $(EXE)

# Rule to build the executable
$(EXE): $(OBJS)
	$(CREATE_BUILD_DIR_CMD)
	$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $^

# Rules to compile Fortran module and object files
$(BUILD_DIR)/%.mod: $(SRC_DIR)/%.f90
	$(CREATE_BUILD_DIR_CMD)
	$(FC) $(FFLAGS) -I$(BUILD_DIR) -mdir $(BUILD_DIR) -c $< -o $(BUILD_DIR)/$*.o

$(BUILD_DIR)/%.o: $(SRC_DIR)/%.f90
	$(CREATE_BUILD_DIR_CMD)
	$(FC) $(FFLAGS) -I$(BUILD_DIR) -mdir $(BUILD_DIR) -c $< -o $@

$(BUILD_DIR)/%.o: $(SRC_DIR)/%.f
	$(CREATE_BUILD_DIR_CMD)
	$(FC) $(FFLAGS) -I$(BUILD_DIR) -mdir $(BUILD_DIR) -c $< -o $@

# Run the compiled program
run: dep-all
	./$(EXE)

# Clean the build directory
clean:
	$(REMOVE_BUILD_DIR_CMD)

# Display current project settings
show_info:
	@echo Project Name: $(PROJECT_NAME)
	@echo Build Mode: $(BUILD_MODE)
	@echo Build Directory: $(BUILD_DIR)
	@echo Exe File: $(EXE)
	@echo Dependencies File: $(DEP_FILE)
	@echo Source Files: $(SRCS_F90) $(SRCS_F)

# Set build mode to debug
set_debug_mode:
	@python scripts/write_settings.py buildMode debug

# Set build mode to release
set_release_mode:
	@python scripts/write_settings.py buildMode release

# Change project name
change_project_name:
	python scripts/change_project_name.py

# Generate dependencies
depend:
	$(CREATE_BUILD_DIR_CMD)
	$(FC) =depend -otype=make $(FFLAGS) $(SRCS_F90) $(SRCS_F) | python scripts/transform_dependencies.py --build_dir=$(BUILD_DIR) > $(DEP_FILE)

# Include the dependency file
-include $(DEP_FILE)
