ROOT = $(TUP_CWD)
DEPS = $(ROOT)/deps
LIB = bin

## Base
ifeq (@(CC),)
CC = clang
else
CC = @(CC)
endif
CFLAGS += -std=c99 -pedantic
CFLAGS += -I$(ROOT)/src
CFLAGS += -I$(ROOT)/src/modules
CFLAGS += -I$(ROOT)/src/lib/stdatomic
CFLAGS += -fvisibility=hidden
CFLAGS += -Wall -Wextra
CFLAGS += -Wno-unused-parameter
CFLAGS_glad.c += -Wno-pedantic
CFLAGS_os_android.c += -Wno-format-pedantic
CFLAGS_headset_openvr.c += -Wno-unused-variable -Wno-typedef-redefinition -Wno-pedantic
CFLAGS_headset_vrapi.c += -Wno-c11-extensions -Wno-gnu-empty-initializer -Wno-pedantic
CFLAGS_miniaudio.c += -Wno-unused-function
CFLAGS_@(STRICT) += -Werror
FLAGS_@(DEBUG) += -g
FLAGS_@(OPTIMIZE) += -Oz
FLAGS_@(SANITIZE) += -fsanitize=address,undefined
CFLAGS_@(OPTIMIZE) += -fdata-sections -ffunction-sections
ifneq (@(DEBUG),y)
LDFLAGS += -Wl,-s
endif

## Modules
DISABLE_@(AUDIO) += -DLOVR_DISABLE_AUDIO
DISABLE_@(DATA) += -DLOVR_DISABLE_DATA
DISABLE_@(EVENT) += -DLOVR_DISABLE_EVENT
DISABLE_@(FILESYSTEM) += -DLOVR_DISABLE_FILESYSTEM
DISABLE_@(GRAPHICS) += -DLOVR_DISABLE_GRAPHICS
DISABLE_@(HEADSET) += -DLOVR_DISABLE_HEADSET
DISABLE_@(MATH) += -DLOVR_DISABLE_MATH
DISABLE_@(PHYSICS) += -DLOVR_DISABLE_PHYSICS
DISABLE_@(SYSTEM) += -DLOVR_DISABLE_SYSTEM
DISABLE_@(THREAD) += -DLOVR_DISABLE_THREAD
DISABLE_@(TIMER) += -DLOVR_DISABLE_TIMER

## Headset backends
CFLAGS_@(SIMULATOR) += -DLOVR_USE_DESKTOP_HEADSET
CFLAGS_@(OPENVR) += -DLOVR_USE_OPENVR
CFLAGS_@(OPENXR) += -DLOVR_USE_OPENXR
CFLAGS_@(OPENXR) += -Ideps/openxr/include
CFLAGS_@(OCULUS) += -DLOVR_USE_OCULUS
CFLAGS_@(OCULUS) += -I@(OCULUS_PATH)/LibOVR/Include
CFLAGS_@(VRAPI) += -DLOVR_USE_VRAPI
CFLAGS_@(PICO) += -DLOVR_USE_PICO
CFLAGS_@(WEBXR) += -DLOVR_USE_WEBXR

## Spatializer backends
CFLAGS_@(OCULUS_AUDIO) += -DLOVR_ENABLE_OCULUS_AUDIO
CFLAGS_@(STEAM_AUDIO) += -DLOVR_ENABLE_PHONON

ifeq (@(PLATFORM),)
PLATFORM = @(TUP_PLATFORM)
else
PLATFORM = @(PLATFORM)
endif

## Windows
ifeq ($(PLATFORM),win32)
  win32 = y
  SUFFIX = .exe
  CFLAGS += -DLOVR_GL
  CFLAGS += -D_CRT_SECURE_NO_WARNINGS
  CFLAGS += -Wno-language-extension-token
  LDFLAGS += -lShell32 -lOle32
  LDFLAGS_@(OPTIMIZE) += -Wl,--gc-sections
  EXTRAS += bin/lovr.lib bin/lovr.exp
  EXTRAS_@(DEBUG) += bin/lovr.pdb bin/lovr.ilk
endif

## Linux
ifeq ($(PLATFORM),linux)
  linux = y
  CFLAGS += -D_POSIX_C_SOURCE=200809L
  CFLAGS += -DLOVR_GL
  LDFLAGS += -lm -lpthread -ldl
  LDFLAGS += -Wl,-rpath,\$ORIGIN
  LDFLAGS_@(OPTIMIZE) += -Wl,--gc-sections
endif

## macOS
ifeq ($(PLATFORM),macosx)
  macos = y
  PLATFORM = macos
  CFLAGS += -DLOVR_GL
  LDFLAGS += -Wl,-rpath,@executable_path
  LDFLAGS_@(OPTIMIZE) += -Wl,-dead_strip
  LDFLAGS += -lobjc
endif

## Android
ifeq ($(PLATFORM),android)
  android = y
  SUFFIX = .so
  PREFIX = apk/lib/arm64-v8a/lib
  LIB = bin/apk/lib/arm64-v8a

  ifeq (@(TUP_PLATFORM),win32)
    HOST = windows-x86_64
  endif
  ifeq (@(TUP_PLATFORM),macosx)
    HOST = darwin-x86_64
  endif
  ifeq (@(TUP_PLATFORM),linux)
    HOST = linux-x86_64
  endif

  CC = @(ANDROID_NDK)/toolchains/llvm/prebuilt/$(HOST)/bin/clang
  CFLAGS += -DLOVR_GLES
  CFLAGS += -I@(ANDROID_NDK)/sources/android/native_app_glue
  FLAGS += --target=aarch64-linux-android@(ANDROID_VERSION)
  FLAGS_@(DEBUG) += -funwind-tables
  LDFLAGS += -shared -landroid -lEGL -lGLESv3
  LDFLAGS_@(OPTIMIZE) += -Wl,--gc-sections

  ACTIVITY_@(OPENXR) = Activity_openxr
  ACTIVITY_@(VRAPI) = Activity_vrapi
  ACTIVITY_@(PICO) = Activity_pico
  ANDROID_MANIFEST_@(OPENXR) = src/resources/AndroidManifest_oculus.xml
  ANDROID_MANIFEST_@(VRAPI) = src/resources/AndroidManifest_oculus.xml
  ANDROID_MANIFEST_@(PICO) = src/resources/AndroidManifest_pico.xml
  ifneq (@(ANDROID_MANIFEST),)
    ANDROID_MANIFEST_y = @(ANDROID_MANIFEST)
  endif
  ifneq (@(ANDROID_PACKAGE),)
    PACKAGE_RENAME = --rename-manifest-package @(ANDROID_PACKAGE)
  endif
  ifneq (@(ANDROID_ASSETS),)
    ANDROID_ASSETS = -A @(ANDROID_ASSETS)
  endif

  ANDROID_JAR = @(ANDROID_SDK)/platforms/android-@(ANDROID_VERSION)/android.jar
  CLASSPATH = $(ANDROID_JAR)
  ifeq (@(PICO),y)
    EXTRA_JARS = $(DEPS)/pico/classes.jar
    ifeq (@(TUP_PLATFORM),win32)
      CLASSPATH = "$(CLASSPATH);$(EXTRA_JARS)"
    else
      CLASSPATH = "$(CLASSPATH):$(EXTRA_JARS)"
    endif
  endif

  TOOLS = @(ANDROID_SDK)/build-tools/@(ANDROID_BUILD_TOOLS_VERSION)
  !dx = |> ^ DX %b^ dx --dex --output=%o %f |>
  !zipalign = |> ^ ZIPALIGN %f^ $(TOOLS)/zipalign -f -p 4 %f %o |>
  !apksigner = |> ^ APKSIGNER %o^ $(TOOLS)/apksigner sign --ks @(ANDROID_KEYSTORE) --ks-pass @(ANDROID_KEYSTORE_PASS) --out %o %f |>

  # OpenXR
  OPENXR_LIB_PATH = $(DEPS)/OpenXR-Oculus/Libs/Android/arm64-v8a/Release
  CFLAGS_@(OPENXR) += -I$(DEPS)/OpenXR-Oculus/Include
  LDFLAGS_@(OPENXR) += -L$(OPENXR_LIB_PATH) -lopenxr_loader
  LIBS_@(OPENXR) += $(OPENXR_LIB_PATH)/libopenxr_loader.so

  # VrApi
  VRAPI_LIB_PATH = $(DEPS)/VrApi/Libs/Android/arm64-v8a/Release
  CFLAGS_@(VRAPI) += -I$(DEPS)/VrApi/Include
  LDFLAGS_@(VRAPI) += -L$(VRAPI_LIB_PATH) -lvrapi
  LIBS_@(VRAPI) += $(VRAPI_LIB_PATH)/libvrapi.so

  # pico
  PICO_LIB_PATH = $(DEPS)/pico/jni/arm64-v8a
  LDFLAGS_@(PICO) += -L$(PICO_LIB_PATH) -lPvr_NativeSDK
  LIBS_@(PICO) += $(PICO_LIB_PATH)/libPvr_NativeSDK.so
endif

## emscripten
ifeq ($(PLATFORM),web)
  web = y
  SUFFIX = .html
  CFLAGS += -DLOVR_WEBGL
  LDFLAGS += -s USE_WEBGL2
  LDFLAGS += -s FORCE_FILESYSTEM
  LDFLAGS += -s EXPORTED_FUNCTIONS="['_main','_lovrDestroy','_webxr_attach','_webxr_detach','_lovrCanvasCreateFromHandle','_lovrCanvasDestroy','_lovrGraphicsSetBackbuffer','_lovrGraphicsSetViewMatrix','_lovrGraphicsSetProjection']"
  LDFLAGS_@(WEBXR) += --js-library $(ROOT)/src/resources/webxr.js
  LDFLAGS += --shell-file $(ROOT)/src/resources/lovr.html
  FLAGS_@(THREAD) += -s USE_PTHREADS=1
  EXTRAS = bin/lovr.js bin/lovr.wasm
  EXTRAS_@(THREAD) += bin/lovr.worker.js
endif

## Libraries
ifneq (@(CMAKE_DEPS),)
  BUILD = @(CMAKE_DEPS)

  ifeq (@(OPTIMIZE),y)
  CONFIG = Release
  else
  CONFIG = Debug
  endif

  # Lua
  ifeq (@(LUAJIT),y)
    CFLAGS += -I$(DEPS)/luajit/src
    LDFLAGS_$(win32) += -L$(BUILD)/luajit/src/$(CONFIG) -lluajit
    LDFLAGS_$(macos) += -L$(BUILD)/luajit/src -lluajit
    LDFLAGS_$(linux) += -L$(BUILD)/luajit/src -lluajit
    LDFLAGS_$(android) += -L$(BUILD)/luajit/src -lluajit
    LIBS_$(win32) += $(BUILD)/luajit/src/$(CONFIG)/luajit.dll
    LIBS_$(macos) += $(BUILD)/luajit/src/libluajit.dylib
    LIBS_$(linux) += $(BUILD)/luajit/src/libluajit.so
  else
    error "Vanillua does not work on this commit"
  endif

  # GLFW
  CFLAGS_$(win32) += -I$(DEPS)/glfw/include
  CFLAGS_$(macos) += -I$(DEPS)/glfw/include
  CFLAGS_$(linux) += -I$(DEPS)/glfw/include
  LDFLAGS_$(win32) += -L$(BUILD)/glfw/src/$(CONFIG) -lglfw3dll
  LDFLAGS_$(macos) += -L$(BUILD)/glfw/src -lglfw
  LDFLAGS_$(linux) += -L$(BUILD)/glfw/src -lglfw
  LIBS_$(win32) += $(BUILD)/glfw/src/$(CONFIG)/glfw3.dll
  LIBS_$(macos) += $(BUILD)/glfw/src/libglfw.*dylib
  LIBS_$(linux) += $(BUILD)/glfw/src/libglfw.*so*

  # msdfgen
  CFLAGS_@(DATA) += -I$(DEPS)/msdfgen
  LDFLAGS_@(DATA)_$(win32) += -L$(BUILD)/msdfgen/$(CONFIG) -lmsdfgen
  LDFLAGS_@(DATA)_$(macos) += -L$(BUILD)/msdfgen -lmsdfgen
  LDFLAGS_@(DATA)_$(linux) += -L$(BUILD)/msdfgen -lmsdfgen
  LDFLAGS_@(DATA)_$(android) += -L$(BUILD)/msdfgen -lmsdfgen
  LDFLAGS_@(DATA)_$(web) += $(BUILD)/msdfgen/libmsdfgen.a
  LIBS_@(DATA)_$(win32) += $(BUILD)/msdfgen/$(CONFIG)/msdfgen.dll
  LIBS_@(DATA)_$(macos) += $(BUILD)/msdfgen/libmsdfgen.dylib
  LIBS_@(DATA)_$(linux) += $(BUILD)/msdfgen/libmsdfgen.so
  LIBS_@(DATA)_$(android) += $(BUILD)/msdfgen/libmsdfgen.so

  # OpenVR
  CFLAGS_@(OPENVR) += -I$(DEPS)/openvr/headers
  LDFLAGS_@(OPENVR)_$(win32) += -L$(DEPS)/openvr/bin/win64 -lopenvr_api64
  LDFLAGS_@(OPENVR)_$(macos) += -L$(DEPS)/openvr/bin/osx32 -lopenvr_api
  LDFLAGS_@(OPENVR)_$(linux) += -L$(DEPS)/openvr/bin/linux64 -lopenvr_api
  LIBS_@(OPENVR)_$(win32) += $(DEPS)/openvr/bin/win64/openvr_api.dll
  LIBS_@(OPENVR)_$(macos) += $(DEPS)/openvr/bin/osx32/libopenvr_api.dylib
  LIBS_@(OPENVR)_$(linux) += $(DEPS)/openvr/bin/linux64/libopenvr_api.so

  # ODE
  CFLAGS_@(PHYSICS) += -I$(DEPS)/ode/include -I$(BUILD)/ode/include
  LDFLAGS_@(PHYSICS)_$(win32) += -L$(BUILD)/ode/$(CONFIG) -lode
  LDFLAGS_@(PHYSICS)_$(macos) += -L$(BUILD)/ode -lode
  LDFLAGS_@(PHYSICS)_$(linux) += -L$(BUILD)/ode -lode
  LDFLAGS_@(PHYSICS)_$(android) += -L$(BUILD)/raw/lib/arm64-v8a -lode
  LDFLAGS_@(PHYSICS)_$(web) += $(BUILD)/ode/libode.a
  LIBS_@(PHYSICS)_$(win32) += $(BUILD)/ode/$(CONFIG)/ode.dll
  LIBS_@(PHYSICS)_$(macos) += $(BUILD)/ode/libode.dylib
  LIBS_@(PHYSICS)_$(linux) += $(BUILD)/ode/libode.so
  LIBS_@(PHYSICS)_$(android) += $(BUILD)/raw/lib/arm64-v8a/libode.so

  # Oculus Audio
  CFLAGS_@(OCULUS_AUDIO) += -I@(OCULUS_AUDIO_PATH)/Include
  LDFLAGS_@(OCULUS_AUDIO)_$(win32) += -L@(OCULUS_AUDIO_PATH)/Lib/x64 -lovraudio64
  LDFLAGS_@(OCULUS_AUDIO)_$(linux) += -L@(OCULUS_AUDIO_PATH)/Lib/Linux64 -lovraudio64
  LDFLAGS_@(OCULUS_AUDIO)_$(android) += -L@(OCULUS_AUDIO_PATH)/Lib/Android/arm64-v8a -lovraudio64
  LIB_@(OCULUS_AUDIO)_$(win32) += @(OCULUS_AUDIO_PATH)/Lib/x64/ovraudio64.dll
  LIB_@(OCULUS_AUDIO)_$(linux) += @(OCULUS_AUDIO_PATH)/Lib/Linux64/libovraudio64.so
  LIB_@(OCULUS_AUDIO)_$(android) += @(OCULUS_AUDIO_PATH)/Lib/Android/arm64-v8a/libovraudio64.so

  # Phonon
  CFLAGS_@(STEAM_AUDIO) += -I@(STEAM_AUDIO_PATH)/include
  LIBS_@(STEAM_AUDIO)_$(win32) += @(STEAM_AUDIO_PATH)/bin/Windows/x64/phonon.dll
  LIBS_@(STEAM_AUDIO)_$(macos) += @(STEAM_AUDIO_PATH)/lib/OSX/libphonon.dylib
  LIBS_@(STEAM_AUDIO)_$(linux) += @(STEAM_AUDIO_PATH)/lib/Linux/x64/libphonon.so
  LIBS_@(STEAM_AUDIO)_$(android) += @(STEAM_AUDIO_PATH)/lib/Android/arm64/libphonon.so
endif

LIBS += $(LIBS_y) $(LIBS_y_y)
CFLAGS += $(FLAGS) $(FLAGS_y) $(DISABLE_n) $(CFLAGS_y) @(EXTRA_CFLAGS)
LDFLAGS += $(FLAGS) $(FLAGS_y) $(LDFLAGS_y) $(LDFLAGS_y_y) @(EXTRA_LDFLAGS)

## Macros
!cc = |> ^o CC %b^ $(CC) $(CFLAGS) $(CFLAGS_%b) -o %o -c %f |>
!ld = |> ^ LD %o^ $(CC) -o %o %f $(LDFLAGS) |>
!xd = |> ^ XD %f^ xxd -i %f > %o |>
!cp = |> ^ CP %b^ cp %f %o |>
