#! /usr/bin/env python
# encoding: utf-8

import shutil, os

def configure (conf):
	conf.env.append_unique ("INCLUDES", ["../src/%s" % p for p in 
		". arithmetic bisector combinatorial contractor function numeric geometry parser set strategy symbolic system tools predicate  integrate cliquer".split()])

def build (bld):

	INCDIR  = "${PREFIX}/include/ibex"
	JAVADIR = "${PREFIX}/share/java"

	ibex_src = bld.path.ant_glob ("**/*.(cpp|yc|l)")

	ibex_hdr = bld.path.ant_glob ("**/ibex_*.h")
	ibex_hdr.append ("ibex_Setting.h")
	ibex_hdr.append ("cliquer/cliquer.h")
	ibex_hdr.append ("cliquer/set.h")
	ibex_hdr.append ("cliquer/graph.h")
	ibex_hdr.append ("cliquer/reorder.h")
	ibex_hdr.append ("cliquer/misc.h")
	ibex_hdr.append ("cliquer/cliquerconf.h")

	if (bld.env.WITH_AMPL):
		# headers
		@bld.rule (
			target = "ibex_Setting.h",
			vars   = ["LP_LIB","INTERVAL_LIB"],
		)
		def _(tsk):
			tsk.outputs[0].write (
				"// This file is automatically generated */\n" +
				"#define _IBEX_RELEASE_ \"%s\" \n" % tsk.env['VERSION'] +
				"#define _IBEX_WITH_%s_ 1\n" % tsk.env['INTERVAL_LIB'] +
				"#define _IBEX_WITH_%s_ 1\n" % tsk.env['LP_LIB'] +
				"#define _IBEX_WITH_AMPL_ 1\n"  )
	else:
		# headers
		@bld.rule (
			target = "ibex_Setting.h",
			vars   = ["LP_LIB","INTERVAL_LIB"],
		)
		def _(tsk):
			tsk.outputs[0].write (
				"// This file is automatically generated */\n" +
				"#define _IBEX_RELEASE_ \"%s\" \n" % tsk.env['VERSION'] +
				"#define _IBEX_WITH_%s_ 1\n" % tsk.env['INTERVAL_LIB'] +
				"#define _IBEX_WITH_%s_ 1\n" % tsk.env['LP_LIB'] )
	
	@bld.rule (
		target = "ibex.h",
		name   = "ibex_headers",
		source = ibex_hdr,
		install_path = INCDIR,
	)
	def _(tsk):
		tsk.outputs[0].write (
			"// This file is automatically generated\n"
			+ "".join ('#include "%s"\n' % h.name for h in tsk.inputs))
	
	bld.install_files (INCDIR, ibex_hdr)
	bld.install_files (INCDIR, bld.path.ant_glob ("**/ibex_*.h_"))

	# JNI
	if bld.env.WITH_JNI:
		JAVA_PACKAGE   = bld.env.JAVA_PACKAGE
		JAVA_SIGNATURE = JAVA_PACKAGE.replace (".", "_")
		JAVA_PATH      = JAVA_PACKAGE.replace (".", "/")


		@bld.rule (
			target = "java/ibex_Java.cpp",
			source = "java/ibex_Java.cpp_",
			vars = ["JAVA_PACKAGE"],
		)
		def _(tsk):
			tsk.outputs[0].write (
				"// This file is generated from %s.\n"
				'#include "%s_Ibex.h_"\n%s'
				% (tsk.inputs[0].name, JAVA_SIGNATURE, 
				   tsk.inputs[0].read().replace ("Java_", "Java_%s_" % JAVA_SIGNATURE)
				))

		for (name, snippet) in (
			("Ibex", "package %s;\n" % JAVA_PACKAGE),
			("Test", "import %s.Ibex;\n" % JAVA_PACKAGE),
		):
			@bld.rule (
				target = "java/%s.java" % name,
				source = "java/%s.java_" % name,
				vars = ["JAVA_PACKAGE"],
				snippet = snippet,
			)
			def _(tsk):
				tsk.outputs[0].write (
					"// This file is generated from %s.\n"
					"%s\n%s"
					% (tsk.inputs[0].name, tsk.generator.snippet, tsk.inputs[0].read()))

		bld (
			target = "java/%s/Ibex.class" % JAVA_PATH,
			source = "java/Ibex.java",
			rule   = "${JAVAC} -d src/java ${SRC}"
		)

		bld (
			target = "java/Test.class",
			source = "java/Test.java",
			rule   = "${JAVAC} -d src/java -cp src/java ${SRC}",
			after  = "java/%s/Ibex.class" % JAVA_PATH,
		)

		bld (
			target = "java/%s_Ibex.h_" % JAVA_SIGNATURE,
			source = "java/%s/Ibex.class" % JAVA_PATH,
			rule   = "${JAVAH} -jni -classpath src/java -o ${TGT} %s.Ibex" % JAVA_PACKAGE
		)

		bld.shlib (
			target = "ibex-java",
			source = "java/ibex_Java.cpp",
			use = "JAVA ibex",
			install_path = bld.env.LIBDIR,
		)
		bld (
			target = "%s.jar" % JAVA_PACKAGE,
			source = "java/%s/Ibex.class" % JAVA_PATH,
			rule = "${JAR} cf ${TGT} -C src/java %s/Ibex.class" % JAVA_PATH,
			install_path = JAVADIR,
		)


	# c++ compilation
	tg_ibex = (bld.shlib if bld.env.ENABLE_SHARED else bld.stlib) (
		target = "ibex",
		use  = "gaol_objs gdtoa_objs ultim_objs filib_obj ampl_obj IBEX_DEPS",
		source = ibex_src,
		install_path = bld.env.LIBDIR,
	)

	# pkg-config file
	
	bld.env.include_pkgconfig=""
	for p in bld.env.INCLUDES_IBEX_DEPS + bld.env.INCLUDES:
		if p not in [os.path.join (bld.env.PREFIX, "include")]:
			bld.env.append_unique ("include_pkgconfig",p)
		
	@bld.rule (
		target = "ibex.pc",
		vars = "PREFIX VERSION INCLUDES LIBPATH_IBEX_DEPS LIB_IBEX_DEPS".split(),
		install_path = "${PREFIX}/share/pkgconfig",
	)
	def _ (tsk):
		tsk.outputs[0].write("""
prefix=%s
includedir=${prefix}/include
libdir=${prefix}/lib

Name: ibex
Description: A C++ library for interval-based algorithm design
Version: %s
Cflags: -I${includedir} -I${includedir}/ibex %s %s
Libs: -L${libdir} %s -libex %s
""" % (		tsk.env.PREFIX, tsk.env.VERSION,
		# extra CFLAGS
		# TODO: maybe remove INCLUDES ?
		" ".join(("-I%s" % p) for p in filter (os.path.isabs, tsk.env.include_pkgconfig)),
		# FIXME: are we allowed to include arbitrary cflags (other that -I) ?
		" ".join(tsk.env.CXXFLAGS_IBEX_DEPS),
		# extra LIBPATH
		" ".join(("-L%s" % p) for p in filter (os.path.isabs, tsk.env.LIBPATH_IBEX_DEPS)),
		# extra LIB
		" ".join(("-l%s" % l) for l in tsk.env.LIB_IBEX_DEPS),
	))

