MKOCTFILE ?= mkoctfile
FFC ?= ffc

CPPFLAGS='@DENSE_CPPFLAGS@ @DOLFIN_CPPFLAGS@ @EIGEN_CPPFLAGS@ -I.'
LIBS_RAW=@EIGEN_LIBS@ @DOLFIN_LIBS@
LIBS=$(patsubst %, "%", $(LIBS_RAW))

OCTFILES= Mesh.oct \
             DirichletBC.oct \
             Expression.oct \
             Function.oct \
             save.oct \
             assemble.oct \
             assemble_system.oct \
             plot_func.oct \
             plot_mesh.oct \
             SubSpace.oct \
             feval.oct \
             interpolate.oct


all: $(OCTFILES)

fem_init_env.oct: fem_init_env.o
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) fem_init_env.o -o $@ $(LIBS)

fem_init_env.o:  fem_init_env.cc mesh.h functionspace.h boundarycondition.h function.h coefficient.h form.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c fem_init_env.cc -o $@

Mesh.oct: Mesh.o
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) Mesh.o -o $@ $(LIBS)

Mesh.o: Mesh.cc mesh.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c Mesh.cc -o $@

fem_get_mesh.oct: fem_get_mesh.o
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) fem_get_mesh.o -o $@ $(LIBS)

fem_get_mesh.o: fem_get_mesh.cc
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c fem_get_mesh.cc -o $@

DirichletBC.oct: DirichletBC.o
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) DirichletBC.o -o $@ $(LIBS)

DirichletBC.o: DirichletBC.cc functionspace.h boundarycondition.h expression.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c DirichletBC.cc -o $@

Expression.oct: Expression.o
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) Expression.o -o $@ $(LIBS)

Expression.o: Expression.cc expression.h coefficient.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c Expression.cc -o $@

Function.oct: Function.o
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) Function.o -o $@ $(LIBS)

Function.o: Function.cc function.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c Function.cc -o $@

assemble.oct: assemble.o
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) assemble.o -o $@ $(LIBS)

assemble.o: assemble.cc form.h boundarycondition.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c assemble.cc -o $@

assemble_system.oct: assemble_system.o
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) assemble_system.o -o $@ $(LIBS)

assemble_system.o: assemble_system.cc form.h boundarycondition.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c assemble_system.cc -o $@

save.oct: save.o mkfunction
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) save.o -o ./@function/save.oct $(LIBS)

save.o: save.cc 
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c save.cc -o $@

mkfunction:
	 mkdir -p @function

mkmesh:
	 mkdir -p @mesh

plot_mesh.oct: plot_mesh.o mkmesh
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) plot_mesh.o -o ./@mesh/plot.oct $(LIBS)

plot_mesh.o: plot_mesh.cc Plot_2d.h mesh.h Plot_3d.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c plot_mesh.cc -o $@

Plot_2d.h: Plot_2d.ufl
	$(FFC) -l dolfin Plot_2d.ufl

Plot_3d.h: Plot_3d.ufl
	$(FFC) -l dolfin Plot_3d.ufl

plot_func.oct: plot_func.o mkfunction
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) plot_func.o -o ./@function/plot.oct $(LIBS)

plot_func.o: plot_func.cc Plot_2d.h mesh.h Plot_3d.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c plot_func.cc -o $@

SubSpace.oct: SubSpace.cc functionspace.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -I. SubSpace.cc $(LIBS)

feval.oct: feval.o mkfunction
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) feval.o -o ./@function/feval.oct $(LIBS)

feval.o: feval.cc function.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c feval.cc -o $@

interpolate.oct: interpolate.o
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) interpolate.o -o $@ $(LIBS)

interpolate.o: interpolate.cc function.h
	CPPFLAGS=$(CPPFLAGS) $(MKOCTFILE) -c interpolate.cc -o $@

clean:
	$(RM) *.o core octave-core *.oct *~ *.xml

cleanall:
	$(RM) *.o core octave-core *.oct *~ *.xml *.status *.log \
          octave-workspace configure *.pvd *.vtu
	$(RM) -r autom4te.cache
	$(RM) ../inst/private/get_vars.m
	$(RM) Makefile


