.PHONY: all test check clean distclean install uninstall
.PRECIOUS: Makefile
.SUFFIXES: .c .o .a

prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@
man1dir = @man1dir@

CC = @CC@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
LD = @LD@
LDFLAGS = @LDFLAGS@
MKDIR_P = @MKDIR_P@
CP_FP = @CP_FP@
RM_F = @RM_F@

@USE_SYSTEM_LIBPNG_FALSE@LIB_LIBPNG =
@USE_SYSTEM_LIBPNG_TRUE@LIB_LIBPNG = @LIBPNG@
@USE_SYSTEM_ZLIB_FALSE@LIB_ZLIB =
@USE_SYSTEM_ZLIB_TRUE@LIB_ZLIB = @LIBZ@
LIBM = @LIBM@
LIBS = @LIBS@
ALL_LIBS = $(LIB_LIBPNG) $(LIB_ZLIB) $(LIBM) $(LIBS)

OPTIPNG_DIR = ../optipng
CEXCEPT_DIR = ../cexcept
OPNGREDUC_DIR = ../opngreduc
OPNGREDUC_LIB = libopngreduc.a
OPNGREDUC_MK = @OPNGREDUC_MK@
PNGXTERN_DIR = ../pngxtern
PNGXTERN_LIB = libpngxtern.a
PNGXTERN_MK = @PNGXTERN_MK@
@USE_SYSTEM_LIBPNG_FALSE@LIBPNG_DIR = ../libpng
@USE_SYSTEM_LIBPNG_FALSE@LIBPNG_LIB = libpng.a
@USE_SYSTEM_LIBPNG_TRUE@LIBPNG_LIB = -lpng
@USE_SYSTEM_LIBPNG_FALSE@LIBPNG_MK = @LIBPNG_MK@
@USE_SYSTEM_LIBPNG_FALSE@LIBPNG_MK_DEF = @LIBPNG_MK_DEF@
@USE_SYSTEM_ZLIB_FALSE@ZLIB_DIR = ../zlib
@USE_SYSTEM_ZLIB_FALSE@ZLIB_LIB = libz.a
@USE_SYSTEM_ZLIB_TRUE@ZLIB_LIB = -lz
@USE_SYSTEM_ZLIB_FALSE@ZLIB_MK = @ZLIB_MK@
GIF_DIR = ../gifread
GIF_LIB = libgifread.a
GIF_MK = @GIF_MK@
PNM_DIR = ../pnmio
PNM_LIB = libpnmio.a
PNM_MK = @PNM_MK@
TIFF_DIR = ../minitiff
TIFF_LIB = libminitiff.a
TIFF_MK = @TIFF_MK@

OPTIPNG_OBJS = \
  optipng.o \
  optim.o \
  bitset.o \
  ioutil.o \
  ratio.o \
  wildargs.o

@USE_SYSTEM_ZLIB_FALSE@OPTIPNG_DEPLIB_ZLIB = $(ZLIB_DIR)/$(ZLIB_LIB)
@USE_SYSTEM_ZLIB_TRUE@OPTIPNG_DEPLIB_ZLIB =
@USE_SYSTEM_LIBPNG_FALSE@OPTIPNG_DEPLIB_LIBPNG = $(LIBPNG_DIR)/$(LIBPNG_LIB)
@USE_SYSTEM_LIBPNG_TRUE@OPTIPNG_DEPLIB_ZLIB =

OPTIPNG_DEPLIBS = \
  $(OPNGREDUC_DIR)/$(OPNGREDUC_LIB) \
  $(PNGXTERN_DIR)/$(PNGXTERN_LIB) \
  $(OPTIPNG_DEPLIB_LIBPNG) \
  $(OPTIPNG_DEPLIB_ZLIB) \
  $(GIF_DIR)/$(GIF_LIB) \
  $(PNM_DIR)/$(PNM_LIB) \
  $(TIFF_DIR)/$(TIFF_LIB)

@USE_SYSTEM_ZLIB_FALSE@OPTIPNG_DEPINCLUDE_ZLIB = -I$(ZLIB_DIR)
@USE_SYSTEM_ZLIB_TRUE@OPTIPNG_DEPINCLUDE_ZLIB =
@USE_SYSTEM_LIBPNG_FALSE@OPTIPNG_DEPINCLUDE_LIBPNG = -I$(LIBPNG_DIR)
@USE_SYSTEM_LIBPNG_TRUE@OPTIPNG_DEPINCLUDE_LIBPNG =
OPTIPNG_DEPINCLUDES = \
  -I$(CEXCEPT_DIR) \
  $(OPTIPNG_DEPINCLUDE_ZLIB) \
  $(OPTIPNG_DEPINCLUDE_LIBPNG) \
  -I$(OPNGREDUC_DIR) \
  -I$(PNGXTERN_DIR)

OPTIPNG_TESTS = \
  test/bitset_test$(EXEEXT) \
  test/ratio_test$(EXEEXT)
OPTIPNG_TESTOBJS = \
  test/bitset_test.o \
  test/ratio_test.o
OPTIPNG_TESTOUT = *.out.png test/*.out

all: optipng$(EXEEXT)

optipng$(EXEEXT): $(OPTIPNG_OBJS) $(OPTIPNG_DEPLIBS)
	$(LD) $(LDFLAGS) -o $@ $(OPTIPNG_OBJS) $(OPTIPNG_DEPLIBS) $(ALL_LIBS)

.c.o:
	$(CC) -c $(CPPFLAGS) $(CFLAGS) $(OPTIPNG_DEPINCLUDES) -o $@ $<

optipng.o: optipng.c optipng.h bitset.h proginfo.h $(OPTIPNG_DEPLIBS)
optim.o: optim.c optipng.h bitset.h ioutil.h ratio.h $(OPTIPNG_DEPLIBS)
bitset.o: bitset.c bitset.h
ioutil.o: ioutil.c ioutil.h
ratio.o: ratio.c ratio.h
wildargs.o: wildargs.c

$(OPNGREDUC_DIR)/$(OPNGREDUC_LIB): \
  $(OPTIPNG_DEPLIB_LIBPNG)
	cd $(OPNGREDUC_DIR) && \
	$(MAKE) -f $(OPNGREDUC_MK) $(OPNGREDUC_LIB) && \
	cd $(OPTIPNG_DIR)

$(PNGXTERN_DIR)/$(PNGXTERN_LIB): \
  $(OPTIPNG_DEPLIB_LIBPNG) \
  $(GIF_DIR)/$(GIF_LIB) \
  $(PNM_DIR)/$(PNM_LIB) \
  $(TIFF_DIR)/$(TIFF_LIB)
	cd $(PNGXTERN_DIR) && \
	$(MAKE) -f $(PNGXTERN_MK) $(PNGXTERN_LIB) && \
	cd $(OPTIPNG_DIR)

$(LIBPNG_DIR)/$(LIBPNG_LIB): \
  $(OPTIPNG_DEPLIB_ZLIB)
	cd $(LIBPNG_DIR) && \
	$(MAKE) -f $(LIBPNG_MK) $(LIBPNG_MK_DEF) && \
	cd $(OPTIPNG_DIR)

$(ZLIB_DIR)/$(ZLIB_LIB):
	cd $(ZLIB_DIR) && \
	$(MAKE) -f $(ZLIB_MK) && \
	cd $(OPTIPNG_DIR)

$(GIF_DIR)/$(GIF_LIB):
	cd $(GIF_DIR) && \
	$(MAKE) -f $(GIF_MK) $(GIF_LIB) && \
	cd $(OPTIPNG_DIR)

$(PNM_DIR)/$(PNM_LIB):
	cd $(PNM_DIR) && \
	$(MAKE) -f $(PNM_MK) $(PNM_LIB) && \
	cd $(OPTIPNG_DIR)

$(TIFF_DIR)/$(TIFF_LIB):
	cd $(TIFF_DIR) && \
	$(MAKE) -f $(TIFF_MK) $(TIFF_LIB) && \
	cd $(OPTIPNG_DIR)

test: local-test test-gifread test-minitiff

.PHONY: local-test
local-test: optipng$(EXEEXT) $(OPTIPNG_TESTS)
	-@$(RM_F) pngtest.out.png
	./optipng$(EXEEXT) -o1 -q img/pngtest.png -out=pngtest.out.png
	-@echo optipng ... ok
	test/bitset_test$(EXEEXT) > test/bitset_test.out
	-@echo bitset_test ... ok
	test/ratio_test$(EXEEXT) > test/ratio_test.out
	-@echo ratio_test ... ok

test/bitset_test$(EXEEXT): test/bitset_test.o bitset.o
	$(LD) $(LDFLAGS) -o $@ \
	  test/bitset_test.o bitset.o $(LIBS)

test/ratio_test$(EXEEXT): test/ratio_test.o ratio.o
	$(LD) $(LDFLAGS) -o $@ \
	  test/ratio_test.o ratio.o $(LIBS)

test/bitset_test.o: test/bitset_test.c bitset.h
	$(CC) -c -I. $(CPPFLAGS) $(CFLAGS) -o $@ $*.c

test/ratio_test.o: test/ratio_test.c ratio.h
	$(CC) -c -I. $(CPPFLAGS) $(CFLAGS) -o $@ $*.c

.PHONY: test-gifread
test-gifread:
	cd $(GIF_DIR) && \
	$(MAKE) -f $(GIF_MK) test && \
	cd $(OPTIPNG_DIR)

.PHONY: test-minitiff
test-minitiff:
	cd $(TIFF_DIR) && \
	$(MAKE) -f $(TIFF_MK) test && \
	cd $(OPTIPNG_DIR)

check: test

clean: \
  local-clean \
  clean-opngreduc \
  clean-pngxtern-gif-pnm-tiff \
  clean-libpng \
  clean-zlib

.PHONY: local-clean
local-clean:
	-$(RM_F) optipng$(EXEEXT) $(OPTIPNG_OBJS)
	-$(RM_F) $(OPTIPNG_TESTS) $(OPTIPNG_TESTOBJS) $(OPTIPNG_TESTOUT)

.PHONY: clean-opngreduc
clean-opngreduc:
	cd $(OPNGREDUC_DIR) && \
	$(MAKE) -f $(OPNGREDUC_MK) clean && \
	cd $(OPTIPNG_DIR)

.PHONY: clean-pngxtern-gif-pnm-tiff
clean-pngxtern-gif-pnm-tiff:
	cd $(PNGXTERN_DIR) && \
	$(MAKE) -f $(PNGXTERN_MK) clean && \
	cd $(OPTIPNG_DIR)
	cd $(GIF_DIR) && \
	$(MAKE) -f $(GIF_MK) clean && \
	cd $(OPTIPNG_DIR)
	cd $(PNM_DIR) && \
	$(MAKE) -f $(PNM_MK) clean && \
	cd $(OPTIPNG_DIR)
	cd $(TIFF_DIR) && \
	$(MAKE) -f $(TIFF_MK) clean && \
	cd $(OPTIPNG_DIR)

.PHONY: clean-libpng
clean-libpng:
@USE_SYSTEM_LIBPNG_FALSE@	cd $(LIBPNG_DIR) && \
@USE_SYSTEM_LIBPNG_FALSE@	$(MAKE) -f $(LIBPNG_MK) $(LIBPNG_MK_DEF) clean && \
@USE_SYSTEM_LIBPNG_FALSE@	cd $(OPTIPNG_DIR)

.PHONY: clean-zlib
clean-zlib:
@USE_SYSTEM_ZLIB_FALSE@	cd $(ZLIB_DIR) && \
@USE_SYSTEM_ZLIB_FALSE@	$(MAKE) -f $(ZLIB_MK) clean && \
@USE_SYSTEM_ZLIB_FALSE@	cd $(OPTIPNG_DIR)

distclean: \
  local-distclean \
  distclean-opngreduc \
  distclean-pngxtern-gif-pnm-tiff \
  distclean-libpng \
  distclean-zlib

.PHONY: local-distclean
local-distclean: local-clean
	-$(RM_F) Makefile
	cd man && \
	$(MAKE) distclean && \
	cd ..

.PHONY: distclean-opngreduc
distclean-opngreduc:
	cd $(OPNGREDUC_DIR) && \
	$(MAKE) -f $(OPNGREDUC_MK) distclean && \
	cd $(OPTIPNG_DIR)

.PHONY: distclean-pngxtern-gif-pnm-tiff
distclean-pngxtern-gif-pnm-tiff:
	cd $(PNGXTERN_DIR) && \
	$(MAKE) -f $(PNGXTERN_MK) distclean && \
	cd $(OPTIPNG_DIR)
	cd $(GIF_DIR) && \
	$(MAKE) -f $(GIF_MK) distclean && \
	cd $(OPTIPNG_DIR)
	cd $(PNM_DIR) && \
	$(MAKE) -f $(PNM_MK) distclean && \
	cd $(OPTIPNG_DIR)
	cd $(TIFF_DIR) && \
	$(MAKE) -f $(TIFF_MK) distclean && \
	cd $(OPTIPNG_DIR)

.PHONY: distclean-libpng
distclean-libpng:
@USE_SYSTEM_LIBPNG_FALSE@	cd $(LIBPNG_DIR) && \
@USE_SYSTEM_LIBPNG_FALSE@	$(MAKE) -f $(LIBPNG_MK) $(LIBPNG_MK_DEF) @LIBPNG_DISTCLEAN@ && \
@USE_SYSTEM_LIBPNG_FALSE@	@LIBPNG_DISTCLEAN_XCMD@ && \
@USE_SYSTEM_LIBPNG_FALSE@	cd $(OPTIPNG_DIR)

.PHONY: distclean-zlib
distclean-zlib:
@USE_SYSTEM_ZLIB_FALSE@	cd $(ZLIB_DIR) && \
@USE_SYSTEM_ZLIB_FALSE@	$(MAKE) -f $(ZLIB_MK) @ZLIB_DISTCLEAN@ && \
@USE_SYSTEM_ZLIB_FALSE@	cd $(OPTIPNG_DIR)

install: optipng$(EXEEXT)
	$(MKDIR_P) $(DESTDIR)$(bindir)
	$(MKDIR_P) $(DESTDIR)$(man1dir)
	-@$(RM_F) $(DESTDIR)$(bindir)/optipng$(EXEEXT)
	-@$(RM_F) $(DESTDIR)$(man1dir)/optipng.1
	$(CP_FP) optipng$(EXEEXT) $(DESTDIR)$(bindir)
	$(CP_FP) man/optipng.1 $(DESTDIR)$(man1dir)

uninstall:
	-$(RM_F) $(DESTDIR)$(bindir)/optipng$(EXEEXT)
	-$(RM_F) $(DESTDIR)$(man1dir)/optipng.1
