# ================= External includes: Eigen, SuiteSparse, and Gfortran =======

EIGEN_INCLUDE_DIR = /usr/local/Cellar/eigen/3.3.7/include/eigen3/

GFORTRAN_LIB_DIR = /usr/local/Cellar/gcc/10.2.0_1/lib/gcc/10/

SUITESPARSE_INCLUDE_DIR = /usr/local/Cellar/suite-sparse/5.8.1/include/
SUITESPARSE_LIB_DIR = /usr/local/Cellar/suite-sparse/5.8.1/lib/

# ================= Local includes ============================================

MESH_INCLUDE_DIR = ./mesh/include
VIEWER_INCLUDE_DIR = ./viewer/include
PARAM1_INCLUDE_DIR = ./Param_intrinsic/include
PARAM2_INCLUDE_DIR = ./Param_extrinsic/include

GLM_INCLUDE_DIR  = ./dependencies/glm
GUI_INCLUDE_DIR  = ./dependencies/nanogui/include/
GLFW_INCLUDE_DIR = ./dependencies/nanogui/ext/glfw/include/
NANO_INCLUDE_DIR = ./dependencies/nanogui/ext/nanovg/src/

NANO_LIB_DIR = ./dependencies/nanogui/build

# ================= Libraries =================================================


SUITESPARSE_LIBS = -lumfpack -lamd -lcholmod -lsuitesparseconfig

GFORTRAN_LIBS = -lgfortran

NANO_LIBS = -lnanogui

BLAS_LIBS = -lblas -llapack
THREAD_LIBS = -lpthread

OPENGL = -framework OpenGL

# ================= Project Directories ====================================

INC_DIR = ./project/include
SRC_DIR = ./project/src
OBJ_DIR = ./project/src
F_SRC_DIR = ./dependencies/Fortran
F_OBJ_DIR = ./dependencies/Fortran
BIN_DIR = ./bin

# ================= Project Name ===========================================

EXT=
NAME=Map2Sphere
NAME2=Map2Sphere-CL
NAMEOBJ=$(OBJ_DIR)/$(NAME).o
NAMEOBJ2=$(OBJ_DIR)/$(NAME2).o
F_NAMEOBJ=$(F_OBJ_DIR)/lbfgs_mod.o $(F_OBJ_DIR)/InitRicci.o $(F_OBJ_DIR)/lbfgsb.o
NAMEBIN=$(BIN_DIR)/$(NAME)$(EXT)
NAMEBIN2=$(BIN_DIR)/$(NAME2)$(EXT)

# ================= Compilers and Flags ====================================

CC 		:= gcc
CFLAGS 		:= -c -O3 -arch x86_64 -ansi -Wall -Werror -pedantic
CPP 		:= g++
CPPFLAGS 	:= -c -std=c++11 -O3 -Wdeprecated-declarations -Wuninitialized -arch x86_64 -ansi -Wall -Werror -pedantic -std=c++0x -Wno-gnu-anonymous-struct -Wno-nested-anon-types
FC 		:= gfortran
FFLAGS 		:= -c -O3 -fcray-pointer -arch x86_64

INCLUDE_DIRS = -I$(INC_DIR) -I$(MESH_INCLUDE_DIR) -I$(PARAM1_INCLUDE_DIR) -I$(PARAM2_INCLUDE_DIR)\
		-I$(EIGEN_INCLUDE_DIR) -I$(SUITESPARSE_INCLUDE_DIR) \
		-I$(VIEWER_INCLUDE_DIR) -I$(GLM_INCLUDE_DIR) \
		-I$(GUI_INCLUDE_DIR) -I$(GLFW_INCLUDE_DIR) -I$(NANO_INCLUDE_DIR)

LIB_DIRS = -L$(GFORTRAN_LIB_DIR) -L$(NANO_LIB_DIR) -L$(SUITESPARSE_LIB_DIR)

LIBS = $(GFORTRAN_LIBS) $(NANO_LIBS) $(SUITESPARSE_LIBS) $(BLAS_LIBS) $(THREAD_LIBS) -lstdc++

LOAD_LIB_PATH = -Wl,-no_compact_unwind,-rpath,/Users/patrice/Research/Devel/Geometry/Map2Sphere/dependencies/nanogui/build/

LD_FLAGS = -O3 $(OPENGL) -arch x86_64

# ================= Pattern rules ==========================================

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
	$(CPP) $(CPPFLAGS) $(INCLUDE_DIRS) $< -o $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
	$(CC) $(CFLAGS) $(INCLUDE_DIRS) $< -o $@

$(F_OBJ_DIR)/%.o: $(F_SRC_DIR)/%.f
	$(FC) $(FFLAGS) $< -o $@

# ================= Compile source code ====================================

OBJECTS = \
$(NAMEOBJ) $(F_NAMEOBJ)

OBJECTS2 = \
$(NAMEOBJ2) $(F_NAMEOBJ)

# ================= Generate Executable ====================================

$(NAMEBIN) : $(OBJECTS)
	$(CPP) -o $(NAMEBIN) $(LD_FLAGS) $(OBJECTS) $(LIB_DIRS) $(LIBS) $(LOAD_LIB_PATH)

$(NAMEBIN2) : $(OBJECTS2)
	$(CPP) -o $(NAMEBIN2) $(LD_FLAGS) $(OBJECTS2) $(LIB_DIRS) $(LIBS) $(LOAD_LIB_PATH)

all: $(OBJECTS) $(OBJECTS2)
	$(CPP) -o $(NAMEBIN) $(LD_FLAGS) $(OBJECTS) $(LIB_DIRS) $(LIBS) $(LOAD_LIB_PATH)
	$(CPP) -o $(NAMEBIN2) $(LD_FLAGS) $(OBJECTS2) $(LIB_DIRS) $(LIBS) $(LOAD_LIB_PATH)

clean:
	touch $(OBJ_DIR)/junk.o; touch $(F_OBJ_DIR)/junk.o; rm -f $(OBJ_DIR)/*.o $(F_OBJ_DIR)/*.o $(NAMEBIN) $(NAMEBIN2)

$(OBJECTS): ./viewer/include/Viewer.h 
