#   Zerocat PS/2-Keyboard --- Get rid of spyware.
#
#   Copyright (C) 2017, 2018, 2020, 2021, 2022, 2023  Kai Mertens <kmx@posteo.net>
#
#   This file is part of Zerocat PS/2-Keyboard.
#
#   Zerocat PS/2-Keyboard is free software: you can redistribute it and/or
#   modify it under the terms of the GNU General Public License as
#   published by the Free Software Foundation, either version 3 of the
#   License, or (at your option) any later version.
#
#   Zerocat PS/2-Keyboard is distributed in the hope that it will be
#   useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
#   General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with Zerocat PS/2-Keyboard.
#   If not, see <http://www.gnu.org/licenses/>.


#   Usage
#   =====
#
#   To generate workbench related documentation, type:
#
#           [env]$ make -C ../../workbench/doc


#   Workaround for GNU Make < 4.3
#   =============================
#
#   Finalize commands within a $(shell) function with semicolon, e.g.:
#
#           $(shell echo;)


# Shell
SHELL                         := /bin/sh


# White Space
EMPTY                         :=
SPACE                         := $(EMPTY) $(EMPTY)
COMMA                         := ,
M5                            := wwwww
TAB1                          := \r\t\t
TAB2                          := \r\t\t\t


# Suffixes
.SUFFIXES :


# Roots
ROOT                          := ../../
ROOT_DOC                      := ../../doc/
ROOT_WB_DOC                   := ../../workbench/doc/
ROOT_WB_PCB                   := ../../workbench/pcb/
ROOT_WB_GSCHEM                := ../../workbench/gschem/


# Utilities
WHEREIS                       := $(shell command -v whereis;)
WHEREIS_FLAGS                 := -b
$(if $(strip $(WHEREIS)),,    $(error Cannot find whereis utility))

CD                            := $(shell command -v cd;)
CD_FLAGS                      :=
$(if $(strip $(CD)),,         $(error Cannot find cd utility))

RM                            := $(shell command -v rm;)
RM_FLAGS                      := -f
$(if $(strip $(RM)),,         $(error Cannot find rm utility))

CAT                           := $(shell command -v cat;)
CAT_FLAGS                     :=
$(if $(strip $(CAT)),,        $(error Cannot find cat utility))

CUT                           := $(shell command -v cut;)
CUT_FLAGS                     := -d' '
$(if $(strip $(CUT)),,        $(error Cannot find cut utility))

GAF                           := $(shell command -v gaf;)
GAF_FLAGS                     :=
$(if $(strip $(GAF)),,        $(error Cannot find gaf utility))

GIT                           := $(shell command -v git;)
GIT_FLAGS                     :=
$(if $(strip $(GIT)),,        $(error Cannot find git utility))

PCB                           := $(shell command -v pcb;)
PCB_FLAGS                     :=
$(if $(strip $(PCB)),,        $(error Cannot find pcb utility))

SED                           := $(shell command -v sed;)
SED_FLAGS                     := -r
$(if $(strip $(SED)),,        $(error Cannot find sed utility))

SET                           := $(shell command -v set;)
SET_FLAGS                     := -f
$(if $(strip $(SET)),,        $(error Cannot find set utility))

DATE                          := $(shell command -v date;)
DATE_FLAGS                    := -R
$(if $(strip $(DATE)),,       $(error Cannot find date utility))

DIFF                          := $(shell command -v diff;)
DIFF_FLAGS                    :=
$(if $(strip $(DIFF)),,       $(error Cannot find diff utility))

ECHO                          := $(shell $(WHEREIS) $(WHEREIS_FLAGS) echo | $(CUT) $(CUT_FLAGS) -f2;)
ECHO_FLAGS                    := -e
$(if $(strip $(ECHO)),,       $(error Cannot find echo utility))

GREP                          := $(shell command -v grep;)
GREP_FLAGS                    :=
$(if $(strip $(GREP)),,       $(error Cannot find grep utility))

SORT                          := $(shell command -v sort;)
SORT_FLAGS                    :=
$(if $(strip $(SORT)),,       $(error Cannot find sort utility))

UNIQ                          := $(shell command -v uniq;)
UNIQ_FLAGS                    :=
$(if $(strip $(UNIQ)),,       $(error Cannot find uniq utility))

WGET                          := $(shell command -v wget;)
WGET_FLAGS                    :=
$(if $(strip $(WGET)),,       $(error Cannot find wget utility))

#   Note ‘mkdir -p’ might not be supported!
MKDIR                         := $(shell command -v mkdir;)
MKDIR_FLAGS                   := -p
$(if $(strip $(MKDIR)),,      $(error Cannot find mkdir utility))

GSCHEM                        := $(shell command -v gschem;)
GSCHEM_FLAGS                  :=
$(if $(strip $(GSCHEM)),,     $(error Cannot find gschem utility))

MKTEMP                        := $(shell command -v mktemp;)
MKTEMP_FLAGS                  :=
$(if $(strip $(MKTEMP)),,     $(error Cannot find mktemp utility))

CONVERT                       := $(shell command -v convert;)
CONVERT_FLAGS                 := -resize 2000x
$(if $(strip $(CONVERT)),,    $(error Cannot find convert utility))

GNETLIST                      := $(shell command -v gnetlist;)
GNETLIST_FLAGS                :=
$(if $(strip $(GNETLIST)),,   $(error Cannot find gnetlist utility))

MARKDOWN                      := $(shell command -v markdown;)
MARKDOWN_FLAGS                :=
$(if $(strip $(MARKDOWN)),,   $(error Cannot find markdown utility))


# Settings
PROJECT_TITLE                 := Zerocat PS/2-Keyboard
PROJECT_BRIEF                 := Get rid of spyware.
MAKEFILE_TITLE                := Generate Workbench Files


# Tinned Cans
define HEADER
$(strip\
	$(ECHO) $(ECHO_FLAGS)\
		"\n$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)"\
		"\n$(M5) $(PROJECT_TITLE) – $(PROJECT_BRIEF)"\
		"\n$(M5) $(MAKEFILE_TITLE)"\
		"\n$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)$(M5)"\
)
endef
define HEADLINE
$(strip\
	$(ECHO) $(ECHO_FLAGS)\
		"$(M5) Process target “$(@)” $(M5)$(M5)"\
)
endef
define DONE
$(strip\
	$(ECHO) $(ECHO_FLAGS)\
		"... successfully processed: “$@”"\
		"\n"\
)
endef


# Special Targets
#~ .SECONDARY :               # uncomment for debugging
.PHONY :\
	all\
	\
	hello\
	help\
	\
	clean-bom.md\
	clean-png\
	clean-bom\
	clean-drc\
	clean


# Targets
#   generate all
all : hello\
	board.bom.md\
		$(ROOT_WB_GSCHEM)board.sch.png\
			$(ROOT_WB_GSCHEM)x200-keyboard-cable.sch.png
	@$(HEADLINE)\
	&& $(DONE);

#   display greeting
#     provided with all, clean and help
hello :
	@$(HEADER)\
	&& $(DONE);

#   display help information
help : hello
	@$(HEADLINE)\
	&& $(ECHO) $(ECHO_FLAGS)\
		"\nList of Targets"\
		"\n==============="\
		"\n"\
		"\nDefault"\
		"\n-------"\
		"\n"\
		"\nall$(TAB1)build hardware documentation files"\
		"\n"\
		"\nHelp"\
		"\n----"\
		"\n"\
		"\nhello$(TAB1)greeter, provided with targets all, clean and help"\
		"\nhelp$(TAB1)list available targets"\
		"\n"\
		"\nClean"\
		"\n-----"\
		"\n"\
		"\nclean-bom.md$(TAB1)remove *.bom.md files"\
		"\nclean-bom$(TAB1)remove *.bom files"\
		"\nclean-png$(TAB1)remove generated images"\
		"\nclean-drc$(TAB1)remove *.drc files"\
		"\nclean$(TAB1)remove all generated files"\
		"\n"\
	&& $(DONE);

#   check design rules of *.sch files
%.drc : $(ROOT_WB_GSCHEM)%.sch $(ROOT_WB_GSCHEM)rules-drc.scm
	@$(HEADLINE)\
	&& $(GNETLIST) $(GNETLIST_FLAGS)\
		-g drc2\
		-l $(ROOT_WB_GSCHEM)rules-drc.scm\
		-o $@\
			$<\
	&& $(DONE);

#   generate bill of material files from gschem schematics
%.bom : %.drc $(ROOT_WB_GSCHEM)attribs
	@$(HEADLINE)\
	&& $(CD) $(CD_FLAGS)\
		$(ROOT_WB_GSCHEM)\
	&& $(GNETLIST) $(GNETLIST_FLAGS)\
		-g bom2\
		-o $(ROOT_WB_DOC)$@\
			$*.sch\
	&& $(CD) $(CD_FLAGS)\
		-\
	&& $(DONE);

#   create markdown file from *.bom file
%.bom.md : %.bom
	@$(HEADLINE)\
	&& $(ECHO) $(ECHO_FLAGS) \# Bill of Material \($*.sch\) > $@\
	&& $(ECHO) $(ECHO_FLAGS) >> $@\
	&& $(ECHO) $(ECHO_FLAGS) >> $@\
	&& $(ECHO) $(ECHO_FLAGS) Footprints are named according to gEDA/gaf and >> $@\
	&& $(ECHO) $(ECHO_FLAGS) PCB footprint naming convention. >> $@\
	&& $(ECHO) $(ECHO_FLAGS) >> $@\
	&& $(SED) $(SED_FLAGS) --in-place\
		-e '{:nline /.*:.*/!{/^:/!N; s/\n/ /g; t nline}}'\
			$<\
	&& $(SED) $(SED_FLAGS) --in-place\
		-e '/:$$/{N; s/\n//g;}'\
		-e 's/:unknown/:/g'\
			$<\
	&& $(SED) $(SED_FLAGS)\
		-e 's/^/    /;'\
		-e 'y/:/\|/; 2i\
	    ----|----|----|----|----|----'\
			$<\
				>> $@\
	&& $(SED) $(SED_FLAGS) --in-place\
		-e 's/\|/  \|/g;'\
			$@\
	&& $(DONE);

#   generate images from schematics
$(ROOT_WB_GSCHEM)%.sch.png : $(ROOT_WB_GSCHEM)%.sch
	@$(HEADLINE)\
	&& TEMPFILE=$(shell $(MKTEMP) $(MKTEMP_FLAGS) --suffix=.png;)\
	&& $(CD) $(CD_FLAGS)\
		$(@D)\
	&& $(GAF) $(GAF_FLAGS)\
		export\
			--color\
			--scale=10mm\
			--margins=10cm\
			--output=$$TEMPFILE\
				$(<F)\
	&& $(CONVERT) $(CONVERT_FLAGS)\
		$$TEMPFILE\
			$(@F)\
	&& $(RM) $(RM_FLAGS)\
		$$TEMPFILE\
	&& $(CD) $(CD_FLAGS)\
		-\
	&& $(DONE);

#   create images from pcb files
%.pcb.png : %.drc
	@$(HEADLINE)\
	&& $(PCB) $(PCB_FLAGS)\
		-x png --dpi 300 --use-alpha --only-visible --photo-mode\
		--outfile $@\
			$(ROOT_WB_PCB)$*.pcb\
	&& $(DONE);

#   clean *.bom.md
clean-bom.md :
	@$(HEADLINE)\
	&& $(RM) $(RM_FLAGS)\
		$(wildcard ./*.bom.md)\
	&& $(DONE);

#   clean *.drc
clean-drc :
	@$(HEADLINE)\
	&& $(RM) $(RM_FLAGS)\
		$(wildcard ./*.drc)\
	&& $(DONE);

#   clean *.bom
clean-bom :
	@$(HEADLINE)\
	&& $(RM) $(RM_FLAGS)\
		$(wildcard ./*.bom)\
	&& $(DONE);

#   clean generated images
clean-png :
	@$(HEADLINE)\
	&& $(RM) $(RM_FLAGS)\
		$(wildcard $(ROOT_WB_GSCHEM)*.sch.png)\
	&& $(DONE);

#   clean generated files
clean : hello\
	clean-drc\
		clean-bom\
			clean-png\
				clean-bom.md
	@$(HEADLINE)\
	&& $(DONE);
