################################################################################
# initialization
################################################################################

# define RSTT version
RSTT_VERSION := 3.1.0

# detect os
OS := $(shell uname -s | tr [:upper:] [:lower:])

# detect bit size
UNAME_M := $(shell uname -m)
ifeq ($(UNAME_M),x86_64)
	ARCH := 64
else
	ARCH := 32
endif

# aliases
FC    := gfortran
JAVA  := java
JAVAC := javac
MAKE  := make
MKDIR := mkdir -p
RM  := rm -rfv
ifeq ($(OS),darwin)
	# MacOS
	LIBEXT := dylib
	LIBEXT_JAVA := jnilib
else
	# linux
	LIBEXT := so
	LIBEXT_JAVA := so
endif

# color definitions
blue := $(shell tput setaf 6)
sgr0 := $(shell tput sgr0)


################################################################################
# recipes
################################################################################

# recipe to make everything (except documentation) and run tests
all: initialize geotess geotess_docs \
      slbm         slbm_test     slbm_docs \
      slbmc       slbmc_test    slbmc_docs \
      slbmfort slbmfort_test slbmfort_docs \
      slbmjni   slbmjni_test  slbmjni_docs \
      clean

# language-specific
cpp:     initialize slbm         slbm_test     slbm_docs clean
c:       initialize slbmc       slbmc_test    slbmc_docs clean
fortran: initialize slbmfort slbmfort_test slbmfort_docs clean
java:    initialize slbmjni   slbmjni_test  slbmjni_docs clean
docs:    initialize geotess_docs slbm_docs slbmc_docs slbmfort_docs slbmjni_docs

# command that tells us which recipes don't build source files
.PHONY: all cpp c fortran java initialize msg_intro make_dirs geotess geotess_docs \
        slbm slbm_test slbm_docs slbmc slbmc_test slbmc_docs \
        slbmfort slbmfort_test slbmfort_docs slbmjni slbmjni_test slbmjni_docs \
        docs clean cleanall
	

# initialize some folders and print status message
initialize: msg_intro make_dirs

msg_intro:
	@echo "$(blue)------------------------------------------------------------$(sgr0)"
	@echo "$(blue)Building Regional Seismic Travel Time v$(RSTT_VERSION)$(sgr0)"
	@echo "$(blue)------------------------------------------------------------$(sgr0)"

# create lib and bin directories, if necessary
make_dirs: lib bin

lib:
	@printf "$(blue)(Make directory) $(sgr0)"
	$(MKDIR) lib

bin:
	@printf "$(blue)(Make directory) $(sgr0)"
	$(MKDIR) bin


# geotess library and docs
geotess: make_dirs lib/libgeotesscpp.$(LIBEXT)
lib/libgeotesscpp.$(LIBEXT):
	@printf "$(blue)(Making GeoTessCPP) $(sgr0)"
	$(MAKE) -C GeoTessCPP

geotess_docs: 
	@printf "$(blue)(Making docs) $(sgr0)"
	$(MAKE) -C GeoTessCPP docs



# slbm c++ library, test, and docs
slbm: geotess lib/libslbm.$(LIBEXT)
lib/libslbm.$(LIBEXT):
	@printf "$(blue)(Making SLBM) $(sgr0)"
	$(MAKE) -C SLBM

slbm_test: slbm bin/slbmtestcc
	@printf "$(blue)(Running C++ test) $(sgr0)"
	./bin/slbmtestcc  models/rstt201404um.geotess models/rstt201404um.regression.dat
bin/slbmtestcc:
	@printf "$(blue)(Making SLBM_test_cc) $(sgr0)"
	$(MAKE) -C SLBM_test_cc

slbm_docs: 
	@printf "$(blue)(Making docs) $(sgr0)"
	$(MAKE) -C SLBM docs




# slbm c library, test, and docs
slbmc: slbm lib/libslbmCshell.$(LIBEXT)
lib/libslbmCshell.$(LIBEXT):
	@printf "$(blue)(Making SLBM_C_shell) $(sgr0)"
	$(MAKE) -C SLBM_C_shell

slbmc_test: slbmc bin/slbmtestc
	@printf "$(blue)(Running C test) $(sgr0)"
	./bin/slbmtestc    models/rstt201404um.geotess models/rstt201404um.regression.dat
bin/slbmtestc:
	@printf "$(blue)(Making SLBM_test_c) $(sgr0)"
	$(MAKE) -C SLBM_test_c

slbmc_docs:
	@printf "$(blue)(Making docs) $(sgr0)"
	$(MAKE) -C SLBM_C_shell docs



# slbm fortran library, test, and docs
ifeq (, $(shell which $(FC)))  # gfortran is not installed
slbmfort:
	@printf "$(blue)(Making SLBM_Fort_shell) $(sgr0)"
	@echo "$(FC) is not installed. Skipping..."

else  # gfortran is installed
slbmfort: slbm lib/libslbmFshell.$(LIBEXT)
lib/libslbmFshell.$(LIBEXT):
	@printf "$(blue)(Making SLBM_Fort_shell) $(sgr0)"
	$(MAKE) -C SLBM_Fort_shell

slbmfort_test: slbmfort bin/slbmtestfort
	@printf "$(blue)(Running Fortran test) $(sgr0)"
	./bin/slbmtestfort models/rstt201404um.geotess models/rstt201404um.regression.dat
bin/slbmtestfort:
	@printf "$(blue)(Making SLBM_test_fort) $(sgr0)"
	$(MAKE) -C SLBM_test_fort

slbmfort_docs:
	@printf "$(blue)(Making docs) $(sgr0)"
	$(MAKE) -C SLBM_Fort_shell docs

endif


# slbm java library and test
ifeq (, $(shell which $(JAVAC)))  # javac is not installed
slbmjni:
	@printf "$(blue)(Making SLBM_JNI) $(sgr0)"
	@echo "$(JAVAC) is not installed. Skipping..."

else  # javac is installed
slbmjni: slbm lib/slbmjni.jar lib/libslbmjni.$(LIBEXT_JAVA)
lib/slbmjni.jar: lib/libslbmjni.$(LIBEXT_JAVA)
lib/libslbmjni.$(LIBEXT_JAVA):
	@printf "$(blue)(Making SLBM_JNI) $(sgr0)"
	$(MAKE) -C SLBM_JNI

slbmjni_test: slbmjni bin/slbmtest.jar
	@printf "$(blue)(Running Java test) $(sgr0)"
	$(JAVA) -jar bin/slbmtest.jar models/rstt201404um.geotess models/rstt201404um.regression.dat
bin/slbmtest.jar:
	@printf "$(blue)(Making SLBM_test_java) $(sgr0)"
	$(MAKE) -C SLBM_test_java

slbmjni_docs:
	@printf "$(blue)(Making docs) $(sgr0)"
	$(MAKE) -C SLBM_JNI docs

endif


# clean up object files
clean:
	@echo "$(blue)------------------------------------------------------------$(sgr0)"
	@echo "$(blue)Cleaning up objects...$(sgr0)"
	@echo "$(blue)------------------------------------------------------------$(sgr0)"
	@printf "$(blue)(Cleaning GeoTessCPP) $(sgr0)"
	$(MAKE) -C GeoTessCPP clean
	@printf "$(blue)(Cleaning SLBM) $(sgr0)"
	$(MAKE) -C SLBM clean
	@printf "$(blue)(Cleaning SLBM_test_cc) $(sgr0)"
	$(MAKE) -C SLBM_test_cc clean
	@printf "$(blue)(Cleaning SLBM_C_shell) $(sgr0)"
	$(MAKE) -C SLBM_C_shell clean
	@printf "$(blue)(Cleaning SLBM_test_c) $(sgr0)"
	$(MAKE) -C SLBM_test_c clean
	@printf "$(blue)(Cleaning SLBM_Fort_shell) $(sgr0)"
	$(MAKE) -C SLBM_Fort_shell clean
	@printf "$(blue)(Cleaning SLBM_test_fort) $(sgr0)"
	$(MAKE) -C SLBM_test_fort clean
	@printf "$(blue)(Cleaning SLBM_JNI) $(sgr0)"
	$(MAKE) -C SLBM_JNI clean
	@printf "$(blue)(Cleaning SLBM_test_java) $(sgr0)"
	$(MAKE) -C SLBM_test_java clean

cleanall: clean
	@echo "$(blue)------------------------------------------------------------$(sgr0)"
	@echo "$(blue)Cleaning up everything...$(sgr0)"
	@echo "$(blue)------------------------------------------------------------$(sgr0)"
	@printf "$(blue)(Cleaning lib) $(sgr0)"
	$(RM) lib
	@printf "$(blue)(Cleaning bin) $(sgr0)"
	$(RM) bin
	@printf "$(blue)(Cleaning GeoTessCPP docs) $(sgr0)"
	$(RM) GeoTessCPP/doc/html
	@printf "$(blue)(Cleaning SLBM docs) $(sgr0)"
	$(RM) SLBM/doc/html
	@printf "$(blue)(Cleaning SLBM_C_shell docs) $(sgr0)"
	$(RM) SLBM_C_shell/doc/html
	@printf "$(blue)(Cleaning SLBM_Fort_shell docs) $(sgr0)"
	$(RM) SLBM_Fort_shell/doc/html
	@printf "$(blue)(Cleaning SLBM_JNI docs) $(sgr0)"
	$(RM) SLBM_JNI/java/SlbmInterface/doc
	@printf "$(blue)(Cleaning usage examples) $(sgr0)"
	cd usage_examples; $(RM) cc_example c_example fortran_example java_example.class
