#
# Makefile for generating the documentation for the Symbiosis system.
#


#
# Where the XML snippets are kept
#
xml_input_dir := xml/
txt_input_dir := txt/

#
# The filename for the XML and PDF outputs
#
book_name := symbiosis

#
# This is where the build takes place
#
build_dir  := build
txt_build  := $(build_dir)/$(book_name).txt
xml_build  := $(build_dir)/$(book_name).xml
hg_log_xml := $(build_dir)/$(book_name)-log-hg.xml
git_log_xml := $(build_dir)/$(book_name)-log-git.xml
releaseinfo_xml := $(build_dir)/$(book_name)-releaseinfo.xml
releaseinfo_inputs := 

#
# This is where the output is generated.
#
output_dir  := output
txt_output  := $(output_dir)/$(book_name).txt
xml_output  := $(output_dir)/$(book_name).xml
pdf_output  := $(output_dir)/$(book_name).pdf
html_output_dir := $(output_dir)
html_output := $(html_output_dir)/$(book_name).html $(html_output_dir)/$(book_name)-chunked.html
index_output := $(output_dir)/index.html

#
# These are a couple of asciidoc config files
#
asciidoc_docinfo := config/$(book_name)-docinfo.xml
asciidoc_config  := config/$(book_name).conf
asciidoc_docinfo_build := $(build_dir)/$(notdir $(asciidoc_docinfo))
asciidoc_base    := /usr/share/asciidoc

#
# This defines where we get the snippets from.  The regex could be cleaned up.
#
txt_inputs  := $(sort $(shell find $(txt_input_dir) -mindepth 1 -regextype posix-basic -type f -regex '^.*/[a-z0-9][a-z0-9-]*\.txt$$'))

#
# This defines which XML inputs are needed for the final build
#
xml_inputs := $(xml_build) $(asciidoc_docinfo_build) 

#
# This is where static stuff should be copied from
#
html_inputs     := xsl/common.xsl xsl/xhtml.xsl
html_input_dirs := stylesheets icons figures 
html_output_dirs := $(foreach d,$(html_input_dirs),$(html_output_dir)/$(d))


#
# Set the xsltproc options
#
xsltproc_opts := 
dblatex_opts  :=

hg := $(shell which hg)

ifneq "$(wildcard .hg)" ""
	#
	# Mercurial revision. 
	#
  hg_id := $(shell hg id -i)

  ifneq ($(hg_id),)
		#
		# If hg is installed, set the release info.
		#
		xml_inputs         += $(releaseinfo_xml)
		releaseinfo_inputs += $(hg_log_xml)

		#
		# If the repo has been changed since a commit, mark this as draft.
		#
		ifneq ($(subst +,,$(hg_id)),$(hg_id))
			hg_id         := $(subst +,,$(hg_id))
		  xsltproc_opts += --stringparam draft.mode yes --stringparam html.stylesheet stylesheets/draft.css
		  dblatex_opts  += --param draft.mode=yes
		endif
	endif
endif

#
# Now do this with git
#
git := $(shell which git)

ifneq "$(wildcard .git)" ""
	#
	# Mercurial revision. 
	#
  git_branch  := $(shell git rev-parse --abbrev-ref HEAD) 

  ifneq ($(git_branch),)
    git_changes := $(shell git ls-files -m)
    git_id  := $(shell git rev-parse $(git_branch))

		#
		# If git is installed, set the release info.
		#
		#xml_inputs    += $(releaseinfo_xml)
		#releaseinfo_inputs += $(git_log_xml)

		#
		# If the repo has been changed since a commit, mark this as draft.
		#
		ifneq ($(git_changes),)
		  xsltproc_opts += --stringparam draft.mode yes --stringparam html.stylesheet stylesheets/draft.css
		  dblatex_opts  += --param draft.mode=yes
		endif
	endif
endif


#
# Make everything :)
#
all: xml pdf html

$(build_dir):
	mkdir -p $@

$(output_dir):
	mkdir -p $@

#
# Assemble all the text together into one big file.
#
$(txt_build): $(txt_inputs) $(build_dir) Makefile
	$(RM) $(txt_build)
	for s in $(txt_inputs) ; do \
	  cat $$s >> $(txt_build);\
	done

#
# Copy the XML document info over for inclusion.
#
$(asciidoc_docinfo_build): $(asciidoc_docinfo)
	cp -a $< $@

#
# Make the XML for use by dblatex/xsltproc
#
$(xml_build): $(txt_build) $(asciidoc_docinfo_build) $(asciidoc_config)
	asciidoc -a docinfo -b docbook -d book -f $(asciidoc_config) -o $@ $<

$(hg_log_xml): $(build_dir)
	hg log -r 'reverse(:$(hg_id))' --style xml > $@

$(git_log_xml): $(build_dir)
	git log > $@

$(releaseinfo_xml): $(releaseinfo_inputs) $(build_dir)
	xsltproc $(xsltproc_opts) --output $@ xsl/hg-releaseinfo.xsl $<

#
# Directories of stuff needed for xml/html output.  I've used a template here
# since I'd have to define the same rule over and over again, otherwise.
#
define files_template
$(1)_inputs := $(shell find static/$(1) -mindepth 1 -maxdepth 1)

$(html_output_dir)/$(1): $$($(1)_inputs)
	[ -d $(html_output_dir)/$(1) ] || mkdir -p $(html_output_dir)/$(1)
	cp -r $$($(1)_inputs) $(html_output_dir)/$(1)
	touch $$@
endef

$(foreach d,$(html_input_dirs),$(eval $(call files_template,$(d))))

#
# Build rules for final outputs
#
xml: $(xml_output)
$(xml_output): $(xml_inputs)
	[ -d $(dir $@) ] || mkdir -p $(dir $@)
	echo $(xml_inputs)
	xmllint --nonet --xinclude --postvalid --noent --format --encode utf-8 --output $@ $<

pdf: $(pdf_output)
$(pdf_output): $(xml_output) xsl/latex.xsl xsl/common.xsl $(figures_inputs) $(icons_inputs) config/$(book_name).sty
	[ -d $(dir $@) ] || mkdir -p $(dir $@)
	dblatex $(dblatex_opts) -s config/$(book_name).sty -p xsl/latex.xsl --fig-path=./static --fig-path=./static/icons -o $@ $<

html: $(html_output) $(index_output)

$(output_dir)/$(book_name).html: $(xml_output) $(foreach dir,$(html_input_dirs),$(html_output_dir)/$(dir)) static/index.html xsl/xhtml-single.xsl  xsl/xhtml-common.xsl xsl/common.xsl xsl/docbook $(output_dir)
	cd $(dir $@) && xsltproc $(xsltproc_opts) -o $(notdir $@) ../xsl/xhtml-single.xsl $(notdir $<)

$(output_dir)/$(book_name)-chunked.html: $(xml_output) $(foreach dir,$(html_input_dirs),$(html_output_dir)/$(dir)) static/index.html xsl/xhtml-chunked.xsl xsl/xhtml-common.xsl xsl/common.xsl xsl/docbook $(output_dir)
	cd $(dir $@) && xsltproc $(xsltproc_opts) -o $(notdir $@) ../xsl/xhtml-chunked.xsl $(notdir $<)

$(index_output): static/index.html $(output_dir)
	cp $< $(html_output_dir)

xsl/docbook:
	if [ -d /usr/share/xml/docbook/stylesheet/docbook-xsl ] ; then \
		ln -sf /usr/share/xml/docbook/stylesheet/docbook-xsl $@ ; \
	elif [ -d /usr/share/xml/docbook/stylesheet/nwalsh ] ; then \
		ln -sf /usr/share/xml/docbook/stylesheet/nwalsh $@ ; \
	fi

#
# The README
#
README.xml: README $(asciidoc_config)
	asciidoc -b docbook -f $(asciidoc_config) -o $@ $<

README.html: README.xml
	xsltproc -o $@ xsl/README.xsl $<

README.pdf: README.xml
	dblatex $(dblatex_opts) -p xsl/latex.xsl -I . --fig-path=static/  -o $@ $<

#
# Do a pull / push / pull
#
update: 
	@if [ "x`hg status`x" != "xx" ] ; then echo "Uncomitted changes (check 'hg status')." ; exit 1 ; fi
	# Not sure how to check to see if we need a pull or not..
	@echo "Pulling..." ; hg pull -u
	@if [ "x`hg heads --template 'a\n' | wc -l`x" != "x1x" ] ; then echo "Merging..." ; hg merge ; echo "Now run hg commit -m 'merge'" ; exit 1 ; fi
	@if [ "x`hg id -i -r tip`x" != "x`hg id -i -r tip default`x" ] ; then echo "Pushing..." ; hg push ; fi

#
# Upload to local web root for testing.
#
upload: update clean all
	mkdir -p $(HOME)/htdocs/docs/$(hg_id)
	rsync -vzr --delete $(output_dir)/ $(HOME)/htdocs/docs/$(hg_id)
	ln -sf $(HOME)/htdocs/docs/$(hg_id) $(HOME)/htdocs/docs/latest

clean:
	$(RM) -r $(build_dir)
	$(RM) -r $(output_dir)
	$(RM) xsl/docbook

.PHONY: clean xml pdf html all upload

