#################################################
# @PACKAGE_STRING@
# @configure_input@
#################################################

@SET_MAKE@
SHELL = /bin/sh

#################################################
# Standard definitions
#################################################

prefix      ?= @prefix@
exec_prefix ?= @exec_prefix@
datarootdir ?= @datarootdir@
datadir     ?= @datadir@
# project root-dir (directory of configure script)
top_srcdir  ?= @top_srcdir@
# project src-dir (directory of the current Makefile)
srcdir      ?= @srcdir@

# file-type suffix of executables (e.g. ".exe" in windows)
EXEEXT ?= @EXEEXT@

#################################################
# Tools
#################################################

# recursive dir creation tool (mkdir -p)
MKDIR     ?= @MKDIR_P@
RM        ?= rm -f
RM_REC    ?= $(RM) -r

#################################################
# General package configuration
#################################################

USDX_PACKAGE_NAME := @PACKAGE_NAME@
USDX_VERSION := @PACKAGE_VERSION@
USDX_TARNAME := @PACKAGE_TARNAME@

#################################################
# USDX Paths
#################################################

USDX_SRC_DIR   := $(top_srcdir)/src
USDX_GAME_DIR  := $(top_srcdir)/game
USDX_TOOLS_DIR := $(top_srcdir)/tools
USDX_BUILD_DIR := $(top_srcdir)/build
USDX_LIB_DIR   := $(USDX_SRC_DIR)/lib

INSTALL_DATADIR := $(datadir)/$(USDX_PACKAGE_NAME)

#################################################
# FPC config
#################################################

# Free Pascal compiler binary
PPC := @PPC@
# FPC target platform and processor
PPLATFORM  := @FPC_PLATFORM@
PPROCESSOR := @FPC_PROCESSOR@

# Directories added to the unit path
PUNIT_FLAGS := -Fu.

# Directory where compiled units (.ppu and .o files) are stored
PCUNIT_DIR   := $(USDX_BUILD_DIR)/fpc-$(PPROCESSOR)-$(PPLATFORM)
PCUNIT_FLAGS := -FU$(PCUNIT_DIR)

# Directories added to the includes path
PINC_FLAGS := -Fi$(USDX_LIB_DIR)/JEDI-SDL/SDL/Pas

##
# PFLAGS
##

# Defined on debug mode
ENABLE_DEBUG := @ENABLE_DEBUG@

# Note: 
#   - PFLAGS/PFLAGS_* defaults to $(PFLAGS_XYZ_DEFAULT) if not set by the user
#   - if PFLAGS is defined, PFLAGS_* will be ignored on "make all"
PFLAGS         ?= @PFLAGS@
PFLAGS_BASE    ?= @PFLAGS_BASE@
PFLAGS_DEBUG   ?= @PFLAGS_DEBUG@
PFLAGS_RELEASE ?= @PFLAGS_RELEASE@

# Do not overwrite, just add extra flags
PFLAGS_EXTRA   += @PFLAGS_EXTRA@

# Default PFLAGS, used if PFLAGS/PFLAGS_* was not set by the user 
# - Do not use -dDEBUG because it will enable unwanted features
# - Do not strip executable (-Xs, set by fpc.cfg) to be GNU make conformant
# - Use DEBUG_MODE instead of DEBUG to avoid enabling the fpc.cfg DEBUG preset
# - The flag -vB appends the full path to filenames
# - Note that fpc.cfg already defines -vinw, so add -v0 first
# - The stack check (-Ct) might not work with enabled threading
# - Do we need -Coi?
PFLAGS_BASE_DEFAULT    := -Si -Sg- -Sc- -v0Binwe -Ciro -gl
PFLAGS_DEBUG_DEFAULT   := -Xs- -g -dDEBUG_MODE
PFLAGS_RELEASE_DEFAULT := -Xs- -O2 -OoNOSTACKFRAME
PFLAGS_EXTRA_DEFAULT   :=

# Debug/Release mode flags
# Note that flags will overwrite previously specified flags,
# e.g. "-vinwe -vi-" is the same as "-vnwe"
PFLAGS_DEBUG_ALL   := $(PFLAGS_BASE) $(PFLAGS_DEBUG) $(PFLAGS_EXTRA)
PFLAGS_RELEASE_ALL := $(PFLAGS_BASE) $(PFLAGS_RELEASE) $(PFLAGS_EXTRA)

# Choose default PFLAGS, depending on debug mode.
# Only used if PFLAGS was not set by the user.
ifdef ENABLE_DEBUG
PFLAGS_DEFAULT := $(PFLAGS_DEBUG_ALL)
else
PFLAGS_DEFAULT := $(PFLAGS_RELEASE_ALL)
endif

###
# linker and library settings
###

LIBS       ?= @LIBS@
LDFLAGS    ?= @LDFLAGS@
linkflags  := $(LDFLAGS) $(sort $(LIBS))
ifneq ($(linkflags),)
PLINKFLAGS := -k"$(linkflags)"
endif

PFLAGS_ALL = $(PFLAGS) $(PDEFINES) $(PLINKFLAGS) $(PLDFLAGS) $(PINC_FLAGS) $(PUNIT_FLAGS) $(PCUNIT_FLAGS)

#################################################
# USDX project config
#################################################

# dpr project file used as input
USDX_PROJ := ultrastardx.dpr
# name of executable
USDX_BIN_NAME ?= ultrastardx$(EXEEXT)
USDX_BIN := $(USDX_GAME_DIR)/$(USDX_BIN_NAME)

#################################################
# ProjectM
#################################################

PROJECTM_CWRAPPER_DIR := $(USDX_LIB_DIR)/projectM/cwrapper
PROJECTM_CWRAPPER_LIB := $(PROJECTM_CWRAPPER_DIR)/libprojectM-cwrapper.a
USE_PROJECTM_CWRAPPER := @USE_PROJECTM_CWRAPPER@

#################################################
# OpenCV
#################################################

OPENCV_CWRAPPER_DIR := $(USDX_LIB_DIR)/openCV3
OPENCV_CWRAPPER_LIB := $(OPENCV_CWRAPPER_DIR)/libopenCV-cwrapper.a
USE_OPENCV_CWRAPPER := @USE_OPENCV_CWRAPPER@
USE_OPENCV_CWRAPPER_DLL ?= no
ifeq ($(EXEEXT),.exe)
USE_OPENCV_CWRAPPER_DLL := yes
endif
ifeq ($(PPLATFORM),darwin)
USE_OPENCV_CWRAPPER_DLL := yes
endif
OPENCV_CWRAPPER_DLL_DIR ?= $(OPENCV_CWRAPPER_DIR)

ifeq ($(USE_OPENCV_CWRAPPER), yes)
PFLAGS_ALL += -Fl$(OPENCV_CWRAPPER_DLL_DIR)
endif

#################################################
# Static libs
#################################################

STATIC_LIBS := 
ifeq ($(USE_PROJECTM_CWRAPPER), yes)
STATIC_LIBS += $(PROJECTM_CWRAPPER_LIB)
endif

ifeq ($(USE_OPENCV_CWRAPPER), yes)
ifneq ($(USE_OPENCV_CWRAPPER_DLL), yes)
STATIC_LIBS += $(OPENCV_CWRAPPER_LIB)
endif
endif

#################################################
# general targets
#################################################

.PHONY: all
all: build

# One shot debug build (always rebuild)
# Note: we cannot set PFLAGS and call build directly, 
#  as target specific flags are not passed at recursive
#  make calls. So call debug-build first.
.PHONY: debug debug-build
debug: clean_obj
	$(MAKE) debug-build

debug-build: PFLAGS := $(PFLAGS_DEBUG_ALL)
debug-build: build

# One shot release build (always rebuild)
# Note: we cannot set PFLAGS and call build directly, 
#  as target specific flags are not passed at recursive
#  make calls. So call release-build first.
.PHONY: release release-build
release: clean_obj
	$(MAKE) release-build

release-build: PFLAGS := $(PFLAGS_RELEASE_ALL)
release-build: build

# Always rebuild, even if no file changed.
.PHONY: rebuild
rebuild: clean_obj
	$(MAKE) build

# Build if files changed. Always clean old data before compiling.
# FPC does not reliably recognize changes, neither in .pas, 
# .inc-files nor static libs (.a/.o). This might result in corrupted 
# builds and renders debugging difficult (because FPC uses outdated
# .ppu/.o data of files that have been changed).
.PHONY: build
build: $(USDX_BIN)

#################################################
# build
#################################################

SRC_FILES = $(shell find $(srcdir) -name "*.inc" -o -name "*.pas" -o -name "*.pp")

# To conform to the GNU Coding Standards, INSTALL_DATADIR is
# not hardcoded so $prefix and $datadir can be changed at any
# execution of this Makefile. 
# Paths cannot be passed to fpc via -d as with gcc's -D parameter.
# We use an intermediate file instead.
#
# See [info autoconf], "19.5 How Do I `#define' Installation Directories?"
#
# Do NOT use paths.inc as target name as it is in the requisite list
# of $(USDX_BIN).
.PHONY: create-pathinfo
create-pathinfo:
	echo "INSTALL_DATADIR = '$(INSTALL_DATADIR)';" > paths.inc

# check if any src-file changed and rebuild
$(USDX_BIN): $(USDX_PROJ) $(STATIC_LIBS) $(SRC_FILES)
	@echo "==================================="
	@echo "Changed files:"
	@echo "$?"
	@echo "==================================="
	@echo "-----------------------------------"
	@echo "Clean old object data..."

	$(MAKE) clean_obj

	@echo "-----------------------------------"

	$(MKDIR) "$(PCUNIT_DIR)"
	$(MAKE) create-pathinfo
	$(PPC) $(strip $(PFLAGS_ALL)) -o$@ $(USDX_PROJ)

#################################################
# clean-up
#################################################

.PHONY: clean
clean: clean_obj
	$(RM) paths.inc

.PHONY: clean_obj
clean_obj: clean_bin
	$(RM_REC) "$(PCUNIT_DIR)"

.PHONY: clean_bin
clean_bin:
	$(RM) "$(USDX_BIN)"
