#   Copyright (C) 2006,2007  Joris Mooij  [joris at jorismooij dot nl]
#   Radboud University Nijmegen, The Netherlands
#   
#   This file is part of libDAI.
#
#   libDAI 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 2 of the License, or
#   (at your option) any later version.
#
#   libDAI 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 libDAI; if not, write to the Free Software
#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


WITH_BP = true
WITH_TRW = true
WITH_MF = true
WITH_HAK = true
WITH_LC = true
WITH_LCLIN = true
WITH_TREEEP = true
WITH_JTREE = true
WITH_IJGP = true
WITH_LCBPLIN = 
WITH_LCBP1 = 
WITH_LCBP2 = 
WITH_LCBP3 = 
WITH_LCBP4 = 
WITH_LCBP5 = 
WITH_MR =
WITH_GMR =
DEBUG = true
NEW_MATLAB = true
WITH_MATLAB =

CC = g++-4.1
CCFLAGS = -Wall -Wno-deprecated -fpic -O3 -I. -I./experimental/ -I../include/ -I/vol/snn/vicen/include #-pg -pedantic -Wextra
BOOSTFLAGS = -lboost_program_options -L/vol/snn/vicen/lib/ #-L/usr/lib64/ #
GSLFLAGS = -lgsl -lgslcblas 
ifdef DEBUG
CCFLAGS := $(CCFLAGS) -g -DLIBDAI_DEBUG
else
CCFLAGS := $(CCFLAGS)
endif

OBJECTS := exact.o
ifdef WITH_BP
CCFLAGS := $(CCFLAGS) -DWITH_BP
OBJECTS := $(OBJECTS) bp.o
endif
ifdef WITH_TRW
CCFLAGS := $(CCFLAGS) -DWITH_TRW
OBJECTS := $(OBJECTS) trw.o
endif
ifdef WITH_MF
CCFLAGS := $(CCFLAGS) -DWITH_MF
OBJECTS := $(OBJECTS) mf.o
endif
ifdef WITH_HAK
CCFLAGS := $(CCFLAGS) -DWITH_HAK
OBJECTS := $(OBJECTS) hak.o
endif
ifdef WITH_LC
CCFLAGS := $(CCFLAGS) -DWITH_LC
OBJECTS := $(OBJECTS) lc.o
endif
ifdef WITH_LCLIN
CCFLAGS := $(CCFLAGS) -DWITH_LCLIN
OBJECTS := $(OBJECTS) lclin.o
endif
ifdef WITH_TREEEP
CCFLAGS := $(CCFLAGS) -DWITH_TREEEP
OBJECTS := $(OBJECTS) treeep.o
endif
ifdef WITH_JTREE
CCFLAGS := $(CCFLAGS) -DWITH_JTREE
OBJECTS := $(OBJECTS) jtree.o
endif
ifdef WITH_IJGP
CCFLAGS := $(CCFLAGS) -DWITH_IJGP
OBJECTS := $(OBJECTS) ijgp.o
endif
ifdef WITH_LCBPLIN
CCFLAGS := $(CCFLAGS) -DWITH_LCBPLIN
OBJECTS := $(OBJECTS) lcbplin.o
endif
ifdef WITH_LCBP1
CCFLAGS := $(CCFLAGS) -DWITH_LCBP1
OBJECTS := $(OBJECTS) lcbp1.o
endif
ifdef WITH_LCBP2
CCFLAGS := $(CCFLAGS) -DWITH_LCBP2
OBJECTS := $(OBJECTS) lcbp2.o
endif
ifdef WITH_LCBP3
CCFLAGS := $(CCFLAGS) -DWITH_LCBP3
OBJECTS := $(OBJECTS) lcbp3.o
endif
ifdef WITH_LCBP4
CCFLAGS := $(CCFLAGS) -DWITH_LCBP4
OBJECTS := $(OBJECTS) lcbp4.o
endif
ifdef WITH_LCBP5
CCFLAGS := $(CCFLAGS) -DWITH_LCBP5
OBJECTS := $(OBJECTS) lcbp5.o
endif
ifdef WITH_MR
CCFLAGS := $(CCFLAGS) -DWITH_MR
OBJECTS := $(OBJECTS) mr.o
endif
ifdef WITH_GMR
CCFLAGS := $(CCFLAGS) -DWITH_GMR
OBJECTS := $(OBJECTS) gmr.o
endif


ifdef WITH_MATLAB
MATLABDIR = $(shell readlink `which matlab` | sed -e "s/\/matlab$$//" -)
MEX = $(MATLABDIR)/mex
MEXEXT := $(shell $(MATLABDIR)/mexext)

MEXFLAGS = -I.
ifdef DEBUG
MEXFLAGS := $(MEXFLAGS) -g -DLIBDAI_DEBUG
endif
ifdef NEW_MATLAB
MEXFLAGS := $(MEXFLAGS) -largeArrayDims
else
MEXFLAGS := $(MEXFLAGS) -DSMALLMEM
endif
endif

HEADERS = bipgraph.h diffs.h index.h var.h factor.h varset.h prob.h daialg.h properties.h alldai.h enum.h exceptions.h graphicalmodel.h box.h Makefile

TARGETS = tests utils libdai.a example testregression doc solvers
ifdef WITH_MATLAB
TARGETS := $(TARGETS) matlabs
endif 
all : $(TARGETS)
	echo -e "\a"

solvers : tests/uai/uai1a tests/uai/uai1b tests/uai/uai2a tests/uai/uai2b tests/uai/uai3a tests/uai/uai3b tests/uai/uai4a tests/uai/uai4b tests/uai/uai5a tests/uai/uai5b tests/uai/uai6a tests/uai/uai6b tests/uai/uai7b tests/uai/uai8b tests/uai/uai9b

matlabs : matlab/dai.$(MEXEXT) matlab/dai_readfg.$(MEXEXT) matlab/dai_writefg.$(MEXEXT) matlab/dai_removeshortloops.$(MEXEXT) matlab/dai_potstrength.$(MEXEXT) matlab/dai_bpconvbound.$(MEXEXT)


libdai.a : daialg.o alldai.o clustergraph.o factorgraph.o properties.o regiongraph.o util.o weightedgraph.o exceptions.o box.o bounds.o $(OBJECTS)
	ar rcus libdai.a daialg.o alldai.o clustergraph.o factorgraph.o properties.o regiongraph.o util.o weightedgraph.o exceptions.o box.o bounds.o $(OBJECTS)

tests : tests/test 
#tests/errorbounds/errorbounds4 tests/errorbounds/errorbounds5 tests/errorbounds/logz tests/kees/kees

utils : utils/createfg utils/fg2dot utils/cavitydot utils/remove_short_loops utils/fginfo utils/maximal_factors utils/change_beta utils/vib2fg utils/clamp

testregression : tests/test
	echo Testing...this can take a while...
	cd tests; time ./testregression; cd ..

doc : *.h *.cpp doxygen.conf
	doxygen doxygen.conf

clean :
	rm *.o matlab/*.$(MEXEXT) matlab/*.o example tests/test tests/errorbounds/errorbounds4 tests/errorbounds/errorbounds5 tests/errorbounds/logz tests/kees/kees utils/fg2dot utils/cavitydot utils/createfg utils/remove_short_loop utils/fginfo utils/maximal_factors utils/change_beta utils/vib2fg utils/remove_short_loops utils/clamp libdai.a tests/errorbounds/bounds_other.o tests/errorbounds/boundprop/boundprop.o tests/uai/uai??; echo 
	rm -R doc; echo

daialg.o : daialg.cpp $(HEADERS)
	$(CC) $(CCFLAGS) -c daialg.cpp

exact.o : exact.cpp exact.h $(HEADERS)
	$(CC) $(CCFLAGS) -c exact.cpp

bp.o : bp.cpp bp.h $(HEADERS)
	$(CC) $(CCFLAGS) -c bp.cpp

bounds.o : bounds.cpp bounds.h tree/tree.hh $(HEADERS)
	$(CC) $(CCFLAGS) -c bounds.cpp

trw.o : trw.cpp trw.h $(HEADERS)
	$(CC) $(CCFLAGS) -c trw.cpp

lc.o : lc.cpp lc.h $(HEADERS)
	$(CC) $(CCFLAGS) -c lc.cpp

lclin.o : lclin.cpp lclin.h $(HEADERS)
	$(CC) $(CCFLAGS) -c lclin.cpp

mf.o : mf.cpp mf.h $(HEADERS)
	$(CC) $(CCFLAGS) -c mf.cpp

factorgraph.o : factorgraph.cpp factorgraph.h $(HEADERS)
	$(CC) $(CCFLAGS) -c factorgraph.cpp

util.o : util.cpp util.h $(HEADERS)
	$(CC) $(CCFLAGS) -c util.cpp

regiongraph.o : regiongraph.cpp regiongraph.h $(HEADERS)
	$(CC) $(CCFLAGS) -c regiongraph.cpp

hak.o : hak.cpp hak.h $(HEADERS) regiongraph.h
	$(CC) $(CCFLAGS) -c hak.cpp

clustergraph.o : clustergraph.cpp clustergraph.h $(HEADERS)
	$(CC) $(CCFLAGS) -c clustergraph.cpp

jtree.o : jtree.cpp jtree.h $(HEADERS) weightedgraph.h clustergraph.h regiongraph.h
	$(CC) $(CCFLAGS) -c jtree.cpp

ijgp.o : ijgp.cpp ijgp.h $(HEADERS) weightedgraph.h clustergraph.h regiongraph.h
	$(CC) $(CCFLAGS) -c ijgp.cpp

treeep.o : treeep.cpp treeep.h $(HEADERS) weightedgraph.h clustergraph.h regiongraph.h jtree.h
	$(CC) $(CCFLAGS) -c treeep.cpp

weightedgraph.o : weightedgraph.cpp weightedgraph.h $(HEADERS)
	$(CC) $(CCFLAGS) -c weightedgraph.cpp

properties.o : properties.cpp $(HEADERS)
	$(CC) $(CCFLAGS) -c properties.cpp

alldai.o : alldai.cpp $(HEADERS)
	$(CC) $(CCFLAGS) -c alldai.cpp

exceptions.o : exceptions.cpp $(HEADERS)
	$(CC) $(CCFLAGS) -c exceptions.cpp

box.o : box.cpp box.h $(HEADERS)
	$(CC) $(CCFLAGS) -c box.cpp

boxbp.o : boxbp.cpp boxbp.h $(HEADERS)
	$(CC) $(CCFLAGS) -c boxbp.cpp


# SOLVERS
##########

tests/uai/uai1a : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIPR -DSOLVER1 -static $(CCFLAGS) -o tests/uai/uai1a tests/uai/uai.cpp libdai.a

tests/uai/uai1b : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIMAR -DSOLVER1 -static $(CCFLAGS) -o tests/uai/uai1b tests/uai/uai.cpp libdai.a

tests/uai/uai2a : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIPR -DSOLVER2 -static $(CCFLAGS) -o tests/uai/uai2a tests/uai/uai.cpp libdai.a

tests/uai/uai2b : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIMAR -DSOLVER2 -static $(CCFLAGS) -o tests/uai/uai2b tests/uai/uai.cpp libdai.a

tests/uai/uai3a : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIPR -DSOLVER3 -static $(CCFLAGS) -o tests/uai/uai3a tests/uai/uai.cpp libdai.a

tests/uai/uai3b : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIMAR -DSOLVER3 -static $(CCFLAGS) -o tests/uai/uai3b tests/uai/uai.cpp libdai.a

tests/uai/uai4a : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIPR -DSOLVER4 -static $(CCFLAGS) -o tests/uai/uai4a tests/uai/uai.cpp libdai.a

tests/uai/uai4b : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIMAR -DSOLVER4 -static $(CCFLAGS) -o tests/uai/uai4b tests/uai/uai.cpp libdai.a

tests/uai/uai5a : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIPR -DSOLVER5 -static $(CCFLAGS) -o tests/uai/uai5a tests/uai/uai.cpp libdai.a

tests/uai/uai5b : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIMAR -DSOLVER5 -static $(CCFLAGS) -o tests/uai/uai5b tests/uai/uai.cpp libdai.a

tests/uai/uai6a : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIPR -DSOLVER6 -static $(CCFLAGS) -o tests/uai/uai6a tests/uai/uai.cpp libdai.a

tests/uai/uai6b : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIMAR -DSOLVER6 -static $(CCFLAGS) -o tests/uai/uai6b tests/uai/uai.cpp libdai.a

tests/uai/uai7b : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIMAR -DSOLVER7 -static $(CCFLAGS) -o tests/uai/uai7b tests/uai/uai.cpp libdai.a

tests/uai/uai8b : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIMAR -DSOLVER8 -static $(CCFLAGS) -o tests/uai/uai8b tests/uai/uai.cpp libdai.a

tests/uai/uai9b : tests/uai/uai.cpp $(HEADERS) libdai.a
	$(CC) -DUAIMAR -DSOLVER9 -static $(CCFLAGS) -o tests/uai/uai9b tests/uai/uai.cpp libdai.a


# EXPERIMENTAL
###############

lcbplin.o : experimental/lcbplin.cpp experimental/lcbplin.h $(HEADERS)
	$(CC) $(CCFLAGS) -c experimental/lcbplin.cpp

lcbp1.o : experimental/lcbp1.cpp experimental/lcbp1.h $(HEADERS)
	$(CC) $(CCFLAGS) -c experimental/lcbp1.cpp

lcbp2.o : experimental/lcbp2.cpp experimental/lcbp2.h $(HEADERS)
	$(CC) $(CCFLAGS) -c experimental/lcbp2.cpp

lcbp3.o : experimental/lcbp3.cpp experimental/lcbp3.h $(HEADERS)
	$(CC) $(CCFLAGS) -c experimental/lcbp3.cpp

lcbp4.o : experimental/lcbp4.cpp experimental/lcbp4.h $(HEADERS)
	$(CC) $(CCFLAGS) -c experimental/lcbp4.cpp

lcbp5.o : experimental/lcbp5.cpp experimental/lcbp5.h $(HEADERS)
	$(CC) $(CCFLAGS) -c experimental/lcbp5.cpp

mr.o : experimental/mr.cpp experimental/mr.h $(HEADERS)
	$(CC) $(CCFLAGS) -c experimental/mr.cpp

gmr.o : experimental/gmr.cpp experimental/gmr.h $(HEADERS)
	$(CC) $(CCFLAGS) -c experimental/gmr.cpp


# EXAMPLE
##########

example : example.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o example example.cpp libdai.a


# TESTS
########

tests/test : tests/test.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o tests/test tests/test.cpp libdai.a $(BOOSTFLAGS)

tests/errorbounds/errorbounds4 : tests/errorbounds/errorbounds4.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o tests/errorbounds/errorbounds4 tests/errorbounds/errorbounds4.cpp libdai.a

tests/errorbounds/errorbounds5 : tests/errorbounds/errorbounds5.cpp $(HEADERS) libdai.a tests/errorbounds/bounds_other.o tests/errorbounds/boundprop/boundprop.o
#	$(CC) $(CCFLAGS) -o tests/errorbounds/errorbounds5 tests/errorbounds/errorbounds5.cpp tests/errorbounds/bounds_other.o tests/errorbounds/boundprop/boundprop.o libdai.a -llpsolve55 -ldl -lcolamd $(GSLFLAGS) $(BOOSTFLAGS)
#	$(CC) $(CCFLAGS) -o tests/errorbounds/errorbounds5 tests/errorbounds/errorbounds5.cpp tests/errorbounds/bounds_other.o tests/errorbounds/boundprop/boundprop.o libdai.a ../code/bound_propagation_1.0/lp_solve_3.2/liblpk.a $(GSLFLAGS) $(BOOSTFLAGS)
	$(CC) $(CCFLAGS) -o tests/errorbounds/errorbounds5 tests/errorbounds/errorbounds5.cpp tests/errorbounds/bounds_other.o tests/errorbounds/boundprop/boundprop.o libdai.a -lglpk $(GSLFLAGS) $(BOOSTFLAGS)

tests/errorbounds/bounds_other.o : tests/errorbounds/bounds_other.cpp $(HEADERS) tests/errorbounds/bounds_other.h
	$(CC) $(CCFLAGS) -c tests/errorbounds/bounds_other.cpp -o tests/errorbounds/bounds_other.o

tests/errorbounds/logz : tests/errorbounds/logz.cpp $(HEADERS) libdai.a tests/errorbounds/bounds_other.o
	$(CC) $(CCFLAGS) -o tests/errorbounds/logz tests/errorbounds/logz.cpp tests/errorbounds/bounds_other.o libdai.a $(GSLFLAGS)

tests/kees/kees : tests/kees/kees.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o tests/kees/kees tests/kees/kees.cpp libdai.a

tests/errorbounds/boundprop/boundprop.o : tests/errorbounds/boundprop/boundprop.cpp $(HEADERS) tests/errorbounds/boundprop/boundprop.h
	$(CC) $(CCFLAGS) -c tests/errorbounds/boundprop/boundprop.cpp -o tests/errorbounds/boundprop/boundprop.o -DUSE_GLPK


# MATLAB INTERFACE
###################

matlab/dai.$(MEXEXT) : matlab/dai.cpp $(HEADERS) matlab/matlab.o libdai.a
	$(MEX) $(MEXFLAGS) -o matlab/dai matlab/dai.cpp matlab/matlab.o libdai.a

matlab/dai_readfg.$(MEXEXT) : matlab/dai_readfg.cpp $(HEADERS) factorgraph.o matlab/matlab.o exceptions.o
	$(MEX) $(MEXFLAGS) -o matlab/dai_readfg matlab/dai_readfg.cpp factorgraph.o matlab/matlab.o exceptions.o

matlab/dai_writefg.$(MEXEXT) : matlab/dai_writefg.cpp $(HEADERS) factorgraph.o matlab/matlab.o exceptions.o
	$(MEX) $(MEXFLAGS) -o matlab/dai_writefg matlab/dai_writefg.cpp factorgraph.o matlab/matlab.o exceptions.o

matlab/dai_removeshortloops.$(MEXEXT) : matlab/dai_removeshortloops.cpp $(HEADERS) factorgraph.o matlab/matlab.o exceptions.o
	$(MEX) $(MEXFLAGS) -o matlab/dai_removeshortloops matlab/dai_removeshortloops.cpp factorgraph.o matlab/matlab.o exceptions.o

matlab/dai_potstrength.$(MEXEXT) : matlab/dai_potstrength.cpp $(HEADERS) matlab/matlab.o exceptions.o box.o
	$(MEX) $(MEXFLAGS) -o matlab/dai_potstrength matlab/dai_potstrength.cpp matlab/matlab.o exceptions.o box.o

matlab/matlab.o : matlab/matlab.cpp matlab/matlab.h $(HEADERS)
	$(MEX) $(MEXFLAGS) -outdir matlab -c matlab/matlab.cpp

matlab/dai_bpconvbound.$(MEXEXT) : matlab/dai_bpconvbound.cpp $(HEADERS) factorgraph.o matlab/matlab.o util.o exceptions.o boxbp.o box.o
	$(MEX) $(MEXFLAGS) -o matlab/dai_bpconvbound matlab/dai_bpconvbound.cpp factorgraph.o matlab/matlab.o util.o exceptions.o boxbp.o box.o


# UTILS
########

utils/createfg : utils/createfg.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o utils/createfg utils/createfg.cpp libdai.a $(BOOSTFLAGS)

utils/fg2dot : utils/fg2dot.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o utils/fg2dot utils/fg2dot.cpp libdai.a

utils/cavitydot : utils/cavitydot.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o utils/cavitydot utils/cavitydot.cpp libdai.a

utils/remove_short_loops : utils/remove_short_loops.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o utils/remove_short_loops utils/remove_short_loops.cpp libdai.a

utils/fginfo : utils/fginfo.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o utils/fginfo utils/fginfo.cpp libdai.a

utils/maximal_factors : utils/maximal_factors.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o utils/maximal_factors utils/maximal_factors.cpp libdai.a

utils/change_beta : utils/change_beta.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o utils/change_beta utils/change_beta.cpp libdai.a

utils/clamp : utils/clamp.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o utils/clamp utils/clamp.cpp libdai.a

utils/vib2fg : utils/vib2fg.cpp $(HEADERS) libdai.a
	$(CC) $(CCFLAGS) -o utils/vib2fg utils/vib2fg.cpp libdai.a
