#!/usr/bin/python
import os
import glob
import sys

options = Variables('options.cache', ARGUMENTS)
options.Add(PathVariable('clam_prefix', 'The prefix where CLAM was installed', ''))
options.Add(BoolVariable('verbose', 'Display the full command line instead a short command description', 'no') )
options.Add(BoolVariable('crossmingw', 'Enables MinGW crosscompilation from linux', 'no') )

def scanFiles(pattern, paths) :
	files = []
	for path in paths :
		files+=glob.glob(path+"/"+pattern)
	return files

def recursiveDirs(root) :
	return filter( (lambda a : a.rfind( ".svn")==-1 ),  [ a[0] for a in os.walk(root)]  )

def unique(list) :
	return dict.fromkeys(list).keys()



toolchain = 'default'
if sys.platform == "win32" : toolchain = 'mingw'
env = Environment(tools=[toolchain], options=options)
options.Save('options.cache', env)

#TODO: This didn't work for dynamic linking

def renameEmbededFileSymbols(source, target, env) :
	""" Remove the path part of the symbol name for the embeded file"""
	objdumpOutput=os.popen("objdump -x %s | grep _binary'.*'start"%target[0] , "r").read()
	startSymbol=objdumpOutput.split()[-1]
	infix = startSymbol[len('_binary_'):-len("_start")]
	baseName = os.path.split(str(source[0]))[-1]
	newInfix = infix[-len(baseName):]
	return Execute("objcopy %(target)s "
		"--redefine-sym _binary_%(infix)s_start=_binary_%(newInfix)s_start "
		"--redefine-sym _binary_%(infix)s_end=_binary_%(newInfix)s_end "
		"--redefine-sym _binary_%(infix)s_size=_binary_%(newInfix)s_size " % {
			"infix": infix,
			"newInfix": newInfix,
			"target": target[0],
		}
	)
"""
embededFileBuilder = Builder(
	action=Action([
		["ld", "-fPIC", "--shared", "-b", "binary", "-o", "$TARGET", "$SOURCE"],
		renameEmbededFileSymbols,
		],
		),
	suffix='.os',
	)
env['BUILDERS']['EmbededFile']=embededFileBuilder
"""

env.SConsignFile() # Single signature file

crosscompiling=env['crossmingw']

CLAMInstallDir = env['clam_prefix']
clam_sconstoolspath = os.path.join(CLAMInstallDir,'share','clam','sconstools')
env.Tool('clam', toolpath=[clam_sconstoolspath])
env.Tool('qt4', toolpath=[clam_sconstoolspath])
if crosscompiling :
	env.Tool('crossmingw', toolpath=[clam_sconstoolspath])

env['CXXFILESUFFIX'] = '.cxx'
env['QT4_UICDECLSUFFIX'] = '.hxx'
env['QT4_MOCHPREFIX'] = os.path.join('generated','moc_')
env['QT4_UICDECLPREFIX'] = os.path.join('generated','uic_')
env['QT4_QRCCXXPREFIX'] = os.path.join('generated','qrc_')
if not env['verbose']:
	env['CXXCOMSTR'] = '== Compiling $SOURCE'
	env['LINKCOMSTR'] = '== Linking $TARGET'
	env['SHLINKCOMSTR'] = '== Linking library $TARGET'
	env['QT4_RCCCOMSTR'] = '== Embeding resources $SOURCE'
	env['QT4_UICCOMSTR'] = '== Compiling interface $SOURCE'
	env['QT4_LRELEASECOMSTR'] = '== Compiling translation $TARGET'
	env['QT4_MOCFROMHCOMSTR'] = '== Generating metaobjects for $SOURCE'
	env['QT4_MOCFROMCXXCOMSTR'] = '== Generating metaobjects for $SOURCE'

env.AppendUnique(ASFLAGS='-I. ')

env.EnableClamModules(libs=[
	'clam_core',
	'clam_audioio',
	'clam_processing',
	], path=CLAMInstallDir)

env.EnableQt4Modules([
	'QtCore',
	'QtGui',
	'QtOpenGL',
#	'QtSql',
#	'QtNetwork',
#	'QtTest',
#	'QtXml',
#	'QtSvg',
#	'QtUiTools',
#	'QtDesigner',
#	'Qt3Support',
	], debug=False,
	crosscompiling=crosscompiling,
	)


sourcePaths = []
extraPaths = [
	CLAMInstallDir+'/include',
	CLAMInstallDir+'/include/CLAM', # KLUDGE to keep old style includes
]
includePaths = sourcePaths + extraPaths

sources = scanFiles('*.cxx', sourcePaths)
sources = unique(sources)


singleSourceExamples = [
	"WritingProcessings.cxx",
	"NetworkPersistence_example.cxx",
	"NetworkUsage_example.cxx",
	"AudioApplicationExample.cxx", # TODO: Windows lacks GUIAudioApplication
	"AudioFileReading_example.cxx",
	"AudioFileWriting_example.cxx",
	"AudioIOExample.cxx",
#	"Configurators_example.cxx", # QT4Port
	"DescriptorComputation_example.cxx",
	"FDFilterExample.cxx",
	"FFT_example.cxx",
	"FileInfo_example.cxx",
	"FilePlayback_example.cxx",
	"FundamentalDetect.cxx",
	"LPCAnalysis_example.cxx", # TODO FLTK Dependencies -> Qt4
	"Midi2XmlExample.cxx",
	"MIDIFileReadWriteExample.cxx",
	"MIDIIOExample.cxx",
	"MIDIOut_example.cxx",
	"MIDI_Synthesizer_example.cxx", # TODO: Windows lacks GUIAudioApplication
	"NetworkPersistence_example.cxx",
	"NetworkUsage_example.cxx",
	"OfflineAudioConvolution.cxx",
	"PersistenceThroughDTs_example.cxx",
	"POCompositeExample.cxx",
	"SimplePortsUsage_example.cxx",
	"ProcessingLifeCycle_example.cxx",
	"ProcessingObject_controls_example.cxx",
	"SDIF_And_Segment_example.cxx", # TODO: FLTK Dependencies
	"Spectrum_example.cxx",
	"StereoToMonoFile.cxx",
#	"ThreadedProcessing_example.cxx", # TODO: Depends on Resample and FLTK
	"Tutorial/UserTutorial1.cxx",
	"Tutorial/UserTutorial2.cxx",
	"Tutorial/UserTutorial3.cxx",
	"Tutorial/UserTutorial4.cxx",
	"Tutorial/UserTutorial5.cxx",
	"Tutorial/UserTutorial6.cxx",
]


directoryBasedExamples = [
	"PortsAndControlsUsageExample",
	"ControlArrayExamples",
	"Wav2SDIF",
	"SDIF2Wav",
	"SDIF2WavStreaming",
]

directoryBasedLibraries = [
#	"PluginExamples/ClamLadspaPluginExample",
	"PluginExamples/ClamNativePluginExample",
# TODO: Files to be integred on the Network editor
#	"PluginExamples/LadspaOSCRemoteController",
]

singleSourceLibraries = [
]

env.Append(CPPPATH=includePaths)
env.AppendUnique(CPPFLAGS=["-g", "-Wall"])
#env.AppendUnique(DEFINES=["_DEBUG"])

examples = []

for libsource in singleSourceLibraries :
	library = os.path.basename(libsource)
	examples += [ env.SharedLibrary(source = libsource ) ]

for folder in directoryBasedLibraries :
	librarySources = glob.glob(folder+"/*.cxx")
#	librarySources += [env.EmbededFile(file) for file in glob.glob(folder+"/*.clamnetwork")]
	library = os.path.basename(folder)
	examples += [ env.SharedLibrary(target=library, source = librarySources ) ]

for main in singleSourceExamples :
	executable = os.path.splitext(os.path.basename(main))[0]
	examples += [ env.Program(target=executable, source = sources + [main] ) ]

for folder in directoryBasedExamples :
	exampleSources = glob.glob(folder+"/*.cxx")
	executable = os.path.basename(folder)+"Exe"
	examples += [ env.Program(target=executable, source = sources + exampleSources ) ]

if not crosscompiling :
	# Still having problems crosscompiling aubio
	tickEnv = env.Clone()
	tickEnv.AppendUnique(CPPPATH=['TickExtractor/libresample-0.1.3/include'])
	tickEnv.ParseConfig('pkg-config aubio --cflags --libs')
	tickSrc = glob.glob("TickExtractor/*cxx") + glob.glob("TickExtractor/libresample-0.1.3/src/*.c")
	examples += [ tickEnv.Program(target="TickExtractorExe", source = tickSrc) ]

env.Alias('examples',examples)

env.Default(examples)



