# - - - - - - - #
#               #
#    COLORS     #
#               #
# - - - - - - - #

GRAY     = "\e[0;30m"
RED      = "\e[0;31m"
GREEN    = "\e[0;32m"
YELLOW   = "\e[0;33m"
BLUE     = "\e[0;34m"
PURPLE   = "\e[0;35m"
CYAN     = "\e[0;36m"
WHITE    = "\e[0;37m"

B_GRAY   = "\e[1;30m"
B_RED    = "\e[1;31m"
B_GREEN  = "\e[1;32m"
B_YELLOW = "\e[1;33m"
B_BLUE   = "\e[1;34m"
B_PURPLE = "\e[1;35m"
B_CYAN   = "\e[1;36m"
B_WHITE  = "\e[1;37m"

RESET    = "\e[0m"

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
#               . name = value \          . += append to a variable   #
#   VARIABLES   .        value            . != set result of command  #
#               . name is case sensitive  . ?= set if not already set #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

NAME          = containers
NAME_FT       = containers_ft
NAME_STL      = containers_stl

CC            = clang++
EXT           = cpp

CFLAGS        = -Wall -Wextra -Werror $(INCLUDES)
CFLAGS       += -std=c++98
CFLAGS       += -g3

CFLAGS_STL    = -Wall -Wextra -Werror $(INCLUDES)
CFLAGS_STL   += -D STL
CFLAGS_STL   += -std=c++98
CFLAGS_STL   += -g3

VPATH         = $(D_SRCS)

LIBS          =

F_INCLUDES    = $(HEADERS:%=$(D_HEADERS)/%) \
				$(TEMPLATES:%=$(D_TEMPLATES)/%) \
				$(TESTS:%=$(D_TESTS)/%)
INCLUDES      = -I$(D_HEADERS) \
				-I$(D_TEMPLATES) \
				-I$(D_TESTS)

D_SRCS        = ./tests
#SRCS          = main42.cpp
#SRCS          = main_map_1.cpp
#SRCS          = main_map_2.cpp
#SRCS          = main_stack_1.cpp
SRCS          = \
				main.cpp \
				tests_definitions.cpp \
				\
				tests_vector.cpp \
				tests_map.cpp \
				tests_stack.cpp

D_HEADERS     = ./headers
HEADERS       = \
				colors.h \
				\
				enable_if.hpp \
				iterator_traits.hpp \
				reverse_iterator.hpp \
				equal.hpp \
				lexicographical_compare.hpp \
				pair.hpp \
				\
				map.hpp \
				map_node.hpp \
				map_iterator.hpp \
				vector.hpp \
				stack.hpp

D_TEMPLATES   = ./templates
TEMPLATES     = \
				vector.tpp \
				map.tpp

D_TESTS       = ./tests/includes
TESTS         = \
				main.hpp \
				tests_utils.hpp

D_OBJS_FT     = builds_ft
OBJS_FT       = $(SRCS:%.$(EXT)=$(D_OBJS_FT)/%.o)
D_OBJS_STL    = builds_stl
OBJS_STL      = $(SRCS:%.$(EXT)=$(D_OBJS_STL)/%.o)


# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
#             .  target: prerequisites    .   $@ : target             #
#    RULES    .          recipe           .   $< : 1st prerequisite   #
#             .          @recipe (silent) .   $^ : all prerequisites  #
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #

all: $(NAME_FT) $(NAME_STL)

stl: $(NAME_STL)
ft: $(NAME_FT)

$(D_OBJS_FT)/%.o: %.$(EXT) | $(D_OBJS_FT)
	@echo $(CYAN)"compilation " $@ $(RESET)
	@$(CC) $(CFLAGS) -c $< -o $@
$(D_OBJS_STL)/%.o: %.$(EXT) | $(D_OBJS_STL)
	@echo $(CYAN)"compilation -D STL" $@ $(RESET)
	@$(CC) $(CFLAGS) -D STL -c $< -o $@

$(D_OBJS_FT) $(D_OBJS_STL):
	mkdir $@

$(OBJS_FT) $(OBJS_STL): $(F_INCLUDES)

# https://stackoverflow.com/questions/19259108/makefile-same-rule-for-multiple-targets
$(NAME_FT): $(OBJS_FT)
$(NAME_STL): $(OBJS_STL)
$(NAME_FT) $(NAME_STL):
	@echo $(PURPLE)"linkage (link objects.o)"$(RESET)
	@$(CC) $^ -o $@ $(LIBS)

leaks: leaksft
leaksft: $(NAME_FT)
	valgrind --leak-check=full --show-leak-kinds=all ./$<
leakstl: $(NAME_STL)
	valgrind --leak-check=full --show-leak-kinds=all ./$<

clean:
	rm -rf $(D_OBJS_FT)
	rm -rf $(D_OBJS_STL)

fclean: clean
	rm -f $(NAME_FT) $(NAME_STL)

re: fclean all

.PHONY : all clean fclean re

