ifndef DUCE
  DUCE := $(shell if [ `which ocamlduce` ]; then echo yes; else echo no; fi)
endif

LIBNAME = textile
VERSION :=$(shell head -n 1 VERSION)

P5FILES = textile.ml
FILES = $(P5FILES)
DUCEFILES = textile_duce.ml

P5C   = ocamlfind ocamlc -g -thread $(P5LIB)
P5OPT = ocamlfind ocamlopt -g -thread $(P5LIB)
P5DOC = ocamlfind ocamldoc $(P5LIB)
P5DEP = ocamlfind ocamldep
P5LIB = -package $(P5PACKAGES) -pp 'camlp5r pa_extend.cmo pa_fstream.cmo q_MLast.cmo'
P5PACKAGES = camlp5.gramlib,camlp5.fstream,extlib

DUCEC   = ocamlducefind ocamlc -g -thread $(DUCELIB)
DUCEOPT = ocamlducefind ocamlopt -g -thread $(DUCELIB)
DUCEDOC = ocamlducefind ocamldoc $(DUCELIB)
DUCEDEP = ocamlducefind ocamldep
DUCELIB = -package $(DUCEPACKAGES)
DUCEPACKAGES = ocamlduce,ocsigen

CAMLC   = ocamlfind ocamlc -g $(LIB)
CAMLOPT = ocamlfind ocamlopt -g $(LIB)
CAMLDOC = ocamlfind ocamldoc $(LIB)
CAMLDEP = ocamlfind ocamldep
LIB =# -package

OBJS        = $(FILES:.ml=.cmo)
OPTOBJS     = $(FILES:.ml=.cmx)
DUCEOBJS    = $(DUCEFILES:.ml=.cmo)
DUCEOPTOBJS = $(DUCEFILES:.ml=.cmx)

CMA  = textile.cma
CMXA = textile.cmxa
CMXS = textile.cmxs
DUCECMA  = textile_duce.cma
DUCECMXA = textile_duce.cmxa
DUCECMXS = textile_duce.cmxs

all: byte native shared

ifeq "$(DUCE)" "yes"
byte:   $(CMA)  $(DUCECMA)  META
native: $(CMXA) $(DUCECMXA) META
shared: $(CMXS) $(DUCECMXS) META
else
byte:   $(CMA)  META
native: $(CMXA) META
shared: $(CMXS) META
endif

META: META.in META.duce.in VERSION
	cp META.in META
	sed "s/_NAME_/$(LIBNAME)/" -i META
	sed "s/_VERSION_/$(VERSION)/" -i META
	sed "s/_REQUIRES_/$(P5PACKAGES)/" -i META
	sed "s/_BYTE_/$(CMA)/" -i META
	sed "s/_NATIVE_/$(CMXA)/" -i META
	sed "s/_SHARED_/$(CMXS)/" -i META
ifeq "$(DUCE)" "yes"
	cp META.duce.in META.duce
	sed "s/_NAME_/duce/" -i META.duce
	sed "s/_REQUIRES_/$(DUCEPACKAGES)/" -i META.duce
	sed "s/_BYTE_/$(DUCECMA)/" -i META.duce
	sed "s/_NATIVE_/$(DUCECMXA)/" -i META.duce
	sed "s/_SHARED_/$(DUCECMXS)/" -i META.duce
	cat META.duce >> META
endif

textile.cmo: textile.ml textile.cmi
	$(P5C) -c $<
textile.cmx: textile.ml textile.cmi
	$(P5OPT) -c $<
textile.cmi: textile.mli
	$(P5C) -c $<

textile_duce.cmo: textile_duce.ml textile_duce.cmi
	$(DUCEC) -c $<
textile_duce.cmx: textile_duce.ml textile_duce.cmi
	$(DUCEOPT) -c $<
textile_duce.cmi: textile_duce.mli
	$(DUCEC) -c $<

xhtmlpretty_duce.cmo: xhtmlpretty_duce.ml xhtmlpretty_duce.cmi
	$(DUCEC) -c $<
xhtmlpretty_duce.cmx: xhtmlpretty_duce.ml xhtmlpretty_duce.cmi
	$(DUCEOPT) -c $<
xhtmlpretty_duce.cmi: xhtmlpretty_duce.mli
	$(DUCEC) -c $<

test.cmo: $(CMA) test.ml
	$(CAMLC) -package $(P5PACKAGES) -c $^
test: $(CMA) test.cmo
	$(CAMLC) -package $(P5PACKAGES) -linkpkg -o test $^

$(CMA): $(OBJS) textile.cmo
	$(CAMLC) -a -o $@ $(OBJS) textile.cmo
$(DUCECMA): $(DUCEOBJS)
	$(CAMLC) -a -o $@ $(DUCEOBJS)

$(CMXA): $(OPTOBJS)
	$(CAMLOPT) -a -o $@ $(OPTOBJS)
$(DUCECMXA): $(DUCEOPTOBJS)
	$(CAMLOPT) -a -o $@ $(DUCEOPTOBJS)

$(CMXS): $(OPTOBJS)
	$(CAMLOPT) -shared -o $(CMXS) $(OPTOBJS)
$(DUCECMXS): $(DUCEOPTOBJS)
	$(CAMLOPT) -shared -o $(CMXS) $(DUCEOPTOBJS)

itextile.cmx: $(CMXA) itextile.ml
	$(CAMLOPT) $(CMXA) -c itextile.ml
itextile: $(CMXA) itextile.cmx
	$(CAMLOPT) $(P5LIB) -linkpkg -o $@ $^

itextile_duce.cmx: $(DUCECMXA) itextile_duce.ml xhtmlpretty_duce.cmx
	$(DUCEOPT) -c itextile_duce.ml
itextile_duce: $(CMXA) $(DUCECMXA) xhtmlpretty_duce.cmx itextile_duce.cmx
	$(DUCEOPT) $(P5LIB) -linkpkg -o $@ $^

tests: itextile itextile_duce
	make -C tests/

install:
	ocamlfind install $(LIBNAME) META *.cmi *.cma *.cmxa *.cmxs *.a

uninstall:
	ocamlfind remove $(LIBNAME)

.SUFFIXES:
.SUFFIXES: .ml .mli .cmo .cmi .cmx

.PHONY: doc

.ml.cmo:
	$(CAMLC) -c $<
.mli.cmi:
	$(CAMLC) -c $<
.ml.cmx:
	$(CAMLOPT) -c $<

doc:
	-mkdir -p doc/textile
	$(P5DOC) -d doc/textile -html -colorize-code $(P5FILES:.ml=.mli)
ifeq "$(DUCE)" "yes"
	-mkdir -p doc/textile_duce
	$(DUCEDOC) -package textile -d doc/textile_duce -html -colorize-code $(DUCEFILES:.ml=.mli)
endif

clean:
	-rm -f *.cm[ioxa] *.o *.a *.cmx[as] *~
	-rm -rf doc
	-rm -f META META.duce
	-rm -f itextile itextile_duce test
	make -C tests/ clean
