import fnmatch

Import('env', 'os', 'sys', 'plugins', 'dist', 
	'MTS_VERSION', 'hasQt', 'hasCollada', 'hasPython')

installTargets = []

def fixOSXPluginPath(plugin):
	return env.AddPostAction(plugin,
		'install_name_tool -change @loader_path/../Frameworks/libmitsuba-core.dylib @loader_path/../Contents/Frameworks/libmitsuba-core.dylib ${TARGET}; ' +
		'install_name_tool -change @loader_path/../Frameworks/libmitsuba-render.dylib @loader_path/../Contents/Frameworks/libmitsuba-render.dylib ${TARGET}; ' +
		'install_name_tool -change @loader_path/../Frameworks/libmitsuba-hw.dylib @loader_path/../Contents/Frameworks/libmitsuba-hw.dylib ${TARGET}; ' +
		'install_name_tool -change @loader_path/../Frameworks/libmitsuba-bidir.dylib @loader_path/../Contents/Frameworks/libmitsuba-bidir.dylib ${TARGET}; ' +
		'install_name_tool -change @loader_path/../Frameworks/libboost_system.dylib @loader_path/../Contents/Frameworks/libboost_system.dylib ${TARGET}; ' +
		'install_name_tool -change @loader_path/../Frameworks/libboost_filesystem.dylib @loader_path/../Contents/Frameworks/libboost_filesystem.dylib ${TARGET};' +
		'install_name_tool -change @loader_path/../Frameworks/libboost_python.dylib @loader_path/../Contents/Frameworks/libboost_python.dylib ${TARGET}'
	)

def install(target, paths, prefix = None):
	global installTargets
	if prefix == None:
		prefix = env['BUILDDIR']
	for path in paths:
		if os.path.splitext(path)[1] == '.dylib':
			installTargets += env.OSXLibInst(target, prefix + '/' + path)
		else:
			installTargets += env.Install(target, prefix + '/' + path)

def installAs(target, path, prefix = None):
	global installTargets
	if prefix == None:
		prefix = env['BUILDDIR']
	if os.path.splitext(path)[1] == '.dylib':
		result = env.OSXLibInstAs(target, prefix + '/' + path)
	else:
		result = env.InstallAs(target, prefix + '/' + path)
	installTargets += result
	return result

if not 'DISTDIR' in env:
	print 'The \"DISTDIR\" variable is missing. Please update your configuration file!'
	Exit(1)

distDir = env.GetBuildPath(env['DISTDIR'])
basePath = env.GetBuildPath('#')

for file in os.listdir(env.GetBuildPath('#data/schema')):
	if fnmatch.fnmatch(file, '*.xsl') or fnmatch.fnmatch(file, '*.xsd'):
		installTargets += env.Install(os.path.join(distDir, 'data/schema'), '#data/schema/' + file)
for file in os.listdir(env.GetBuildPath('#data/ior')):
	if fnmatch.fnmatch(file, '*.spd'):
		installTargets += env.Install(os.path.join(distDir, 'data/ior'), '#data/ior/' + file)

if sys.platform == 'linux2':
	for plugin in plugins:
		installTargets += env.Install(os.path.join(distDir, 'plugins'), plugin)
	install(distDir, ['libcore/libmitsuba-core.so', 'libhw/libmitsuba-hw.so',
			'librender/libmitsuba-render.so', 'libbidir/libmitsuba-bidir.so'])
	if hasPython:
		install(os.path.join(distDir, 'python'), ['libpython/mitsuba.so'])
	install(distDir, ['mitsuba/mitsuba', 'mitsuba/mtssrv', 'mitsuba/mtsutil', 'mtsgui/mtsgui'])
	if hasCollada:
		install(distDir, ['converter/mtsimport'])
if sys.platform == 'win32':
	for plugin in plugins:
		if '.dll' in plugin.__str__():
			installTargets += env.Install(os.path.join(distDir, 'plugins'), plugin)

	if 'WIN64' in env['CXXFLAGS']:
		dllprefix='#dependencies/windows/lib64'
	else:
		dllprefix='#dependencies/windows/lib32'

	if env['MSVC_VERSION'] == '9.0':
		compilerType = 'vc90'
	elif env['MSVC_VERSION'] == '10.0':
		compilerType = 'vc100'
	else:
		raise Exception('Unknown compiler version!')

	if hasCollada:
		install(distDir, ['converter/mtsimport.exe'])
	sdkDir = os.path.join(distDir, "sdk")
	sdkLibDir = os.path.join(sdkDir, "lib")

	install(distDir, ['mitsuba/mitsuba.exe', 'mitsuba/mtssrv.exe', 'mitsuba/mtsutil.exe'])
	install(distDir, ['libcore/libmitsuba-core.dll', 'libhw/libmitsuba-hw.dll',
			'librender/libmitsuba-render.dll', 'libbidir/libmitsuba-bidir.dll'])
	install(sdkLibDir, ['libcore/mitsuba-core.lib', 'libhw/mitsuba-hw.lib',
			'librender/mitsuba-render.lib', 'libbidir/mitsuba-bidir.lib'])
	for entry in os.walk(os.path.join(basePath, "include")):
		includeDir = entry[0][len(basePath)+1:]
		installTargets += env.Install(os.path.join(sdkDir, includeDir),
			[ ('#' + os.path.join(includeDir, fname)) for fname in entry[2] ])
	if hasPython:
		installAs(os.path.join(distDir, 'python/mitsuba.pyd'), 'libpython/mitsuba.dll')
	install(distDir, ['Iex.dll', 'Half.dll','IlmThread.dll', 'Imath.dll','IlmImf.dll','zlib1.dll',
		'libpng13.dll',	'jpeg62.dll', 'pthreadVCE2.dll', 'xerces-c_3_0.dll', 'glew32mx.dll'],
		prefix=dllprefix)
	install(distDir, ['libcollada14dom23.dll', 'boost_python-%s-mt-1_44.dll' % compilerType,
		'boost_system-%s-mt-1_44.dll' % compilerType, 'boost_filesystem-%s-mt-1_44.dll' % compilerType],
		dllprefix + '/' + compilerType + '/')
	if 'WIN64' in env['CXXFLAGS']:
		installTargets += env.Install(distDir, '#dependencies/windows/bin/vcredist_2010_sp1_x64.exe')
	else:
		installTargets += env.Install(distDir, '#dependencies/windows/bin/vcredist_2010_sp1_x86.exe')
	installTargets += env.Install(distDir, '#data/windows/README.txt')

	if 'REDIST_PATH' in env:
		install(distDir, ['libmmd.dll', 'libiomp5md.dll'], prefix = env['REDIST_PATH'])

	if hasQt:
		install(distDir, ['mtsgui/mtsgui.exe'])
		install(distDir, ['QtCore4.dll', 'QtGui4.dll', 'QtXml4.dll',
			'QtNetwork4.dll', 'QtOpenGL4.dll', 'QtXmlPatterns4.dll'], prefix = env['QT4_BINPATH'])
elif sys.platform == 'darwin':
	for i in plugins:
		plugin = env.Install(os.path.join(distDir, 'plugins'), i)
		installTargets += fixOSXPluginPath(plugin)
	for entry in os.walk(os.path.join(basePath, "include")):
		includeDir = entry[0][len(basePath)+1:]
		installTargets += env.Install(os.path.join(os.path.join(distDir, 'Headers'), includeDir),
			[ ('#' + os.path.join(includeDir, fname)) for fname in entry[2] ])
	install(os.path.join(distDir, 'Contents/MacOS'), ['mitsuba/mitsuba', 'mitsuba/mtssrv', 'mitsuba/mtsutil'])
	if hasCollada:
		install(os.path.join(distDir, 'Contents/MacOS'), ['converter/mtsimport'])
	plist = env.Install(os.path.join(distDir, 'Contents'), '#data/darwin/Info.plist')
	installTargets += plist
	installTargets += env.AddPostAction(plist, 'perl -pi -e "s/MTS_VERSION/%s/" $TARGET' % MTS_VERSION)
	installTargets += env.Install(os.path.join(distDir, 'Contents'), '#data/darwin/PkgInfo')
	installTargets += env.Install(os.path.join(distDir, 'Contents/Resources'), '#data/darwin/Resources/mitsuba.icns')
	frameworkDir = os.path.join(distDir, 'Contents/Frameworks')

	install(frameworkDir, ['libcore/libmitsuba-core.dylib', 'libhw/libmitsuba-hw.dylib',
		'librender/libmitsuba-render.dylib', 'libbidir/libmitsuba-bidir.dylib'])
	if hasPython:
		plugin = installAs(os.path.join(distDir, 'python/mitsuba.so'), 'libpython/mitsuba.dylib')
		installTargets += fixOSXPluginPath(plugin)
	install(frameworkDir, [
		'GLEW.framework/Resources/libs/libGLEW.dylib', 'OpenEXR.framework/Resources/lib/libHalf.6.dylib',
		'OpenEXR.framework/Resources/lib/libIex.6.dylib', 'OpenEXR.framework/Resources/lib/libImath.6.dylib',
		'OpenEXR.framework/Resources/lib/libIlmThread.6.dylib', 'OpenEXR.framework/Resources/lib/libIlmImf.6.dylib',
		'Xerces-C.framework/Resources/lib/libxerces-c-3.0.dylib', 'libpng.framework/Resources/lib/libpng.dylib', 
		'libjpeg.framework/Resources/lib/libjpeg.dylib', 'libboost.framework/Resources/lib/libboost_python.dylib',
		'libboost.framework/Resources/lib/libboost_system.dylib',
		'libboost.framework/Resources/lib/libboost_filesystem.dylib'], '#dependencies/darwin')
	if hasCollada:
		install(frameworkDir, [
			'Collada14Dom.framework/Resources/lib/libCollada14Dom.dylib'], '#dependencies/darwin')
	if hasQt:
		install(os.path.join(distDir, 'Contents/MacOS'), ['mtsgui/mtsgui'])
		install(os.path.join(distDir, 'Contents/MacOS'), ['mtsgui/symlinks_install'])
		installTargets += env.OSXLibInst(frameworkDir, '/Library/Frameworks/QtCore.framework/Versions/4/QtCore')
		opengl = env.OSXLibInst(frameworkDir, '/Library/Frameworks/QtOpenGL.framework/Versions/4/QtOpenGL')
		xml = env.OSXLibInst(frameworkDir, '/Library/Frameworks/QtXml.framework/Versions/4/QtXml')
		xmlpatterns = env.OSXLibInst(frameworkDir, '/Library/Frameworks/QtXmlPatterns.framework/Versions/4/QtXmlPatterns')
		network = env.OSXLibInst(frameworkDir, '/Library/Frameworks/QtNetwork.framework/Versions/4/QtNetwork')
		gui = env.OSXLibInst(frameworkDir, '/Library/Frameworks/QtGui.framework/Versions/4/QtGui')
		installTargets += env.AddPostAction(xml, 'install_name_tool -change QtCore.framework/Versions/4/QtCore @loader_path/../Frameworks/QtCore $TARGET')
		installTargets += env.AddPostAction(xmlpatterns, 'install_name_tool -change QtCore.framework/Versions/4/QtCore @loader_path/../Frameworks/QtCore $TARGET')
		installTargets += env.AddPostAction(xmlpatterns, 'install_name_tool -change QtNetwork.framework/Versions/4/QtNetwork @loader_path/../Frameworks/QtNetwork $TARGET')
		installTargets += env.AddPostAction(network, 'install_name_tool -change QtCore.framework/Versions/4/QtCore @loader_path/../Frameworks/QtCore $TARGET')
		installTargets += env.AddPostAction(gui, 'install_name_tool -change QtCore.framework/Versions/4/QtCore @loader_path/../Frameworks/QtCore $TARGET')
		installTargets += env.AddPostAction(opengl, 'install_name_tool -change QtCore.framework/Versions/4/QtCore @loader_path/../Frameworks/QtCore $TARGET')
		installTargets += env.AddPostAction(opengl, 'install_name_tool -change QtGui.framework/Versions/4/QtGui @loader_path/../Frameworks/QtGui $TARGET')
		installTargets += env.Install(os.path.join(distDir, 'Contents/Resources'), '/Library/Frameworks//QtGui.framework/Versions/4/Resources/qt_menu.nib')
		installTargets += env.Install(os.path.join(distDir, 'Contents/Resources/PreviewSettings.nib'), '#data/darwin/PreviewSettings.nib/designable.nib')
		installTargets += env.Install(os.path.join(distDir, 'Contents/Resources/PreviewSettings.nib'), '#data/darwin/PreviewSettings.nib/keyedobjects.nib')
		installTargets += env.Install(os.path.join(distDir, 'Contents/Resources'), '#data/darwin/qt.conf')
		installTargets += env.Install(os.path.join(distDir, 'Contents/Frameworks/BWToolkitFramework.framework/Versions/A'),
			'#dependencies/darwin/BWToolkitFramework.framework/Versions/A/BWToolkitFramework')
		for file in os.listdir(env.GetBuildPath('#dependencies/darwin/BWToolkitFramework.framework/Versions/A/Resources')):
			if fnmatch.fnmatch(file, '*.pdf') or fnmatch.fnmatch(file, '*.tiff') or fnmatch.fnmatch(file, '*.tif') or fnmatch.fnmatch(file, '*.png') or fnmatch.fnmatch(file, '*.rtf') or fnmatch.fnmatch(file, '*.plist'):
				installTargets += env.Install(os.path.join(distDir, 'Contents/Frameworks/BWToolkitFramework.framework/Resources'), '#dependencies/darwin/BWToolkitFramework.framework/Versions/A/Resources/' + file)

if dist:
	if sys.platform == 'win32':
		bits = 64 if 'WIN64' in env['CXXFLAGS'] else 32
		distCommand = env.GetBuildPath('#data/windows/build-dist.bat')
		distTarget = env.Command("Mitsuba %s %ibit.zip" % (MTS_VERSION, bits), [], "%s %s %i" % (distCommand, MTS_VERSION, bits))
		Depends(distTarget, installTargets)
	elif sys.platform == 'darwin':
		distTarget = env.Command("Mitsuba %s.dmg" % MTS_VERSION, [], "#data/darwin/build-dmg.sh %s" % MTS_VERSION)
		Depends(distTarget, installTargets)
	elif sys.platform == 'linux2':
		env.Command("mitsuba-%s.tar.gz" % MTS_VERSION, [], "#data/linux/build-sourcedist.sh %s" % MTS_VERSION)