# BUILD CONFIGURATION ---------------------------------------------------------
 BINARY  = freechain
 VERSION = 0.4
SCRATCH  = /tmp/scratch/$(BINARY)/
DISTFILE = freechain-$(VERSION).zip
DISTMSG  = "FreeChain version $(VERSION)"

# expects GNU-flavoured tools
    CC = gcc
    LD = gcc
   ZIP = zip
 UNZIP = unzip
    SH = bash
  ECHO = echo
PRINTF = printf
    RM = rm
 MKDIR = mkdir
    CP = cp
    MV = mv
 EGREP = egrep

# Extra flags to control build type
# Debugging:
# CFLAGSEX = -g -O
#LDFLAGSEX =
# Release:
 CFLAGSEX = -O3 -Werror
LDFLAGSEX =

# SOURCES ---------------------------------------------------------------------
  CSOURCES = game.c ncurses.c ncursessetup.c aiminimax.c simulate.c
   HEADERS = game.h ui.h ncursesui.h ai.h simulate.h
 EXTRADIST = Makefile README.txt CHANGELOG.txt LICENSE.txt

# PREAMBLE / AUTOCONFIGURATION / DERIVED --------------------------------------
OBJECTS = $(CSOURCES:%.c=%.o)
NOTOBJECTS = $(filter-out %.o, $(OBJECTS))
ifneq ($(NOTOBJECTS),)
    $(error OBJECTS contains non-object(s) $(NOTOBJECTS))
endif
SOURCES = $(CSOURCES)

# All files which are sources, /including/ non-compiled ones (e.g. headers)
ALLSOURCESMANU = $(SOURCES) $(HEADERS)

# Compiler warning flags (-Werror is saved for release build)
WARNFLAGS = -W -Wall -Wpointer-arith -Wcast-align -Wwrite-strings \
            -Wno-unused-parameter -Wuninitialized -Wno-unknown-pragmas
CWFLAGS   = $(WARNFLAGS) -Wcast-qual -Wmissing-declarations \
            -Wnested-externs -Wredundant-decls -Wundef \
            -Wstrict-prototypes -Wmissing-prototypes

# Tool flags
CFLAGS    = $(CWFLAGS) -I./ -I./src -std=c99 -pedantic $(CFLAGSEX)
LDFLAGS   = -lncurses $(LDFLAGSEX)

EXTRACDEPS = Makefile $(HEADERS)

# MAKEFILE METADATA AND MISCELLANY --------------------------------------------
# Gratuitous colours. While they make your build process look like an
# '80s disco, they also make it easy to see what it's doing at-a-glance.
RED=\033[31;1m
YELLOW=\033[33;1m
GREEN=\033[32;1m
BLUE=\033[34;1m
MAGENTA=\033[35;1m
CYAN=\033[36;1m
WHITE=\033[0m
RV=\033[7m
COLUMN2=\033[40G

.PHONY: all clean dist disttest work env info

# Cygwin handling =============================================================
# Autodetect a Cygwin enviroment. Make imports enviroment variables, and
# modern Windows tends to have one called "OS", value "Windows_NT".
ifeq ($(OS), Windows_NT)
	CFLAGS+=-DCYGWIN
	CPPFLAGS+=-DCYGWIN
	# Cygwin terminals don't support ANSI codes
	RED=
	YELLOW=
	GREEN=
	BLUE=
	MAGENTA=
	CYAN=
	WHITE=
	RV=
	COLUMN2=
else
	# Assume Linux.
	CFLAGS+=-DLINUX
	CPPFLAGS+=-DLINUX
endif

# RULES =======================================================================
all: $(BINARY)

$(BINARY): $(OBJECTS)
	@$(PRINTF) "$(BLUE)--- $(RV)LINKING   $(WHITE) $@\n"
	@$(LD) $(LDFLAGS) -o $(BINARY) $^
	@$(PRINTF) "$(BLUE)$(RV)***$(WHITE) $(BINARY) built\n"

%.o : %.c   $(EXTRACDEPS)
	@$(PRINTF) "$(GREEN)--- $(RV)COMPILING $(WHITE) $<\n"
	@$(CC) -o $@ -c $(CFLAGS)   $<

clean:
	@$(PRINTF) "$(RED)--- $(RV)CLEANING  $(WHITE)\n"
	@$(RM) -fv  $(OBJECTS)
	@$(RM) -fvr $(SCRATCH)
	@$(RM) -fv  $(BINARY) $(DISTFILE)
	@$(PRINTF) "$(RED)$(RV)***$(WHITE) Cleansed\n"

# Create distributable archive
dist: $(DISTFILE)
$(DISTFILE): $(SOURCES) $(HEADERS) $(EXTRADIST)
	@$(PRINTF) "$(MAGENTA)--- $(RV)BUNDLING  $(WHITE) $(DISTFILE)\n"
	@$(ECHO) $(DISTMSG) | $(ZIP) -z -9 $(DISTFILE) $^
	@$(PRINTF) "$(MAGENTA)$(RV)***$(WHITE) $(DISTFILE) created\n"

# Test distributable
disttest: $(DISTFILE)
	@$(PRINTF) "$(CYAN)--- $(RV)TESTING   $(WHITE) $(DISTFILE)\n"
	@$(MKDIR) -p $(SCRATCH)
	@$(CP) $(DISTFILE) $(SCRATCH)
	@$(ECHO) "cd $(SCRATCH); $(UNZIP) $(DISTFILE); make" | $(SH)
	@$(PRINTF) "$(CYAN)$(RV)***$(WHITE) Distributable tested\n"

# To `make work' is to find things to do ;)
work: $(SOURCES) $(HEADERS)
	@$(PRINTF) "$(RV)***$(WHITE) Outstanding tasks:\n"
	@$(EGREP) '(\\todo|TODO|XXX|FIXME)' --color=auto $^ || true


# Build environment information
env:
	@$(PRINTF) "C compiler       : $(CC)\n"
	@$(PRINTF) "Linker           : $(LD)\n"
	@$(PRINTF) "C compile flags  : $(CFLAGS)\n"
	@$(PRINTF) "Linker flags     : $(LDFLAGS)\n"

# Complete Makefile information
info: env
	@$(PRINTF) "C sources        : $(CSOURCES)\n"
	@$(PRINTF) "Objects          : $(OBJECTS)\n"

