
ifneq "$(QUBX_CCP)" ""
  CCP := $(QUBX_CCP)
  LN  := $(QUBX_CCP)
else
  CCP := g++
  LN  := g++
endif

ifneq "$(QUBX_PYTHON)" ""
  PYTHON := $(QUBX_PYTHON)
else
  PYTHON := python
endif

APIDIR := api
OBJDIR := obj

# c++ (and some python) converted via mathcode2html;
# to also create a remote copy of the html, set environment var QUBX_HTMLIFY_SCP_PATH, e.g.:
# export QUBX_HTMLIFY_SCP_PATH="-s myserver:remote/path"       <-- no trailing slash
HTMLIFY := htmlify/convert_and_place.py -o $(APIDIR) $(QUBX_HTMLIFY_SCP_PATH)

VPATH := .

PRESET_FILES := $(shell find Presets -mindepth 1 -maxdepth 3 -name "*.qpr")
ICON_FILES   := $(shell find icons -mindepth 1 -maxdepth 3 -name "*.png")
MENU_FILES   := $(shell find menu -mindepth 1 -maxdepth 3 -name "*.desktop")

AUXFILES := Makefile qub-express fitness3 qub-express-local fitness3-local \
            README.txt README_Fitness.txt LICENSE.txt INSTALL.txt \
            QUB_Express_change_log.txt About_QUB_Express.txt \
            Fitness_change_log.txt About_Fitness.txt \
            qub-express.key msearch-models.qtr \
            qubfast.txt \
            $(PRESET_FILES) $(ICON_FILES)
AUXFILES += $(shell find notebook_files -mindepth 1 -maxdepth 3 -name "*")

PY_PACKAGEDIRS := 

PYFILES := $(shell find SampleInitScripts -mindepth 1 -maxdepth 3 -name "*.py")
PYFILES += $(shell find QtiPlot -mindepth 1 -maxdepth 3 -name "*.py")
PYFILES += $(shell find scidavis -mindepth 1 -maxdepth 3 -name "*.py")
PYFILES += python_path.py setup_qubx.py global_names.py
PYFILES += $(shell find Scripts -mindepth 1 -maxdepth 8 -name "*.py")
PYFILES += $(shell find InitScripts -mindepth 1 -maxdepth 8 -name "*.py")
PYFILES += $(shell find MeasurementScripts -mindepth 1 -maxdepth 3 -name "*.py")

COMMON_SRCFILES := $(shell find common -mindepth 1 -maxdepth 3 -name "*.cpp")
COMMON_HDRFILES := $(shell find common -mindepth 1 -maxdepth 3 -name "*.h")
COMMON_HTMLFILES := $(shell find $(APIDIR)/common -mindepth 1 -maxdepth 3 -name "*.html")
COMMON_OBJFILES := $(patsubst %.cpp,$(OBJDIR)/%.o,$(COMMON_SRCFILES))

SRCFILES := $(COMMON_SRCFILES)
HDRFILES := $(COMMON_HDRFILES)
OBJFILES := $(COMMON_OBJFILES)
HTMLFILES := $(COMMON_HTMLFILES)
DEPFILES := $(patsubst %.cpp,$(OBJDIR)/%.d,$(SRCFILES))

DISTRO   := $(shell cat /etc/lsb-release | sed -n 's/DISTRIB_CODENAME=\([a-zA-Z_]*\)/\1/p')
VERSION  := $(shell cat qubx/express.py | sed -n 's/^VERSION[^"]*"\(.*\)"/\1/p')
VERSION_FITNESS := $(shell cat qubx/fitness.py | sed -n 's/^VERSION[^"]*"\(.*\)"/\1/p')

PYTHON_PATH_SYS := $(shell $(PYTHON) python_path.py)
PYTHON_PATH_LOCAL := $(shell $(PYTHON) python_path.py local)

TMPDIR   := /tmp

CFLAGS := -W -Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wcast-align \
              -Wwrite-strings -Wredundant-decls -Wno-long-long -Wconversion \
              -g -I./common -I./qubtree -fPIC -O3 -DNDEBUG $(QUBX_CFLAGS) \
              -I/usr/local/include
#              -Winline
#              -Wmissing-declarations
OPENMPFLAGS := -fopenmp
OPENMPLINK  := -lgomp
LNFLAGS :=

ifneq "$(wildcard /System/Library)" ""
  # mac os x:
  LNFLAGS += -Wl,-headerpad_max_install_names
  CFLAGS += -DQUBX_OPENMP_BROKEN
  CFLAGS += -I/opt/local/include
  LNFLAGS += -L/opt/local/lib
  OPENCLFLAGS := -DQUBX_MAC_OPENCL -framework OpenCL
  OPENCLLINK  := -framework OpenCL
  OPENCLEXT   := _opencl
else
  CFLAGS += -I/usr/include
  # linux/nvidia: (is amd the same? does intel have opencl yet?)
  CUDA_PATH   := /usr/local/cuda
  OPENCLPATH = $(shell locate libOpenCL.so | grep lib)
  ifneq "$(wildcard $(OPENCLPATH))" ""
    ifneq "$(wildcard $(CUDA_PATH))" ""
      OPENCLFLAGS := -DQUBX_MAC_OPENCL -I$(CUDA_PATH)/include
      OPENCLLINK  := -lOpenCL
      OPENCLEXT   := _opencl
    endif
  endif
endif


.PHONY: all clean test run install install_local zip deb debs deb_beta deb_other deb_other_beta deb other_debs docs todolist \
       fitness fitness_install fitness_install_local deb_fitness deb_fitness_beta deb_fitness_other deb_fitness_other_beta \
        qubx qubfast qubx_extras qubx_single_molecule qubx_macroscopic qubx_macror qubx_hjcfit \
        plugins plugins_install plugins_install_local

default: libs todolist

all: libs plugins

include qubtree/Makefile_qubtree.in
include qubopt/Makefile_qubopt.in
include qubfast/Makefile_qubfast.in

include qubx/Makefile_qubx.in

include qubx_single_molecule/Makefile_qubx_single_molecule.in

include qubx_macroscopic/Makefile_qubx_macroscopic.in

include qubx_macror/Makefile_qubx_macror.in

include qubx_hjcfit/Makefile_qubx_hjcfit.in

include qubx_extras/Makefile_qubx_extras.in

include qubx_idlmdl/Makefile_qubx_idlmdl.in

-include $(DEPFILES)


ALLFILES := $(SRCFILES) $(HDRFILES) $(AUXFILES) $(PYFILES)


libs: qubtree qubfast qubopt

plugins: qubx_extras qubx_single_molecule qubx_macroscopic qubx_macror qubx_idlmdl qubx_hjcfit

plugins_test: qubx_single_molecule_test qubx_macroscopic_test qubx_macror_test qubx_idlmdl_test qubx_hjcfit_test

debs: deb deb_beta maxill_deb maxmll_deb qubxmacror_deb qubxidlmdl_deb deb_fitness deb_fitness_beta
other_debs: deb_other deb_other_beta maxill_deb_other maxmll_deb_other qubxmacror_deb_other qubxidlmdl_deb_other deb_fitness_other deb_fitness_other_beta

install: qubx_install qubtree_install qubfast_install qubopt_install
	cp qub-express fitness3 /usr/bin
	cp menu/qub-express.desktop /usr/share/applications
	mkdir -p /usr/share/qub-express
	rsync -avR $(ALLFILES) /usr/share/qub-express/
	update-desktop-database

install_local: qubx_install_local qubtree_install_local qubfast_install_local qubopt_install_local
	mkdir -p $(HOME)/bin
	cp qub-express-local $(HOME)/bin/qub-express
	cp fitness3-local $(HOME)/bin/fitness3
	mkdir -p $(HOME)/.local/share/qub-express
	rsync -avR $(ALLFILES) $(HOME)/.local/share/qub-express/

plugins_install_local: qubx_single_molecule_install_local qubx_macroscopic_install_local qubx_macror_install_local qubx_idlmdl_install_local qubx_extras_install_local qubx_hjcfit_install_local

plugins_install: qubx_single_molecule_install qubx_macroscopic_install qubx_macror_install qubx_idlmdl_install qubx_extras_install qubx_hjcfit_install

$(OBJDIR)/%.o: %.cpp Makefile
	-@mkdir -p $(dir $@)
	@$(CCP) $(CFLAGS) -MMD -MP -MT "$(OBJDIR)/$*.d $(OBJDIR)/$*.o" -c $< -o $@

$(APIDIR)/%.h.html: %.h
	$(HTMLIFY) $<

$(APIDIR)/%.cpp.html: %.cpp
	$(HTMLIFY) $<

$(APIDIR)/%.py.html: %.py
	$(HTMLIFY) $<

docs: qubfast_docs common_docs py_docs qubx_docs qubx_single_molecule_docs qubx_macroscopic_docs qubx_macror_docs qubx_idlmdl_docs qubx_extras_docs qubx_hjcfit_docs

common_docs: $(COMMON_HTMLFILES)

py_docs: $(PYFILES)
	-which epydoc && QUBX_PATH=. PYTHONPATH=. LD_LIBRARY_PATH=. epydoc --html -o $(APIDIR) --name "QUB Express" --url http://www.qub.buffalo.edu/wiki/index.php/QUB_Express --show-sourcecode --debug -v $(PY_PACKAGEDIRS)


clean: qubx_clean qubtree_clean qubfast_clean qubopt_clean qubx_single_molecule_clean qubx_macroscopic_clean qubx_macror_clean qubx_idlmdl_clean qubx_extras_clean qubx_hjcfit_clean
	-@rm  $(wildcard $(DEPFILES) $(COMMON_OBJFILES))

run: libs plugins_test todolist
	QUBX_PATH=. PYTHONPATH=. LD_LIBRARY_PATH=. CL_LOG_ERRORS=stdout $(PYTHON) -m qubx.express

test: libs plugins_test todolist
	QUBX_PATH=. PYTHONPATH=. LD_LIBRARY_PATH=. CL_LOG_ERRORS=stdout $(PYTHON) -m qubx.express -s test_all.py

test_fitness: libs plugins_test todolist
	QUBX_PATH=. PYTHONPATH=. LD_LIBRARY_PATH=. $(PYTHON) -m qubx.fitness -s test_fitness.py

profile: libs plugins_test todolist
	LD_LIBRARY_PATH=. PYTHONPATH=. QUBX_PATH=. $(PYTHON) -m cProfile -o $(TMPDIR)/qubx-profile qubx/express.py

profile_fitness: libs plugins_test todolist
	LD_LIBRARY_PATH=. PYTHONPATH=. QUBX_PATH=. $(PYTHON) -m cProfile -o $(TMPDIR)/fitness-profile qubx/fitness.py

zip: docs $(ALLFILES) $(MENU_FILES)
	-@rm -fr $(TMPDIR)/qub-express
	-@mkdir -p $(TMPDIR)/qub-express
	@rsync -avR $(ALLFILES) $(HTMLFILES) $(MENU_FILES) $(APIDIR) $(TMPDIR)/qub-express/
	@sh -c 'cd $(TMPDIR); zip -r qub-express.zip qub-express'
	mv $(TMPDIR)/qub-express.zip ./qub-express-source-$(VERSION).zip

deb: libs qubx $(ALLFILES) $(MENU_FILES)
	-@rm -fr $(TMPDIR)/qub-express-deb
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/applications
	@cp -a menu/qub-express.desktop $(TMPDIR)/qub-express-deb/usr/share/applications
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/qub-express
	@rsync -avR $(ALLFILES) $(TMPDIR)/qub-express-deb/usr/share/qub-express
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/qub-express/Plugins
	@rsync -avR $(QUBX_EXTRAS_PLUGFILES) $(TMPDIR)/qub-express-deb/usr/share/qub-express/Plugins
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/lib
	@cp -a libqubfast.so libqubtree.so libqubopt.so $(TMPDIR)/qub-express-deb/usr/lib
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/bin
	@cp -a qub-express $(TMPDIR)/qub-express-deb/usr/bin
	@mkdir -p $(TMPDIR)/qub-express-deb$(PYTHON_PATH_SYS)
	@rsync -avR $(QUBX_PYFILES) $(TMPDIR)/qub-express-deb$(PYTHON_PATH_SYS)/
	./qubx-dpkg.sh $(DISTRO) release $(TMPDIR)/qub-express-deb
#	./qubx-dpkg.sh none release $(TMPDIR)/qub-express-deb

deb_beta: libs qubx $(ALLFILES) $(MENU_FILES)
	-@rm -fr $(TMPDIR)/qub-express-deb
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/applications
	@cp -a menu/qub-express.desktop $(TMPDIR)/qub-express-deb/usr/share/applications
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/qub-express
	@rsync -avR $(ALLFILES) $(TMPDIR)/qub-express-deb/usr/share/qub-express
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/qub-express/Plugins
	@rsync -avR $(QUBX_EXTRAS_PLUGFILES) $(TMPDIR)/qub-express-deb/usr/share/qub-express/Plugins
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/lib
	@cp -a libqubfast.so libqubtree.so libqubopt.so $(TMPDIR)/qub-express-deb/usr/lib
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/bin
	@cp -a qub-express $(TMPDIR)/qub-express-deb/usr/bin
	@mkdir -p $(TMPDIR)/qub-express-deb$(PYTHON_PATH_SYS)
	@rsync -avR $(QUBX_PYFILES) $(TMPDIR)/qub-express-deb$(PYTHON_PATH_SYS)/
	./qubx-dpkg.sh $(DISTRO) beta $(TMPDIR)/qub-express-deb
#	./qubx-dpkg.sh none beta $(TMPDIR)/qub-express-deb

# just the executable one-line script and desktop entry (the rest is included in qub-express)
deb_fitness: fitness3
	-@rm -fr $(TMPDIR)/fitness-deb
	-@mkdir -p $(TMPDIR)/fitness-deb/usr/share/applications
	@cp -a menu/fitness3.desktop $(TMPDIR)/fitness-deb/usr/share/applications
	-@mkdir -p $(TMPDIR)/fitness-deb/usr/bin
	@cp -a fitness3 $(TMPDIR)/fitness-deb/usr/bin
	./fitness-dpkg.sh $(DISTRO) release $(TMPDIR)/fitness-deb

deb_fitness_beta: fitness3
	-@rm -fr $(TMPDIR)/fitness-deb
	-@mkdir -p $(TMPDIR)/fitness-deb/usr/share/applications
	@cp -a menu/fitness3.desktop $(TMPDIR)/fitness-deb/usr/share/applications
	-@mkdir -p $(TMPDIR)/fitness-deb/usr/bin
	@cp -a fitness3 $(TMPDIR)/fitness-deb/usr/bin
	./fitness-dpkg.sh $(DISTRO) beta $(TMPDIR)/fitness-deb

# dist-agnostic: python version detection, symlink into *-packages postinst
# TODO: runtime trouble detection; suggested "sudo ..." fix
deb_other: libs qubx $(ALLFILES) $(MENU_FILES)
	-@rm -fr $(TMPDIR)/qub-express-deb
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/applications
	@cp -a menu/qub-express.desktop $(TMPDIR)/qub-express-deb/usr/share/applications
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/qub-express
	@rsync -avR $(ALLFILES) $(TMPDIR)/qub-express-deb/usr/share/qub-express
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/qub-express/Plugins
	@rsync -avR $(QUBX_EXTRAS_PLUGFILES) $(TMPDIR)/qub-express-deb/usr/share/qub-express/Plugins
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/lib
	@cp -a libqubfast.so libqubtree.so libqubopt.so $(TMPDIR)/qub-express-deb/usr/lib
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/bin
	@cp -a qub-express $(TMPDIR)/qub-express-deb/usr/bin
	./qubx-dpkg-other.sh release $(TMPDIR)/qub-express-deb

deb_other_beta: libs qubx $(ALLFILES) $(MENU_FILES)
	-@rm -fr $(TMPDIR)/qub-express-deb
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/applications
	@cp -a menu/qub-express.desktop $(TMPDIR)/qub-express-deb/usr/share/applications
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/qub-express
	@rsync -avR $(ALLFILES) $(TMPDIR)/qub-express-deb/usr/share/qub-express
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/share/qub-express/Plugins
	@rsync -avR $(QUBX_EXTRAS_PLUGFILES) $(TMPDIR)/qub-express-deb/usr/share/qub-express/Plugins
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/lib
	@cp -a libqubfast.so libqubtree.so libqubopt.so $(TMPDIR)/qub-express-deb/usr/lib
	-@mkdir -p $(TMPDIR)/qub-express-deb/usr/bin
	@cp -a qub-express $(TMPDIR)/qub-express-deb/usr/bin
	./qubx-dpkg-other.sh beta $(TMPDIR)/qub-express-deb

deb_fitness_other: fitness3
	-@rm -fr $(TMPDIR)/fitness-deb
	-@mkdir -p $(TMPDIR)/fitness-deb/usr/share/applications
	@cp -a menu/fitness3.desktop $(TMPDIR)/fitness-deb/usr/share/applications
	-@mkdir -p $(TMPDIR)/fitness-deb/usr/bin
	@cp -a fitness3 $(TMPDIR)/fitness-deb/usr/bin
	./fitness-dpkg.sh other release $(TMPDIR)/fitness-deb

deb_fitness_other_beta: fitness3
	-@rm -fr $(TMPDIR)/fitness-deb
	-@mkdir -p $(TMPDIR)/fitness-deb/usr/share/applications
	@cp -a menu/fitness3.desktop $(TMPDIR)/fitness-deb/usr/share/applications
	-@mkdir -p $(TMPDIR)/fitness-deb/usr/bin
	@cp -a fitness3 $(TMPDIR)/fitness-deb/usr/bin
	./fitness-dpkg.sh other beta $(TMPDIR)/fitness-deb

# Mac OS X:
BUNDLE_RESOURCES := dist/QUB-Express.app/Contents/Resources
FITNESS_BUNDLE_RESOURCES := dist/Fitness.app/Contents/Resources

bundle: libs qubx plugins $(ALLFILES)
	./create_app_bundle.sh
	rsync -avR $(ALLFILES) dist/QUB-Express.app/Contents/Resources
	mkdir -p $(BUNDLE_RESOURCES)/Plugins
	mv $(BUNDLE_RESOURCES)/qubx_macroscopic $(BUNDLE_RESOURCES)/qubx_macror $(BUNDLE_RESOURCES)/qubx_single_molecule $(BUNDLE_RESOURCES)/qubx_idlmdl $(BUNDLE_RESOURCES)/qubx_extras $(BUNDLE_RESOURCES)/qubx_hjcfit $(BUNDLE_RESOURCES)/Plugins
	cp qubfast.alt dist/QUB-Express.app/Contents/Resources/qubfast.txt

fitness_bundle: libs qubx $(ALLFILES)
	./fitness_create_app_bundle.sh
	rsync -avR $(ALLFILES) dist/Fitness.app/Contents/Resources
	mkdir -p $(FITNESS_BUNDLE_RESOURCES)/Plugins

dmg: bundle
	./create_dmg.sh $(VERSION)

fitness_dmg: fitness_bundle
	./fitness_create_dmg.sh $(VERSION_FITNESS)

todolist:
	-@for file in $(ALLFILES); do fgrep -H -e TODO -e FIXME $$file; done; true


bundle_paid: libs qubx plugins $(ALLFILES)
	./create_app_bundle.sh
	rsync -avR $(ALLFILES) dist/QUB-Express.app/Contents/Resources
	mkdir -p $(BUNDLE_RESOURCES)/Plugins
	mv $(BUNDLE_RESOURCES)/qubx_macroscopic $(BUNDLE_RESOURCES)/qubx_macror $(BUNDLE_RESOURCES)/qubx_single_molecule $(BUNDLE_RESOURCES)/qubx_idlmdl $(BUNDLE_RESOURCES)/qubx_extras $(BUNDLE_RESOURCES)/qubx_hjcfit $(BUNDLE_RESOURCES)/Plugins

dmg_paid: bundle_paid
	./create_dmg.sh $(VERSION)

#TODO: windows build
#TODO: test links between api and libs doc (..)
#TODO: mac plugin

