##
 # Makefile
 # Copyright (C) 2010 - 2013 Peter Belkner <pbelkner@snafu.de>
 # 
 # This program 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.
 # 
 # This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 ##
include config.mak
include $(SRCDIR)/in_ffsox/version.mak

###############################################################################
MAKENSIS=$(NSIS)/makensis.exe

###############################################################################
.PHONY: all install release
all: $(ALL)
install: $(INSTALL)
release: $(RELEASE)

###############################################################################
.PHONY: all-full all-tiny
all-full:
	$(MAKE) full/build/in_ffsox/in_ffsox.dll MODE=full
all-tiny:
	$(MAKE) tiny/build/in_ffsox/in_ffsox.dll MODE=tiny

###############################################################################
.PHONY: install-full install-tiny install-recursive
install-full:
	$(MAKE) install-recursive MODE=full
install-tiny:
	$(MAKE) install-recursive MODE=tiny

###############################################################################
.PHONY: release-full release-tiny release-recursive
release-full:
	$(MAKE) release-recursive MODE=full
release-tiny:
	$(MAKE) release-recursive MODE=tiny

###############################################################################
AVUTIL=avutil-$(AVUTIL_VER)
SWRESAMPLE=swresample-$(SWRESAMPLE_VER)
SWSCALE=swscale-$(SWSCALE_VER)
POSTPROC=postproc-$(POSTPROC_VER)
AVCODEC=avcodec-$(AVCODEC_VER)
AVFORMAT=avformat-$(AVFORMAT_VER)
AVFILTER=avfilter-$(AVFILTER_VER)
FFMPEG_DLLS:=$(AVUTIL).dll
FFMPEG_DLLS+=$(SWRESAMPLE).dll
FFMPEG_DLLS+=$(SWSCALE).dll
FFMPEG_DLLS+=$(POSTPROC).dll
FFMPEG_DLLS+=$(AVCODEC).dll
FFMPEG_DLLS+=$(AVFORMAT).dll
FFMPEG_DLLS+=$(AVFILTER).dll
FFMPEG_TARGETS:=$(patsubst %,$(MODE)/bin/%,$(FFMPEG_DLLS))
FFMPEG_TARGETS+=$(patsubst %.dll,$(MODE)/lib/%.def,$(FFMPEG_DLLS))
FFMPEG_DELAYLOADS:=$(patsubst %,$(MODE)/lib/delayload/lib%.a,$(FFMPEG_DLLS))

SOX_DLLS:=libsox-$(LIBSOX_VER).dll
SOX_TARGETS:=$(patsubst %,bin/%,$(SOX_DLLS))

define INSTALL
  mkdir -p $(@D)
  cp $< -p $(@D)
endef

###############################################################################
SFURL=http://sourceforge.net/projects/$1/files/$2/download

define DOWNLOAD
  mkdir -p $(@D)
  wget -O $@ $1
endef

###############################################################################
IN_FFSOX:=in_ffsox
BUILDDIR:=$(MODE)/build/$(IN_FFSOX)

IN_FFSOX_DEPS:=$(MODE)/lib/libffsox.a
IN_FFSOX_DEPS+=lib/lib1770.a
IN_FFSOX_DEPS+=lib/libpb.a
IN_FFSOX_DEPS+=lib/delayload/libsox-$(LIBSOX_VER).dll.a
IN_FFSOX_DEPS+=lib/delayload/libdlgitemurl.dll.a
IN_FFSOX_DEPS+=$(SRCDIR)/in_ffsox/version.mak

IN_FFSOX_OPTS:='--bindir=$(BINDIR)'
IN_FFSOX_OPTS+=--mode=$(MODE)
IN_FFSOX_OPTS+='--msvc=$(MSVC)'
IN_FFSOX_OPTS+='--mssdk=$(MSSDK)'
IN_FFSOX_OPTS+='--wasdk=$(WASDK)'
IN_FFSOX_OPTS+='--ffmpeg-src=$(PWD)/unpack/ffmpeg'
IN_FFSOX_OPTS+='--ffmpeg-build=$(PWD)/$(MODE)/build/ffmpeg'
IN_FFSOX_OPTS+='CPPFLAGS=-I$(PWD)/$(MODE)/include -I$(PWD)/include'
IN_FFSOX_OPTS+='LDFLAGS=-L$(PWD)/$(MODE)/lib -L$(PWD)/lib'

$(MODE)/build/$(IN_FFSOX)/in_ffsox.dll: FORCE
$(MODE)/build/$(IN_FFSOX)/in_ffsox.dll: $(MODE)/build/$(IN_FFSOX)/Makefile
	cd $(<D) && $(MAKE)
$(MODE)/build/$(IN_FFSOX)/Makefile: $(IN_FFSOX_DEPS)
$(MODE)/build/$(IN_FFSOX)/Makefile: OPTS=$(IN_FFSOX_OPTS)

### INSTALL ###################################################################
install-recursive: $(patsubst %,install-mode-%,$(FFMPEG_DLLS))
install-recursive: $(patsubst %,install-%,$(SOX_DLLS))
install-recursive: install-libdlgitemurl.dll
install-recursive: $(BUILDDIR)/in_ffsox.dll
	mkdir -p '$(BINDIR)'
	cp -p $< '$(BINDIR)'
install-%: bin/%
	mkdir -p '$(BINDIR)/in_ffsox'
	cp -p $< '$(BINDIR)/in_ffsox'
install-mode-%: $(MODE)/bin/%
	mkdir -p '$(BINDIR)/in_ffsox'
	cp -p $< '$(BINDIR)/in_ffsox'

### RELEASE ###################################################################
RELNAME:=$(APP)-$(VERSION)
RELPFX:=$(RELDIR)/$(RELNAME)/$(RELNAME)

### BIN NSIS ###################
BINRELDEPS:=$(BUILDDIR)/in_ffsox.dll
BINRELDEPS+=$(patsubst %,$(BUILDDIR)/in_ffsox/%,$(FFMPEG_DLLS))
BINRELDEPS+=$(patsubst %,$(BUILDDIR)/in_ffsox/%,$(SOX_DLLS))
BINRELDEPS+=$(BUILDDIR)/in_ffsox/libdlgitemurl.dll
BINRELDEPS+=$(BUILDDIR)/in_ffsox/COPYING
BINRELDEPS+=FORCE

define NSIPATCH
  sed -e 's,@@VERSION@@,$(VERSION),g' \
      -e 's,@@RELPFX@@,$(shell $(PWD)/bin/p2w $(RELPFX) 2),g' \
	  $< >$@
endef

release-recursive: $(RELPFX).exe
$(RELPFX).exe: $(BUILDDIR)/$(RELNAME).nsi
	rm -f $@
	mkdir -p $(@D)
	cd $(<D) && '$(MAKENSIS)' $(<F)
#.INTERMEDIATE: $(BUILDDIR)/$(RELNAME).nsi
$(BUILDDIR)/$(RELNAME).nsi: $(SRCDIR)/in_ffsox.nsi $(BINRELDEPS) bin/p2w
	$(NSIPATCH)
bin/p2w: $(SRCDIR)/p2w.c
	mkdir -p $(@D)
	gcc -o $@ $<

### BIN 7z #####################
#release-recursive: $(RELPFX).7z
$(RELPFX).7z: $(BINRELDEPS)
	rm -f $@
	mkdir -p $(@D)
	cd $(<D) && 7za a $@ $(subst $(<D)/,,$^)

### BIN dll.7z #################
release-recursive: $(RELPFX).dll.7z
$(RELPFX).dll.7z: $(BUILDDIR)/in_ffsox.dll
	rm -f $@
	mkdir -p $(@D)
	cd $(<D) && 7za a $@ $(subst $(<D)/,,$^)

### SRC ########################
release-recursive: $(RELPFX)-src.tar.gz
$(RELPFX)-src.tar.gz: FORCE
	mkdir -p $(@D)
	cd $(SRCDIR) && tar cfvz $@ ./*  --transform 's,^\.,$(RELNAME),g'

### TOOLS ######################
release-recursive: $(RELPFX)-tools.tar.gz
$(RELPFX)-tools.tar.gz: FORCE
	mkdir -p $(@D)
	cd $(TOOLDIR) && tar cfvz $@ ./* --transform 's,^\.,$(RELNAME)/tools,g'

################################
$(MODE)/build/in_ffsox/in_ffsox/%.dll: $(MODE)/bin/%.dll
	mkdir -p $(@D)
	cp -p $< $(@D)
$(MODE)/build/in_ffsox/in_ffsox/%.dll: bin/%.dll
	mkdir -p $(@D)
	cp -p $< $(@D)
$(MODE)/build/in_ffsox/in_ffsox/%: $(SRCDIR)/%
	mkdir -p $(@D)
	cp -p $< $(@D)

### FFSOX #####################################################################
LIBFFSOX:=libffsox
LIBFFSOX_DEPS:=lib/libpb.a
LIBFFSOX_DEPS+=lib/lib1770.a
LIBFFSOX_DEPS+=$(FFMPEG_DELAYLOADS)
LIBFFSOX_DEPS+=$(SOX_TARGETS)
LIBFFSOX_DEPS+=bin/libdlgitemurl.dll

LIBFFSOX_OPTS:=--prefix=$(PWD)/$(MODE)
LIBFFSOX_OPTS+=--disable-magick
LIBFFSOX_OPTS+=--disable-lame
LIBFFSOX_OPTS+=--disable-replaygain
#LIBFFSOX_OPTS+=--disable-dlgitemurl
LIBFFSOX_OPTS+='CPPFLAGS=-I$(PWD)/include'

$(MODE)/lib/libffsox.a: $(MODE)/build/$(LIBFFSOX)/Makefile
	cd $(<D) && $(MAKE) && $(MAKE) install
$(MODE)/build/$(LIBFFSOX)/Makefile: $(LIBFFSOX_DEPS)
$(MODE)/build/$(LIBFFSOX)/Makefile: OPTS=$(LIBFFSOX_OPTS)

### FFMPEG ####################################################################
#FFMPEG_LINK_STATIC_LIBS=X
FFMPEG:=ffmpeg
FFMPEG_DEPS:=lib/libpthread.a
FFMPEG_DEPS+=lib/libopus.a
FFMPEG_DEPS+=lib/libiconv.a
FFMPEG_DEPS+=lib/libbz2.a
FFMPEG_DEPS+=lib/libz.a

FFMPEG_OPTS:=--prefix=$(PWD)/$(MODE)
FFMPEG_OPTS+=--enable-gpl
FFMPEG_OPTS+=--enable-version3
FFMPEG_OPTS+=--enable-shared
FFMPEG_OPTS+=--disable-doc
FFMPEG_OPTS+=--disable-w32threads
FFMPEG_OPTS+=--disable-os2threads
FFMPEG_OPTS+=--enable-libopus

ifeq (tiny,$(MODE)) # [
FFMPEG_OPTS+=--disable-encoders
FFMPEG_OPTS+=--disable-decoders
FFMPEG_OPTS+=--disable-muxers
FFMPEG_OPTS+=--disable-demuxers
FFMPEG_OPTS+=--disable-hwaccels
FFMPEG_OPTS+=--disable-parsers
#FFMPEG_OPTS+=--disable-filter=elbg
#FFMPEG_OPTS+=--disable-parser=hevc
# ???
#FFMPEG_OPTS+=--enable-dct
FFMPEG_OPTS+=--disable-dxva2
# decoders
FFMPEG_OPTS+=--enable-decoder=pcm_s16le
FFMPEG_OPTS+=--enable-decoder=pcm_s24le
FFMPEG_OPTS+=--enable-decoder=pcm_dvd
FFMPEG_OPTS+=--enable-decoder=flac
FFMPEG_OPTS+=--enable-decoder=wavpack
FFMPEG_OPTS+=--enable-decoder=vorbis
FFMPEG_OPTS+=--enable-decoder=libopus
FFMPEG_OPTS+=--enable-decoder=vp3
FFMPEG_OPTS+=--enable-decoder=vp5
FFMPEG_OPTS+=--enable-decoder=vp6
FFMPEG_OPTS+=--enable-decoder=vp6a
FFMPEG_OPTS+=--enable-decoder=vp6f
FFMPEG_OPTS+=--enable-decoder=vp7
FFMPEG_OPTS+=--enable-decoder=vp8
FFMPEG_OPTS+=--enable-decoder=vp9
FFMPEG_OPTS+=--enable-decoder=theora
# demuxers
FFMPEG_OPTS+=--enable-demuxer=pcm_s16le
FFMPEG_OPTS+=--enable-demuxer=pcm_s24le
FFMPEG_OPTS+=--enable-demuxer=flac
FFMPEG_OPTS+=--enable-demuxer=wav
FFMPEG_OPTS+=--enable-demuxer=ogg
FFMPEG_OPTS+=--enable-demuxer=matroska
# parsers
FFMPEG_OPTS+=--enable-parser=png
FFMPEG_OPTS+=--enable-parser=vorbis
FFMPEG_OPTS+=--enable-parser=vp3
FFMPEG_OPTS+=--enable-parser=vp8
FFMPEG_OPTS+=--enable-parser=vp9
endif # ]

FFMPEG_LDFLAGS:=-static-libgcc
FFMPEG_LDFLAGS+=-L$(PWD)/lib
#FFMPEG_LDSOFLAGS+=-lole32
FFMPEG_OPTS+='--extra-ldflags=$(FFMPEG_LDFLAGS)'
#FFMPEG_OPTS+='--extra-ldsoflags=$(FFMPEG_LDSOFLAGS)'

$(FFMPEG_TARGETS): $(MODE)/build/$(FFMPEG)/Makefile
	cd $(<D) && $(MAKE) && $(MAKE) install
$(MODE)/build/$(FFMPEG)/Makefile: $(FFMPEG_DEPS)
$(MODE)/build/$(FFMPEG)/Makefile: OPTS=$(FFMPEG_OPTS)

$(TOOLDIR)/ffmpeg-snapshot.tar.bz2:
	$(call DOWNLOAD,http://ffmpeg.org/releases/$(@F))

$(MODE)/lib/delayload/lib%.dll.a: $(MODE)/lib/delayload/%.def
	dlltool -d $< --output-delaylib $@

$(MODE)/lib/delayload/%.def: $(MODE)/lib/%.def
	@mkdir -p $(@D)
	@echo LIBRARY "$*.dll" > $@
	@cat $< >> $@

### SOX #######################################################################
#SOX_SHARED=X
SOXVER:=14.4.2
SOX:=sox-$(SOXVER)
SOX_DEPS:=lib/libpthread.a
SOX_DEPS+=lib/libgomp.a
ifneq (x,x$(SOX_SHARED)) # [
SOX_DEPS+=lib/libgcc_s.a
endif # ]
SOX_LDFLAGS+=-shared
SOX_LDFLAGS+=-static-libgcc
SOX_LDFLAGS+=-Llib
SOX_LDLIBS+=-lgomp
SOX_LDLIBS+=-lpthread
SOX_LDLIBS+=-lwinmm

SOX_OPTS:=--prefix=$(PWD)
ifneq (x,x$(SOX_SHARED)) # [
SOX_OPTS+=--enable-shared
SOX_OPTS+=--disable-static
else # ] [
SOX_OPTS+=--disable-shared
endif # ]
SOX_OPTS+=--without-ladspa
SOX_OPTS+=--with-ffmpeg=no
SOX_OPTS+='LDFLAGS=-static-libgcc -L$(PWD)/lib'

lib/delayload/libsox-$(LIBSOX_VER).dll.a: \
		lib/delayload/libsox-$(LIBSOX_VER).def
	dlltool -d $< --output-delaylib $@
lib/delayload/libsox-$(LIBSOX_VER).def: lib/libsox.def
	mkdir -p $(@D)
	echo 'LIBRARY "libsox-$(LIBSOX_VER).dll"' > $@
	cat $< >> $@
bin/libsox-$(LIBSOX_VER).dll lib/libsox.dll.a: lib/libsox.def lib/libsox.a 
	gcc -o bin/libsox-$(LIBSOX_VER).dll -Wl,--out-implib,lib/libsox.dll.a $^ \
			$(SOX_LDFLAGS) $(SOX_LDLIBS)
lib/libsox.a: build/$(SOX)/Makefile
	cd $(<D) && $(MAKE) && $(MAKE) install
lib/libsox.def: lib/libsox.a
	echo EXPORTS > $@
	nm $< | sed -n 's/.* T _\(sox.*\)/\1/p' >> $@
build/$(SOX)/Makefile: $(SOX_DEPS)
build/$(SOX)/Makefile: OPTS=$(SOX_OPTS)

$(TOOLDIR)/$(SOX).tar.bz2:
	$(call DOWNLOAD,$(call SFURL,sox,sox/$(SOXVER)/$(@F)))

###############################################################################
#OPUS:=opus-1.1
#OPUS:=opus-1.0.2
OPUS:=opus-1.2

OPUS_OPTS:=--prefix=$(PWD)
OPUS_OPTS+=--disable-shared

lib/libopus.a: build/$(OPUS)/Makefile
	cd $(<D) && $(MAKE) && $(MAKE) install
build/$(OPUS)/Makefile: $(OPUS_DEPS)
build/$(OPUS)/Makefile: OPTS=$(OPUS_OPTS)

$(TOOLDIR)/$(OPUS).tar.gz:
	$(call DOWNLOAD,http://downloads.xiph.org/releases/opus/$(@F))

###############################################################################
LIB1770:=lib1770
LIB1770_DEPS:=

LIB1770_OPTS:=--prefix=$(PWD)

lib/lib1770.a: build/$(LIB1770)/Makefile
	cd $(<D) && $(MAKE) && $(MAKE) install
build/$(LIB1770)/Makefile: $(LIB1770_DEPS)
build/$(LIB1770)/Makefile: OPTS=$(LIB1770_OPTS)

###############################################################################
#LIBPB:=libpb-0.1.0
LIBPB:=libpb
LIBPB_DEPS:=

LIBPB_OPTS:=--prefix=$(PWD)

lib/libpb.a: build/$(LIBPB)/Makefile
	cd $(<D) && $(MAKE) && $(MAKE) install
build/$(LIBPB)/Makefile: $(LIBPB_DEPS)
build/$(LIBPB)/Makefile: OPTS=$(LIBPB_OPTS)

###############################################################################
LIBDLGITEMURL:=libdlgitemurl
LIBDLGITEMURL_DEPS:=

LIBDLGITEMURL_OPTS:=--prefix=$(PWD)

lib/delayload/libdlgitemurl.dll.a: lib/delayload/libdlgitemurl.def
	dlltool -d $< --output-delaylib $@
lib/delayload/libdlgitemurl.def: build/libdlgitemurl/libdlgitemurl.def
	mkdir -p $(@D)
	echo LIBRARY "libdlgitemurl.dll" > $@
	cat $< >> $@
build/libdlgitemurl/libdlgitemurl.def: bin/libdlgitemurl.dll
bin/libdlgitemurl.dll: build/$(LIBDLGITEMURL)/Makefile
	cd $(<D) && $(MAKE) && $(MAKE) install
build/$(LIBDLGITEMURL)/Makefile: $(LIBPB_DEPS)
build/$(LIBDLGITEMURL)/Makefile: OPTS=$(LIBDLGITEMURL_OPTS)

###############################################################################
# We copy some static libraries local in order that during linking they will
# be found before their shared counterparts. In order to make this work we
# need to set up the linker's library search path accordingly.
lib/lib%.a:
	mkdir -p $(@D)
	cp -p $(shell gcc -print-file-name=$(@F)) $(@D)

#ifeq (x,x$(BUILD_MSYS2)) # [
### INSTALL ###################################################################
#.PRECIOUS: $(BINDIR)/in_ffsox/% $(BUILDDIR)/in_ffsox/%
#$(BINDIR)/in_ffsox/% $(BUILDDIR)/in_ffsox/%: bin/%
#	$(INSTALL)
#$(BINDIR)/in_ffsox/% $(BUILDDIR)/in_ffsox/%: $(MODE)/bin/%
#	$(INSTALL)
#$(BINDIR)/in_ffsox/% $(BUILDDIR)/in_ffsox/%: $(SRCDIR)/in_ffsox/%
#	$(INSTALL)
#endif # ]

### CONFIGURE #################################################################
PWD_PATH:=$(PWD)/lib/pkgconfig
PWD_MODE_PATH:=$(PWD)/$(MODE)/lib/pkgconfig:$(PWD_PATH)

define CONFIGURE
  mkdir -p $(@D)
  export PKG_CONFIG_PATH=$1 && cd $(@D) && $2 $(OPTS)
  touch $@
endef

.PRECIOUS: $(MODE)/build/%/Makefile build/%/Makefile
$(MODE)/build/%/Makefile: $(SRCDIR)/%/configure
	$(call CONFIGURE,$(PWD_MODE_PATH),$<)
$(MODE)/build/%/Makefile: unpack/%/configure
	$(call CONFIGURE,$(PWD_MODE_PATH),$(PWD)/$<)
build/%/Makefile: $(SRCDIR)/%/configure
	$(call CONFIGURE,$(PWD_PATH),$<)
build/%/Makefile: unpack/%/configure
	$(call CONFIGURE,$(PWD_PATH),$(PWD)/$<)

### UNPACK ####################################################################
define UNPACK
  mkdir -p unpack
  tar xfv$1 $< -C unpack
  if test -e $(SRCDIR)/patch/$*.patch; then \
    cd unpack; \
    patch -p0 -i $(SRCDIR)/patch/$*.patch; \
  fi
  touch $@
endef

.PRECIOUS: unpack/%/configure
unpack/$(FFMPEG)/configure: $(TOOLDIR)/ffmpeg-snapshot.tar.bz2
	rm -rf tiny/build/$(FFMPEG)/*
	rm -rf full/build/$(FFMPEG)/*
	rm -rf $(@D)/*
	$(call UNPACK,j)
unpack/%/configure: $(TOOLDIR)/%.tar.bz2
	$(call UNPACK,j)
unpack/%/configure: $(TOOLDIR)/%.tar.gz
	$(call UNPACK,z)
unpack/%/configure: $(TOOLDIR)/%-src.tar.gz
	$(call UNPACK,z)

###############################################################################
.PHONY: FORCE
FORCE:
