#----------------------------------------------------------------------------------------------
# makefile to build MPXPLAY WIN32-QT-FFMPEG-GUI-X64 program, static link version
#   required tools: 
# QT 5.6.3, MinGWw64 12.2.0 x64, Msys2, FFMpeg 6.1.x (installed in Qt's dir), AV1d, VVdec and Z libs
#----------------------------------------------------------------------------------------------

# project root defs
PROJECT_ROOTDIR = $(CURDIR)
PROJECT_LIBDIR = $(PROJECT_ROOTDIR)
BUILDDIR = $(PROJECT_ROOTDIR)/build
EXE_MPXPLAY = $(PROJECT_ROOTDIR)/mpxp_mmc_x64.exe
NSI_MPXPLAY = mpxp_mmc_x64.nsi

# mingw tool/compiler defs
TOOLS_ROOT_DIR = c:/CPP
QTDIR = $(TOOLS_ROOT_DIR)/QT
QTVERSION = 5.6.3
TOOLVERSION = 12.2.0
TOOLDIR = $(QTDIR)/Tools/mingw1220_64
MINGW_INCDIRS = -I$(TOOLDIR)/include -I$(TOOLDIR)/x86_64-w64-mingw32/include
MINGW_LIBDIRS = -L$(TOOLDIR)/lib -L$(TOOLDIR)/x86_64-w64-mingw32/lib -L$(TOOLDIR)/lib/gcc/x86_64-w64-mingw32/$(TOOLVERSION)

BINDIR = $(TOOLDIR)/bin
AR = $(BINDIR)/ar
CC = $(BINDIR)/gcc
RANLIB = $(BINDIR)/ranlib
STRIP = $(BINDIR)/strip
MSYS_BIN_DIR = $(TOOLS_ROOT_DIR)/msys2_x64/usr/bin
CP = $(MSYS_BIN_DIR)/cp -f
RM = $(MSYS_BIN_DIR)/rm
MKDIR = $(MSYS_BIN_DIR)/mkdir

DEL_LIB_OBJS = $(RM) $(addsuffix /*.o, $(dir $<))

ARFLAGS = rcs

# compiler options (for Mpxplay win32 part)
MPX_DEFINES = -DMPXPLAY -DMPXPLAY_GUI_QT -DMPXPLAY_LINK_DXVA -D_WIN32_WINNT=0x0600 $(MAKE_CFLAGS)
CFLAGS_BASE = -pipe -funsigned-char -I. $(MINGW_INCDIRS) -ffast-math $(MPX_DEFINES)
CFLAGS_OPTI = -s -O2 -Wno-deprecated-declarations
CFLAGS = $(CFLAGS_BASE) $(CFLAGS_OPTI)
LFLAGS = -static -lwinmm -ldsound -lws2_32 -lwsock32 -lmpr -lpthread
LFLAGS += $(MINGW_LIBDIRS)
#LFLAGS +=-Wl,-M -Wl,-Map=$(BUILDDIR)\mpxplay.map

#--- QT compiler/build defs -------------------------------------------------
QT_DIR_ROOT = $(QTDIR)/$(QTVERSION)/qt_static_x64
QT_DIR_BIN = $(QT_DIR_ROOT)/bin
QT_DIR_H = $(QT_DIR_ROOT)/include
QT_DIR_LIB = $(QT_DIR_ROOT)/lib

QT_CC = $(BINDIR)gcc.exe
QT_CXX = $(BINDIR)/g++

QT_DEFINES += -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WIDGETS_LIB -DQT_STATIC -DINITGUID
QT_DEFINES += -DQT_NO_TABLETEVENT
QT_DEFINES += -DQT_NO_FTP -DQT_NO_HTTP -DQT_NO_NETWORKDISKCACHE
QT_DEFINES += -DQT_NO_SOCK5 -DQT_NO_SSL
QT_DEFINES += -DQT_NO_NETWORKINTERFACE -DQT_NO_NETWORKPROXY -DQT_NO_UDPSOCKET -DQT_NO_BEARERMANAGEMENT
QT_DEFINES += -DQT_NO_CODECS -DQT_NO_ICONV
QT_DEFINES += -DQT_NO_BIG_CODECS -DQT_NO_SORTFILTERPROXYMODEL -DQT_NO_IDENTITYPROXYMODEL

QT_CXXFLAGS = -std=c++11 -frtti -fno-keep-inline-dllexport $(CFLAGS) $(QT_DEFINES) -include $(QT_DIR_H)/QtCore/qconfig.h
QT_INCPATH  = -I'$(QT_DIR_H)' -I'$(QT_DIR_H)/QtWidgets' -I'$(QT_DIR_H)/QtGui' -I'$(QT_DIR_H)/QtCore' -I'$(QT_DIR_H)/QtMultimedia'
QT_INCPATH += -I'$(QT_DIR_ROOT)/mkspecs/win32-g++'
CFLAGS += -I'$(QT_DIR_H)'
QT_LINKER = $(QT_CXX)
QT_LFLAGS = -Wl,-s -Wl,-subsystem,windows:6.0
QT_LIBS  = -L$(QT_DIR_LIB) -L$(QT_DIR_ROOT)/plugins/platforms -L$(QT_DIR_ROOT)/plugins/mediaservice
QT_LIBS += -lQt5MultimediaWidgets -Wl,--start-group -lQt5Multimedia -ldsengine -Wl,--end-group
QT_LIBS += -lQt5Widgets -lqwindows -lQt5Gui -lQt5WinExtras -lQt5Core -lQt5PlatformSupport

QT_LIBS += -lswresample -lavfilter -lavcodec -lavformat -lswscale -lavutil
LFLAGS += -L$(QT_DIR_LIB) -lavfilter -lavcodec -lavformat -lswscale -lavutil -lswresample -ldav1d -lvvdec -lz
QT_LIBS += -lgdiplus -lqtpcre -lz
QT_LIBS += -lstrmiids -loleaut32 -lgdi32 -limm32 -lole32 -luuid -lmfuuid -lamstrmid

QT_LIBS += $(BUILDDIR)/mmc_resource.o

#--- main lib-----------------------------------------------------------------
LIB_MAIN = mpx_main.a
DIR_MAIN = $(PROJECT_ROOTDIR)
SRC_MAIN = MPXPLAY.C IN_FILE.C MPXINBUF.C
SRCS_MAIN = $(addprefix $(DIR_MAIN)/, $(notdir $(SRC_MAIN)))
OBJS_MAIN := $(SRCS_MAIN:.C=.o)
VPATH = $(DIR_MAIN)
LIB_ALL = $(LIB_MAIN)

#--- QT GUI lib --------------------------------------------------------------
LIB_DISPQT = disp_qt.a
DIR_DISPQT = $(PROJECT_LIBDIR)/DISP_QT
SRC_DISPQT_BASE  = main.cpp mainwindow.cpp config.cpp config_ini.cpp avmixer.cpp dialog_elems.cpp
SRC_DISPQT_BASE += driveline.cpp dvb_epg.cpp dvb_scan.cpp editor.cpp editor_table.cpp seekbar.cpp
SRC_DISPQT_BASE += textwin.cpp video_contextmenu.cpp video_ctrlbar.cpp video_events.cpp
SRC_DISPQT_BASE += video_qt.cpp video_widget.cpp video_filter.cpp video_filters_cfg.cpp
SRC_DISPQT_BASE += video_render_base.cpp video_render_common.cpp
SRC_DISPQT_BASE += video_render_d3d11.cpp video_render_d3d9.cpp
SRC_DISPQT_BASE += video_render_gdi.cpp video_render_qpaint.cpp video_render_vulkan.cpp
SRC_DISPQT_BASE += video_trans.cpp video_workdec.cpp video_worksubt.cpp video_worker.cpp
SRCS_DISPQT_BASE = $(addprefix $(DIR_DISPQT)/, $(SRC_DISPQT_BASE))

SRC_DISPQT_MOC_H  = moc_mainwindow.h moc_config.h moc_avmixer.h moc_dialog_elems.h moc_driveline.h
SRC_DISPQT_MOC_H += moc_dvb_epg.h moc_editor.h moc_seekbar.h moc_textwin.h moc_video_ctrlbar.h
SRC_DISPQT_MOC_H += moc_video_qt.h moc_video_render.h
SRCS_DISPQT_MOC_CPP = $(addprefix $(DIR_DISPQT)/, $(SRC_DISPQT_MOC_H:.h=.cpp))

SRC_DISPQT_QRC_QRC = qrc_disp_qt.qrc
SRCS_DISPQT_QRC_CPP = $(addprefix $(DIR_DISPQT)/, $(SRC_DISPQT_QRC_QRC:.qrc=.cpp))

SRCS_DISPQT_ALL = $(SRCS_DISPQT_BASE) $(SRCS_DISPQT_MOC_CPP) $(SRCS_DISPQT_QRC_CPP)
OBJS_DISPQT := $(SRCS_DISPQT_ALL:.cpp=.o)

# moved to last
#LIB_ALL += $(LIB_DISPQT)

#--- AU_CARDS lib ------------------------------------------------------------
LIB_AUCARDS = au_cards.a
DIR_AUCARDS = $(PROJECT_LIBDIR)/AU_CARDS
SRC_AUCARDS = AU_CARDS.C DMAIRQ.C SC_WAV.C SC_NULL.C SC_WINDS.C SC_WINWO.C
SRCS_AUCARDS = $(addprefix $(DIR_AUCARDS)/, $(notdir $(SRC_AUCARDS)))
OBJS_AUCARDS := $(SRCS_AUCARDS:.C=.o)
VPATH += $(DIR_AUCARDS)
LIB_ALL += $(LIB_AUCARDS)

#--- AU_MIXER lib -------------------------------------------------------------
LIB_AUMIXER = au_mixer.a
DIR_AUMIXER = $(PROJECT_LIBDIR)/AU_MIXER
SRC_AUMIXER = ANALISER.C AU_MIXER.C CUTSILEN.C CV_BITS.C CV_CHAN.C CV_FREQ.C FX_SURR.C FX_TONE.C MX_AVOL.C MX_CROSF.C MX_VOLUM.C
SRCS_AUMIXER = $(addprefix $(DIR_AUMIXER)/, $(notdir $(SRC_AUMIXER)))
OBJS_AUMIXER := $(SRCS_AUMIXER:.C=.o)
VPATH += $(DIR_AUMIXER)
LIB_ALL += $(LIB_AUMIXER)

#--- CONTROL lib ---------------------------------------------------------------
LIB_CONTROL = control.a
DIR_CONTROL = $(PROJECT_LIBDIR)/CONTROL
SRC_CONTROL = CONTROL.C FASTLIST.C JOY.C KEYCTRL.C KEYGROUP.C SERIAL.C STARTUP.C
SRCS_CONTROL = $(addprefix $(DIR_CONTROL)/, $(notdir $(SRC_CONTROL)))
OBJS_CONTROL := $(SRCS_CONTROL:.C=.o)
VPATH += $(DIR_CONTROL)
LIB_ALL += $(LIB_CONTROL)

#--- DECODERS lib --------------------------------------------------------------
LIB_DECODERS = decoders.a
DIR_DECODERS = $(PROJECT_LIBDIR)/DECODERS
SRC_DECODERS = DECODERS.C AD_PCM.C
SRCS_DECODERS = $(addprefix $(DIR_DECODERS)/, $(notdir $(SRC_DECODERS)))
OBJS_DECODERS := $(SRCS_DECODERS:.C=.o)
VPATH += $(DIR_DECODERS)
LIB_ALL += $(LIB_DECODERS)

#--- DEMUXERS lib --------------------------------------------------------------
LIB_DEMUXERS = demuxers.a
DIR_DEMUXERS = $(PROJECT_LIBDIR)/DEMUXERS
SRC_DEMUXERS = IN_ASF.C IN_MP4.C IN_OGG.C
SRCS_DEMUXERS = $(addprefix $(DIR_DEMUXERS)/, $(notdir $(SRC_DEMUXERS)))
OBJS_DEMUXERS := $(SRCS_DEMUXERS:.C=.o)
VPATH += $(DIR_DEMUXERS)
LIB_ALL += $(LIB_DEMUXERS)

#--- DEPARSER lib --------------------------------------------------------------
LIB_DEPARSER = deparser.a
DIR_DEPARSER = $(PROJECT_LIBDIR)/DEPARSER
SRC_DEPARSER = TAGGING.C IN_FLAC.C IN_FMPEG.C
SRC_DEPARSER += FFMPADEC.C FFMPDMUX.C FFMPEPG.C FFMPFILE.C FFMPGDEC.C FFMPLANG.C FFMPQUEU.C FFMPPARS.C FFMPSTRM.C
SRCS_DEPARSER = $(addprefix $(DIR_DEPARSER)/, $(notdir $(SRC_DEPARSER)))
OBJS_DEPARSER := $(SRCS_DEPARSER:.C=.o)
VPATH += $(DIR_DEPARSER)
LIB_ALL += $(LIB_DEPARSER)
LIB_ALL += $(LIB_DEMUXERS)

#--- DISKDRIV lib --------------------------------------------------------------
LIB_DISKDRIV = diskdriv.a
DIR_DISKDRIV = $(PROJECT_LIBDIR)/DISKDRIV
SRC_DISKDRIV_C = DISKDRIV.C DRV_CD.C DRV_HD.C DRV_FTP.C DRV_HTTP.C DRV_ICE.C DRV_DTV.C CD_ASPI.C
SRC_DISKDRIV_C += DTVDBASE.C DTVSCAN.C OPEN_FTP.C TCPCOMON.C
SRC_DISKDRIV_CPP = DTV_BDA.CPP
SRCS_DISKDRIV_C = $(addprefix $(DIR_DISKDRIV)/, $(notdir $(SRC_DISKDRIV_C)))
SRCS_DISKDRIV_CPP = $(addprefix $(DIR_DISKDRIV)/, $(notdir $(SRC_DISKDRIV_CPP)))
OBJS_DISKDRIV := $(SRCS_DISKDRIV_C:.C=.o)
OBJS_DISKDRIV_CPP := $(SRCS_DISKDRIV_CPP:.CPP=.o)
VPATH += $(DIR_DISKDRIV)
LIB_ALL += $(LIB_DISKDRIV)

#--- DISPLAY lib --------------------------------------------------------------
LIB_DISPLAY = display.a
DIR_DISPLAY = $(PROJECT_LIBDIR)/DISPLAY
SRC_DISPLAY = TEXTWIN.C
SRCS_DISPLAY = $(addprefix $(DIR_DISPLAY)/, $(notdir $(SRC_DISPLAY)))
OBJS_DISPLAY := $(SRCS_DISPLAY:.C=.o)
VPATH += $(DIR_DISPLAY)
LIB_ALL += $(LIB_DISPLAY)

#--- NEWFUNC lib --------------------------------------------------------------
LIB_NEWFUNC = newfunc.a
DIR_NEWFUNC = $(PROJECT_LIBDIR)/NEWFUNC
SRC_NEWFUNC = NEWFUNC.C BITSTRM.C CPU.C DLL_LOAD.C DPMI.C DRIVEHND.C ERRORHND.C FILEHAND.C FPU.C
SRC_NEWFUNC += KEYBOARD.C MEMORY.C MIXED.C STRING.C THREADS.C TIME.C TIMER.C
SRCS_NEWFUNC = $(addprefix $(DIR_NEWFUNC)/, $(notdir $(SRC_NEWFUNC)))
OBJS_NEWFUNC := $(SRCS_NEWFUNC:.C=.o)
VPATH += $(DIR_NEWFUNC)
LIB_ALL += $(LIB_NEWFUNC)

#--- PLAYLIST lib --------------------------------------------------------------
LIB_PLAYLIST = playlist.a
DIR_PLAYLIST = $(PROJECT_LIBDIR)/PLAYLIST
SRC_PLAYLIST = PLAYLIST.C CHKENTRY.C DISKFILE.C EDITLIST.C FILEINFO.C ID3LIST.C JUKEBOX.C LOADDIR.C
SRC_PLAYLIST += LOADLIST.C LOADSUB.C RANDLIST.C SAVELIST.C SKIPLIST.C SORTLIST.C TEXTCONV.C
SRCS_PLAYLIST = $(addprefix $(DIR_PLAYLIST)/, $(notdir $(SRC_PLAYLIST)))
OBJS_PLAYLIST := $(SRCS_PLAYLIST:.C=.o)
VPATH += $(DIR_PLAYLIST)
LIB_ALL += $(LIB_PLAYLIST)

#################################################################################
#--- AD_VORBI lib --------------------------------------------------------------
LIB_AD_VORBI = ad_vorbi.a
DIR_AD_VORBI = $(DIR_DECODERS)/AD_VORBI
SRC_AD_VORBI  = BITWISE.C BLOCK.C CODEBOOK.C FLOOR0.C FLOOR1.C FRAMING.C INFO.C MAPPING0.C RES0.C SHARBOOK.C SYNTHESI.C WINDOW.C LSP.C MDCT_VOR.C
SRCS_AD_VORBI = $(addprefix $(DIR_AD_VORBI)/, $(notdir $(SRC_AD_VORBI)))
OBJS_AD_VORBI := $(SRCS_AD_VORBI:.C=.o)
VPATH += $(DIR_AD_VORBI)
LIB_ALL += $(LIB_AD_VORBI)

# !!! it have to be the last
LIB_ALL += $(LIB_DISPQT)

#################################################################################
LIBS_MPXPLAY := $(addprefix $(BUILDDIR)/, $(notdir $(LIB_ALL:.a=.a)))

all: $(EXE_MPXPLAY)

$(BUILDDIR)/$(LIB_MAIN): $(OBJS_MAIN)
	$(AR) $(ARFLAGS) $@ $(OBJS_MAIN)
	$(DEL_LIB_OBJS)

$(BUILDDIR)/$(LIB_AUCARDS): $(OBJS_AUCARDS)
	$(AR) $(ARFLAGS) $@ $(OBJS_AUCARDS)
	$(DEL_LIB_OBJS)

$(BUILDDIR)/$(LIB_AUMIXER): $(OBJS_AUMIXER)
	$(AR) $(ARFLAGS) $@ $(OBJS_AUMIXER)
	$(DEL_LIB_OBJS)

$(BUILDDIR)/$(LIB_CONTROL): $(OBJS_CONTROL)
	$(AR) $(ARFLAGS) $@ $(OBJS_CONTROL)
	$(DEL_LIB_OBJS)

$(BUILDDIR)/$(LIB_DECODERS): $(OBJS_DECODERS)
	$(AR) $(ARFLAGS) $@ $(OBJS_DECODERS)
	$(DEL_LIB_OBJS)

$(BUILDDIR)/$(LIB_DEMUXERS): $(OBJS_DEMUXERS)
	$(AR) $(ARFLAGS) $@ $(OBJS_DEMUXERS)
	$(DEL_LIB_OBJS)

$(BUILDDIR)/$(LIB_DEPARSER): $(OBJS_DEPARSER)
	$(AR) $(ARFLAGS) $@ $(OBJS_DEPARSER)
	$(DEL_LIB_OBJS)

$(BUILDDIR)/$(LIB_DISKDRIV): $(OBJS_DISKDRIV) $(OBJS_DISKDRIV_CPP)
	$(AR) $(ARFLAGS) $@ $(OBJS_DISKDRIV) $(OBJS_DISKDRIV_CPP)
	$(DEL_LIB_OBJS)

$(BUILDDIR)/$(LIB_DISPLAY): $(OBJS_DISPLAY)
	$(AR) $(ARFLAGS) $@ $(OBJS_DISPLAY)
	$(DEL_LIB_OBJS)

$(BUILDDIR)/$(LIB_DISPQT): $(OBJS_DISPQT)
	$(AR) $(ARFLAGS) $@ $(OBJS_DISPQT)
	$(DEL_LIB_OBJS)
#	$(RM) $(SRCS_DISPQT_MOC_CPP) $(SRCS_DISPQT_QRC_CPP)

$(BUILDDIR)/$(LIB_NEWFUNC): $(OBJS_NEWFUNC)
	$(AR) $(ARFLAGS) $@ $(OBJS_NEWFUNC)
	$(DEL_LIB_OBJS)

$(BUILDDIR)/$(LIB_PLAYLIST): $(OBJS_PLAYLIST)
	$(AR) $(ARFLAGS) $@ $(OBJS_PLAYLIST)
	$(DEL_LIB_OBJS)

#---------------------------------------------------------------------------------
$(BUILDDIR)/$(LIB_AD_VORBI): $(OBJS_AD_VORBI)
	$(AR) $(ARFLAGS) $@ $(OBJS_AD_VORBI)
	$(DEL_LIB_OBJS)

#------------------------------------------------------------------------------------
.PHONY : all ranlib clean installer

ranlib: $(LIBS_MPXPLAY)
	$(RANLIB) $(LIBS_MPXPLAY)

all: $(EXE_MPXPLAY)

$(EXE_MPXPLAY): ranlib $(BUILDDIR)/mmc_resource.o
	$(QT_LINKER) -o $@ $(LIBS_MPXPLAY) $(QT_LFLAGS) $(QT_LIBS) $(LFLAGS)
	$(STRIP) -s $(EXE_MPXPLAY)

%.o: %.c
	$(CC) -c -x c $(CFLAGS) -o $@ $<

%.o: %.C
	$(CC) -c -x c $(CFLAGS) -o $@ $<

%.o: %.CPP
	$(QT_CXX) -c $(QT_CXXFLAGS) $(QT_INCPATH) -o $@ $<

$(DIR_DISPQT)/%.cpp: $(DIR_DISPQT)/%.h
	$(QT_DIR_BIN)/moc.exe $(MPX_DEFINES) $(QT_DEFINES) -D__GNUC__ -DWIN32 $(QT_INCPATH) -o $@ $<

$(DIR_DISPQT)/%.cpp: $(DIR_DISPQT)/%.qrc
	$(QT_DIR_BIN)/rcc.exe -name mpxplay_qt_qrc -o $@ $<

$(BUILDDIR)/%.o: $(DIR_DISPQT)/%.rc
	$(BINDIR)/windres.exe -i $< -o $@ --include-dir=. $(QT_DEFINES)

$(DIR_DISPQT)/%.o: $(DIR_DISPQT)/%.cpp
	$(QT_CXX) -c $(QT_CXXFLAGS) $(QT_INCPATH) -o $@ $<

clean distclean:
	$(RM) -f $(EXE_MPXPLAY)
	$(RM) -f $(BUILDDIR)/?*.*
	$(RM) -f $(BUILDDIR)/COPYING
	$(RM) -f $(BUILDDIR)/DOCS/?*.*

installer: clean all
	$(CP) ./DISP_QT/installer/$(NSI_MPXPLAY) $(BUILDDIR)
	$(CP) ./DISP_QT/installer/COPYING $(BUILDDIR)
	$(CP) $(EXE_MPXPLAY) $(BUILDDIR)
	$(CP) ./DOCS/MMC/mpxplay.ini $(BUILDDIR)
	$(CP) ./EXTLIBS/DLLS/libcrypto-1_1-x64.dll $(BUILDDIR)
	$(CP) ./EXTLIBS/DLLS/libssl-1_1-x64.dll $(BUILDDIR)
	$(MKDIR) -p $(BUILDDIR)/DOCS
	$(CP) ./DOCS/MMC/DOCS/*.* $(BUILDDIR)/DOCS
	@makensis "$(BUILDDIR)/$(NSI_MPXPLAY)"
