# Include the other makefile for definitions to make this easier
include ./MakefileInc.mk

SRCDIR = src
OBJDIR = obj
BINDIR = bin
SRCEXT = cpp

COMPILE_FLAGS = -std=c++11
RCOMPILE_FLAGS = -D NDEBUG -O2 -march=native -g
DCOMPILE_FLAGS = -D DEBUG -O0 -g
LINK_FLAGS =
RLINK_FLAGS =
DLINK_FLAGS =

ifeq ($(THREADING),omp)
	COMPILE_FLAGS += -fopenmp
	LINK_FLAGS += -fopenmp
endif

ifeq ($(THREADING),iomp)
	COMPILE_FLAGS += -qopenmp
	LINK_FLAGS += -qopenmp
endif

ifeq ($(NOGRAPH),true)
	COMPILE_FLAGS += -D NOGRAPH
	LINK_FLAGS += -D NOGRAPH
endif

UNAME_S:=$(shell uname -s)

# Newer, more sexy version of the Makefile with the proper logic
# Really, we just need to know if we are local on an OSX machine,
# on a linux machine, or on Summit. Unfortunately, Makefiles do
# not have the ability to easily do logical AND or OR, so we 
# have to use this hack. The order is:
# OSX + GNU
# OSX + Intel
ifeq ($(UNAME_S)$(THREADING),Darwinomp)
	GSLINCS = `pkg-config --cflags gsl`
	GSLLIBS = `pkg-config --libs gsl`
	FFTWINCS = `pkg-config --cflags fftw3`
	GLFW3INCS = -I/opt/X11/include -I/usr/X11R6/include
	GLFW3LIBS = -L/opt/X11/lib -L/usr/local/Cellar/glfw/3.3/lib -lglfw -framework OpenGL -lglew
	YAMLINCS = -I./Lib/yaml-cpp/include
	YAMLLIBS = -Wl,-rpath,./Lib/yaml-cpp/osxlib -L./Lib/yaml-cpp/osxlib/ -lyaml-cpp
	PNGLIBS = `/usr/local/bin/libpng-config --ldflags`
	INCLUDES = $(GLFW3INCS) $(YAMLINCS) $(GSLINCS) $(FFTWINCS)
	LIBS = $(PNGLIBS) $(GLFW3LIBS) $(YAMLLIBS) $(GSLLIBS)
else ifeq ($(UNAME_S)$(THREADING),Darwiniomp)
	GSLINCS = `pkg-config --cflags gsl`
	GSLLIBS = `pkg-config --libs gsl`
	FFTWINCS = `pkg-config --cflags fftw3`
	GLFW3INCS = -I/opt/X11/include -I/usr/X11R6/include
	GLFW3LIBS = -L/opt/X11/lib -L/usr/local/Cellar/glfw/3.3/lib -lglfw -framework OpenGL -lglew
	YAMLINCS = -I./Lib/yaml-cpp/include
	YAMLLIBS = -Wl,-rpath,./Lib/yaml-cpp/osx_intel -L./Lib/yaml-cpp/osx_intel/ -lyaml-cpp
	PNGLIBS = `/usr/local/bin/libpng-config --ldflags`
	INCLUDES = $(GLFW3INCS) $(YAMLINCS) $(GSLINCS) $(FFTWINCS)
	LIBS = $(PNGLIBS) $(GLFW3LIBS) $(YAMLLIBS) $(GSLLIBS)
else ifeq ($(LOC)$(THREADING),Summitomp)
	GSLINCS = `pkg-config --cflags gsl`
	GSLLIBS = `pkg-config --libs gsl`
	GLFW3INCS =
	GLFW3LIBS =
	FFTWINCS = `pkg-config --cflags fftw3`
	YAMLINCS = -I./Lib/yaml-cpp/include
	YAMLLIBS = -Wl,-rpath,./Lib/yaml-cpp/summitlib -L./Lib/yaml-cpp/summitlib/ -lyaml-cpp
	PNGLIBS = `/usr/bin/libpng-config --ldflags`
	INCLUDES = $(GLFW3INCS) $(YAMLINCS) $(GSLINCS) $(FFTWINCS)
	LIBS = $(GLFW3LIBS) $(YAMLLIBS) $(GSLLIBS) $(PNGLIBS)
endif


	


#ifeq ($(LOC),CJE)
#	CC = gcc-9
#	CXX = g++-9
#	GSLINCS = `pkg-config --cflags gsl`
#	GSLLIBS = `pkg-config --libs gsl`
#	FFTWINCS = `pkg-config --cflags fftw3`
#	GLFW3INCS = -I/opt/X11/include -I/usr/X11R6/include
#	GLFW3LIBS = -L/opt/X11/lib -L/usr/local/Cellar/glfw/3.3/lib -lglfw3 -framework OpenGL -lglew
#	YAMLINCS = -I./Lib/yaml-cpp/include
#	YAMLLIBS = -Wl,-rpath,./Lib/yaml-cpp/osxlib -L./Lib/yaml-cpp/osxlib/ -lyaml-cpp
#	PNGLIBS = `/usr/local/bin/libpng-config --ldflags`
#	INCLUDES = $(GLFW3INCS) $(YAMLINCS) $(GSLINCS) $(FFTWINCS)
#	LIBS = $(PNGLIBS) $(GLFW3LIBS) $(YAMLLIBS) $(GSLLIBS)
#else ifeq ($(UNAME_S),Darwin)
#	CC = gcc-9
#	CXX = g++-9
#	GSLINCS = `pkg-config --cflags gsl`
#	GSLLIBS = `pkg-config --libs gsl`
#	FFTWINCS = `pkg-config --cflags fftw3`
#	GLFW3INCS = -I/opt/X11/include -I/usr/X11R6/include
#	GLFW3LIBS = -L/opt/X11/lib -L/usr/local/Cellar/glfw/3.3/lib -lglfw -framework OpenGL -lglew
#	YAMLINCS = -I./Lib/yaml-cpp/include
#	YAMLLIBS = -Wl,-rpath,./Lib/yaml-cpp/osxlib -L./Lib/yaml-cpp/osxlib/ -lyaml-cpp
#	PNGLIBS = `/usr/local/bin/libpng-config --ldflags`
#	INCLUDES = $(GLFW3INCS) $(YAMLINCS) $(GSLINCS) $(FFTWINCS)
#	LIBS = $(PNGLIBS) $(GLFW3LIBS) $(YAMLLIBS) $(GSLLIBS)
#else ifeq ($(LOC),Janus)
#	GSLINCS = `pkg-config --cflags gsl`
#	GSLLIBS = `pkg-config --libs gsl`
#	GLFW3INCS =
#	GLFW3LIBS =
#	FFTWINCS = `pkg-config --cflags fftw3`
#	YAMLINCS = -I./januslib/yaml-cpp/include
#	YAMLLIBS = -Wl,-rpath,./januslib/yaml-cpp/static -L./januslib/yaml-cpp/static -lyaml-cpp
#	PNGLIBS = `/usr/bin/libpng-config --ldflags`
#	INCLUDES = $(GLFW3INCS) $(YAMLINCS) $(GSLINCS) $(FFTWINCS)
#	LIBS = $(GLFW3LIBS) $(YAMLLIBS) $(GSLLIBS) $(PNGLIBS)
#else ifeq ($(LOC),Summit)
#	GSLINCS = `pkg-config --cflags gsl`
#	GSLLIBS = `pkg-config --libs gsl`
#	GLFW3INCS =
#	GLFW3LIBS =
#	FFTWINCS = `pkg-config --cflags fftw3`
#	YAMLINCS = -I./Lib/yaml-cpp/include
#	YAMLLIBS = -Wl,-rpath,./Lib/yaml-cpp/summitlib -L./Lib/yaml-cpp/summitlib/ -lyaml-cpp
#	PNGLIBS = `/usr/bin/libpng-config --ldflags`
#	INCLUDES = $(GLFW3INCS) $(YAMLINCS) $(GSLINCS) $(FFTWINCS)
#	LIBS = $(GLFW3LIBS) $(YAMLLIBS) $(GSLLIBS) $(PNGLIBS)
#else ifeq ($(LOC),Pando)
#	GSLINCS = `pkg-config --cflags gsl`
#	GSLLIBS = `pkg-config --libs gsl`
#	GLFW3INCS =
#	GLFW3LIBS =
#	FFTWINCS = `pkg-config --cflags fftw3`
#	YAMLINCS = -I./pandolib/yaml-cpp/include
#	YAMLLIBS = -Wl,-rpath,./pandolib/yaml-cpp/static -L./pandolib/yaml-cpp/static -lyaml-cpp
#	PNGLIBS = `/usr/bin/libpng-config --ldflags`
#	INCLUDES = $(GLFW3INCS) $(YAMLINCS) $(GSLINCS) $(FFTWINCS)
#	LIBS = $(GLFW3LIBS) $(YAMLLIBS) $(GSLLIBS) $(PNGLIBS)
#else
#	GSLINCS = -I/usr/local/include
#	GSLLIBS = -L/usr/local/libs -lgsl -lgslcblas -lm
#	GLFW3INCS = -I/home/cedelmaier/common/glfw/include
#	GLFW3LIBS = -L/home/cedelmaier/common/glfw/build/src -lglfw3 -lGLEW -lGLU -lGL -lX11 -lXxf86vm -lpthread -ldl -lXrandr -lXi -lXcursor -lXinerama
#	#YAMLINCS = -I/home/cedelmaier/common/yaml-cpp/include
#	#YAMLLIBS = -Wl,-rpath,/home/cedelmaier/common/yaml-cpp/build -L/home/cedelmaier/common/yaml-cpp/build -lyaml-cpp
#	YAMLINCS = -I./rumorlib/yaml-cpp/include
#	YAMLLIBS = -Wl,-rpath,./rumorlib/yaml-cpp/static -L./rumorlib/yaml-cpp/static -lyaml-cpp
#	PNGLIBS = `/usr/bin/libpng-config --ldflags`
#	INCLUDES = $(GLFW3INCS) $(YAMLINCS) $(GSLINCS)
#	LIBS = $(GLFW3LIBS) $(YAMLLIBS) $(GSLLIBS) $(PNGLIBS)
#endif

print-%: ; @echo $*=$($*)

SHELL = /bin/bash

.SUFFIXES:

ifneq ($(LIBS),)
	COMPILE_FLAGS += $(shell pkg-config --cflags $(LIBS))
	LINK_FLAGS += $(shell pkg-config --libs $(LIBS))
endif

# Special stuff for intel compiler
CC=$(CXX)
ifeq ($(CC),icpc)
	COMPILE_FLAGS += -Wno-deprecated
	#RCOMPILE_FLAGS += -openmp -DBOB_OMP
else
	COMPILE_FLAGS += -Wno-deprecated-declarations -Wno-deprecated
	#RCOMPILE_FLAGS += -fopenmp -DBOB_OMP
endif

# Combine compiler and linker flags
ifeq ($(CFG),release)
	export CXXFLAGS := $(CXXFLAGS) $(COMPILE_FLAGS) $(RCOMPILE_FLAGS)
	export LDFLAGS := $(LDFLAGS) $(LINK_FLAGS) $(RLINK_FLAGS)
else
	export CXXFLAGS := $(CXXFLAGS) $(COMPILE_FLAGS) $(DCOMPILE_FLAGS)
	export LDFLAGS := $(LDFLAGS) $(LINK_FLAGS) $(DLINK_FLAGS)
endif

# build information on all sources
ifeq ($(UNAME_S),Darwin)
	SOURCES = $(shell find $(SRCDIR) -name '*.$(SRCEXT)' | sort -k 1nr | cut -f2-)
else
	SOURCES = $(shell find $(SRCDIR) -name '*.$(SRCEXT)' -printf '%T@\t%p\n' \
			  										| sort -k 1nr | cut -f2-)
endif

# fallback case
rwildcard = $(foreach d, $(wildcard $1*), $(call rwildcard,$d/,$2) \
									$(filter $(subst *,%,$2), $d))
ifeq ($(SOURCES),)
	SOURCES := $(call rwildcard, $(SRCDIR), *.$(SRCEXT))
endif

# Now we have to figure out which we are building of the program list, since that matters
# for things like not compiling more than one main
SPINDLE_BD_MP_SRC = $(SRCDIR)/spindle_bd_mp.cpp
CROSSLINK_SPHERO_BD_MP_SRC = $(SRCDIR)/crosslink_sphero_bd_mp.cpp
SPINDLE_ANALYSIS_SRC = $(SRCDIR)/spindle_analysis.cpp
DIFFUSION_ANALYSIS_FREE_SRC = $(SRCDIR)/diffusion_analysis_free.cpp
XLINK_ANALYSIS_SRC = $(SRCDIR)/xlink_analysis.cpp
CONFIGURE_PARAMETERS_SRC = $(SRCDIR)/configure_parameters.cpp
FLUID_SPHERO_BUILDER_SRC = $(SRCDIR)/fluid_builder_sphero.cpp
SPINDLE_ANALYSIS_NEW_SRC = $(SRCDIR)/spindle_analysis_new.cpp
UNIT_TESTS_SRC = $(SRCDIR)/unit_tests.cpp
SPHERO_MOVIE_SRC = $(SRCDIR)/sphero_movie.cpp

MAIN_SOURCES = $(SPINDLE_BD_MP_SRC) $(CROSSLINK_SPHERO_BD_MP_SRC) \
	       $(SPINDLE_ANALYSIS_SRC) $(DIFFUSION_ANALYSIS_FREE_SRC) \
	       $(XLINK_ANALYSIS_SRC) $(CONFIGURE_PARAMETERS_SRC) \
	       $(FLUID_SPHERO_BUILDER_SRC) $(SPINDLE_ANALYSIS_NEW_SRC) \
	       $(UNIT_TESTS_SRC) $(SPHERO_MOVIE_SRC)

# These are the common sources
SRCS = $(filter-out $(MAIN_SOURCES) $(EXCLUDE_SOURCES), $(SOURCES))

OBJECTS = $(SRCS:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)
SPINDLE_BD_MP_OBJ = $(SPINDLE_BD_MP_SRC:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)
CROSSLINK_SPHERO_BD_MP_OBJ= $(CROSSLINK_SPHERO_BD_MP_SRC:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)
SPINDLE_ANALYSIS_OBJ= $(SPINDLE_ANALYSIS_SRC:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)
DIFFUSION_ANALYSIS_FREE_OBJ= $(DIFFUSION_ANALYSIS_FREE_SRC:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)
XLINK_ANALYSIS_OBJ = $(XLINK_ANALYSIS_SRC:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)
CONFIGURE_PARAMETERS_OBJ = $(CONFIGURE_PARAMETERS_SRC:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)
FLUID_SPHERO_BUILDER_OBJ = $(FLUID_SPHERO_BUILDER_SRC:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)
SPINDLE_ANALYSIS_NEW_OBJ= $(SPINDLE_ANALYSIS_NEW_SRC:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)
UNIT_TESTS_OBJ= $(UNIT_TESTS_SRC:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)
SPHERO_MOVIE_OBJ= $(SPHERO_MOVIE_SRC:$(SRCDIR)/%.$(SRCEXT)=$(OBJDIR)/%.o)

DEPS = $(OBJECTS:.o=.d)

.PHONY: dirs
dirs:
	mkdir -p $(OBJDIR)
	mkdir -p $(BINDIR)

.PHONY: clean
clean:
	rm -f -r $(OBJDIR)
	rm -f -r $(BINDIR)
	rm -f spindle_bd_mp
	rm -f crosslink_sphero_bd_mp
	rm -f spindle_analysis
	rm -f diffusion_analysis_free
	rm -f xlink_analysis
	rm -f configure_parameters
	rm -f fluid_builder_sphero
	rm -f spindle_analysis_new
	rm -f unit_tests
	rm -f sphero_movie

.PHONY : clean-output
clean-output :
	rm -f *.posit *.config *.thermo *.initial_config.* *.final_config *.final_config.* \
	*.checkpoint.* *.checkpoint *.thermo_ext sphero.crosslinks.* test-log


spindle_bd_mp: dirs $(BINDIR)/spindle_bd_mp;cp $(BINDIR)/spindle_bd_mp spindle_bd_mp

crosslink_sphero_bd_mp: dirs $(BINDIR)/crosslink_sphero_bd_mp; cp $(BINDIR)/crosslink_sphero_bd_mp crosslink_sphero_bd_mp

spindle_analysis: dirs $(BINDIR)/spindle_analysis; cp $(BINDIR)/spindle_analysis spindle_analysis

spindle_analysis_new: dirs $(BINDIR)/spindle_analysis_new; cp $(BINDIR)/spindle_analysis_new spindle_analysis_new

diffusion_analysis_free: dirs $(BINDIR)/diffusion_analysis_free; cp $(BINDIR)/diffusion_analysis_free diffusion_analysis_free

xlink_analysis: dirs $(BINDIR)/xlink_analysis; cp $(BINDIR)/xlink_analysis xlink_analysis

configure_parameters: dirs $(BINDIR)/configure_parameters; cp $(BINDIR)/configure_parameters configure_parameters

fluid_builder_sphero: dirs $(BINDIR)/fluid_builder_sphero; cp $(BINDIR)/fluid_builder_sphero fluid_builder_sphero

unit_tests: dirs $(BINDIR)/unit_tests; cp $(BINDIR)/unit_tests unit_tests

sphero_movie: dirs $(BINDIR)/sphero_movie; cp $(BINDIR)/sphero_movie sphero_movie

$(BINDIR)/spindle_bd_mp: $(OBJECTS) $(SPINDLE_BD_MP_OBJ)
	$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)

$(BINDIR)/crosslink_sphero_bd_mp: $(OBJECTS) $(CROSSLINK_SPHERO_BD_MP_OBJ)
	$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)

$(BINDIR)/spindle_analysis: $(OBJECTS) $(SPINDLE_ANALYSIS_OBJ)
	$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)

$(BINDIR)/spindle_analysis_new: $(OBJECTS) $(SPINDLE_ANALYSIS_NEW_OBJ)
	$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)

$(BINDIR)/diffusion_analysis_free: $(OBJECTS) $(DIFFUSION_ANALYSIS_FREE_OBJ)
	$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)

$(BINDIR)/xlink_analysis: $(OBJECTS) $(XLINK_ANALYSIS_OBJ)
	$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)

$(BINDIR)/configure_parameters: $(OBJECTS) $(CONFIGURE_PARAMETERS_OBJ)
	$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)

$(BINDIR)/fluid_builder_sphero: $(OBJECTS) $(FLUID_SPHERO_BUILDER_OBJ)
	$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)

$(BINDIR)/unit_tests: $(OBJECTS) $(UNIT_TESTS_OBJ)
	$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)

$(BINDIR)/sphero_movie: $(OBJECTS) $(SPHERO_MOVIE_OBJ)
	$(CXX) $^ -o $@ $(LDFLAGS) $(LIBS)

# add dependencies
-include $(DEPS)

# source file rules
$(OBJDIR)/%.o: $(SRCDIR)/%.$(SRCEXT)
	$(CXX) $(CXXFLAGS) $(INCLUDES) -MP -MMD -c $< -o $@
