import os
import sys
import glob
import SCons
import shutil

# BIG FAT WARNING:
# Make sure you use TABS for indentation, NOT spaces! (Python doesn't like spaces, be forewarned!)
#
#   ####       ####  ##########  #####    #####  #####    #####  #####    #####
#   ######   ######     ####      #####  #####    #####  #####    #####  #####
#   #### ## ## ####     ####        ########        ########        ########
#   ####   #   ####     ####      #####  #####    #####  #####    #####  #####
#   ####       ####  ##########  #####    #####  #####    #####  #####    #####
#
#  #############################################################################
#    #########################################################################
#

#
#Useful functions
#

def getSVNRevision(): # GPL code taken from http://trac.zeitherrschaft.org/zzub/browser/trunk/SConstruct
	# if this is a repository, take the string from svnversion
	svnversionpath = env.WhereIs('svnversion', os.environ['PATH'])
	if os.path.isdir('../.svn') and (svnversionpath != None):  # we always start in .obj for some reason, so we must use ../.svn
		rev = os.popen('svnversion ..').readline().strip()
		if rev != "" and rev != "exported":
			return rev
	return ""

#Checks for OpenGL on all three platforms
def CheckOpenGL():
	if not conf.CheckLib('GL') and not conf.CheckLib('opengl32') and not conf.CheckCHeader('/System/Library/Frameworks/OpenGL.framework/Versions/A/Headers/gl.h') and not conf.CheckCHeader('GL/gl.h'):
		print 'Did not find OpenGL development files, exiting!'
		Exit(1)

	if not conf.CheckLib('GLU') and not conf.CheckLib('glu32') and not conf.CheckCHeader('/System/Library/Frameworks/OpenGL.framework/Versions/A/Headers/glu.h'):
		print 'Did not find GLU development files, exiting!'
		Exit(1)
	#Workaround for SCONS not detecting frameworks on OS X
	if platform == 'osx':
		env.Append(LINKFLAGS = '-framework OpenGL')

	return

#Checks for OGG/Vorbis on all three platforms
def CheckOggVorbis():
	#Check for Ogg and Vorbis on Linux, OS X, and Win32
	if not conf.CheckLib('vorbisfile'):
		print 'Did not find libvorbisfile.a, libvorbisfile.lib, or the libvorbisfile development headers, exiting!'
		Exit(1)

	if not conf.CheckLib('vorbis'):
		print 'Did not find libvorbis.a, libvorbis.lib, or the libvorbisfile development headers, exiting!'
		Exit(1)

	if not conf.CheckLib('ogg'):
		print 'Did not find libogg.a, libogg.lib, or the libogg development headers, exiting!'
		Exit(1)

# This function is here for historical reasons. It used to be easiest to build
# Mixxx on OS X using the Vorbis and OGG "frameworks", and so this function
# used to have some OS X-specific stuff in it. If you're building on OS X now
# though, just install libvorbis and libogg from source.

	return

#Check for FFMPEG support
def CheckFFMPEG(conf, sources):
	flags_ffmpeg = ARGUMENTS.get('ffmpeg', 0)
	if int(flags_ffmpeg):
		if platform == 'linux':
			#Check for libavcodec, libavformat
			#I just randomly picked version numbers lower than mine for this - Albert
			if not conf.CheckForPKG('libavcodec', '51.20.0'):
				print 'libavcodec not found.'
				Exit(1)
			if not conf.CheckForPKG('libavformat', '51.1.0'):
				print 'libavcodec not found.'
				Exit(1)
			else:
				#Grabs the libs and cflags for ffmpeg
				env.ParseConfig('pkg-config libavcodec --silence-errors --cflags --libs')
				env.ParseConfig('pkg-config libavformat --silence-errors --cflags --libs')
				env.Append(CXXFLAGS = '-D__FFMPEGFILE__')
		else:
			# aptitude install libavcodec-dev libavformat-dev liba52-0.7.4-dev libdts-dev
			env.Append(LIBS = 'avcodec')
			env.Append(LIBS = 'avformat')
			env.Append(LIBS = 'z')
			env.Append(LIBS = 'a52')
			env.Append(LIBS = 'dts')
			env.Append(LIBS = 'gsm')
			env.Append(LIBS = 'dc1394_control')
			env.Append(LIBS = 'dl')
			env.Append(LIBS = 'vorbisenc')
			env.Append(LIBS = 'raw1394')
			env.Append(LIBS = 'avutil')
			env.Append(LIBS = 'vorbis')
			env.Append(LIBS = 'm')
			env.Append(LIBS = 'ogg')
			env.Append(CXXFLAGS = '-D__FFMPEGFILE__')
		sources += Split("""soundsourceffmpeg.cpp """)
		print "Not working FFMPEG support... enabled"
	else:
		print "Not working FFMPEG support... disabled"
	return	


# Checks for pkg-config on Linux
def CheckForPKGConfig( context, version='0.0.0' ):
	context.Message( "Checking for pkg-config (at least version %s)... " % version )
	ret = context.TryAction( "pkg-config --atleast-pkgconfig-version=%s" %version )[0]
	context.Result( ret )
	return ret

# Uses pkg-config to check for a minimum version
def CheckForPKG( context, name, version="" ):
	if version == "":
		context.Message( "Checking for %s... \t" % name )
		ret = context.TryAction( "pkg-config --exists '%s'" % name )[0]
	else:
		context.Message( "Checking for %s (%s or higher)... \t" % (name,version) )
		ret = context.TryAction( "pkg-config --atleast-version=%s '%s'" % (version,name) )[0]
		context.Result( ret )
	return ret
	

def flatten(x):
	"""flatten(sequence) -> list

	Returns a single, flat list which contains all elements retrieved
	from the sequence and all recursively contained sub-sequences
	(iterables).

	Examples:
	>>> [1, 2, [3,4], (5,6)]
	[1, 2, [3, 4], (5, 6)]
	>>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, MyVector(8,9,10)])
	[1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10]"""

	result = []
	for el in x:
		#if isinstance(el, (list, tuple)):
		if hasattr(el, "__iter__"):
			result.extend(flatten(el))
		else:
			result.append(el)
	return result

def getFlags(env, argflag, default=0):
	"""
	* get value passed as an argument to scons as argflag=value
	* if no value is passed to scons use stored value
	* if no value is stored, use default
	Returns the value and stores it in env[argflag]
	"""
	flags = ARGUMENTS.get(argflag, -1)
	if int(flags) < 0:
		if env.has_key(argflag):
			flags = env[argflag]
		else: #default value
			flags = default
	env[argflag] = flags
	return flags

###### MAIN LINE ######
#######################
#Get the platform/OS that we're building on:
if os.name == 'nt':
	print 'Platform: Windows'
	platform = 'win32'
elif sys.platform == 'linux2':
	print 'Platform: Linux'
	platform = 'linux'
elif sys.platform == 'darwin':
	print 'Platform: OS X'
	platform = 'osx'
else:
	print 'Platform: Unknown (assuming Linux-like)'
	platform = 'linux'

#Figure out what the QT path is
if platform == 'linux':
	default_qtdir = '/usr/share/qt4'
elif platform == 'osx':
	default_qtdir = '/usr/local/Trolltech/Qt-4.3.2/'
elif platform == 'win32':
	default_qtdir = 'C:\\qt\\4.3.0'

#Read the qtdir flag, if it was set explicitly
flags_qtdir = ARGUMENTS.get('qtdir', default_qtdir)
if not os.path.exists(flags_qtdir) and platform != 'osx': #OS X doesn't have a qt path.
	print "Error: QT path does not exist or QT4 is not installed."
	print "Please specify your QT path by running 'scons qtdir=[path]'"
	Exit(1)
elif flags_qtdir.find("qt3") != -1 or flags_qtdir.find("qt/3") != -1:
	print "Error: Mixxx now requires QT4 instead of QT3 - please use your QT4 path with the qtdir build flag."
	Exit(1)
else:
	print "QT path: " + flags_qtdir


#Set up our environment, tell SCONS to use it's QT tools, and set some enviroment variables for it.
#The ENV = os.environ part pulls in your existing environment variables. This is useful for awkward Linux setups
#and on Windows where all the paths are set in the shell.
if platform == 'linux' or platform == 'osx':
	env = Environment(tools=['default','qt4', 'msvs'], toolpath=['../', './'], QTDIR=flags_qtdir, QT_LIB='', ENV = os.environ)
 	os.environ['PKG_CONFIG_PATH']=flags_qtdir+'lib/pkgconfig'  #Set the PKG_CONFIG_PATH explicitly, handles multiple QT 4.x installations
elif platform == 'win32':
	#Pull in the environment's variables for win32...
	env = Environment(tools=['default','qt4', 'msvs'], toolpath=['../', './'], QTDIR=flags_qtdir, QT_LIB='', VCINSTALLDIR = os.getenv('VCInstallDir'), ENV = os.environ)
#	env.Append(LIBPATH = (flags_qtdir + "/plugins/iconengines"))

## Global cache directory
## Put all project files in it so a rm -rf cache will clean up the config
if not env.has_key('CACHEDIR'):
  env['CACHEDIR'] =os.getcwd()+ '/../../cache/'
if not os.path.isdir(env['CACHEDIR']):
  os.mkdir(env['CACHEDIR'])

## Avoid spreading .sconsign files everywhere
#env.SConsignFile(env['CACHEDIR']+'/scons_signatures')
## WARNING - We found that the above line causes SCons to randomly not find
##           dependencies for some reason. It might not happen right away, but
##           a good number of users found that it caused weird problems - Albert (May 15/08)


#Hijack scons -h and --help
cachefile = env['CACHEDIR'] + 'custom.py'
opts = Options(cachefile)
opts.Add('prefix', 'Set to your install prefix', '/usr/local')
opts.Add('qtdir', 'Set to your QT4 directory', '/usr/share/qt4')
opts.Add('djconsole', 'Set to 1 to enable Hercules support through libdjconsole', 0)
opts.Add('djconsole_legacy', 'Set to 1 to enable legacy Hercules support (for Hercules MP3 Control only, not MK2', 0)
opts.Add('hifieq', 'Set to 1 to enable high quality EQs', 1)
opts.Add('ipod', 'Set to 1 to enable iPod support through libgpod', 0)
opts.Add('ladspa', '(EXPERIMENTAL) Set to 1 to enable LADSPA plugin support', 0)
opts.Add('ffmpeg', '(EXPERIMENTAL) Set to 1 to enable FFMPEG support', 0)
opts.Add('vinylcontrol', 'Set to 1 to enable vinyl control support', 1)
opts.Add('shoutcast', 'Set to 1 to enable shoutcast support', 0)
opts.Add('msvshacks', 'Set to 1 to build properly with MS Visual Studio 2005 (Express users should leave this off)', 0)
opts.Add('cmetrics', 'Set to 1 to enable crash reporting/usage statistics via Case Metrics (This should be disabled on development builds)', 0)
opts.Add('optimize', 'Set to 1 to enable -O3 compiler optimizations. Set to 2 to enable Pentium 4 optimizations. Set to 3 to enable Intel Core optimizations, and set to 4 to enable Intel Core 2 optimizations.', 1)
if not platform == 'win32':
	opts.Add('gprof', '(DEVELOPER) Set to 1 to enable profiling using gprof', 0)
	opts.Add('tuned', '(EXPERIMENTAL) Set to 1 to optimise mixxx for this CPU', 0)
	opts.Add('force32', 'Set to 1 to force GCC to compile a 32-bit binary with the -m32 flag', 0)
#env = Environment(options = opts)
opts.Update(env)
Help(opts.GenerateHelpText(env))

# user-defined CXXFLAGS
if os.environ.has_key('CXXFLAGS'):
	env.Append(CXXFLAGS = SCons.Util.CLVar( os.environ['CXXFLAGS'] ))
# user-defined CCFLAGS
if os.environ.has_key('CCFLAGS'):
	env.Append(CCFLAGS = SCons.Util.CLVar(os.environ['CCFLAGS']))

### embed SVN version into build
build_rev = getSVNRevision()
### Old way - causes everything to be rebuilt each time the SVN ver moves. :(
#if build_rev != '':
# 	env.Append(CXXFLAGS = '-DBUILD_REV=\\"' + build_rev + '\\"')
### Put version info into a file, so it doesn't force a rebuild of everything :)
f = open("../.mixxx_version.svn","w")
try:
	f.write('#define BUILD_REV "' + build_rev + '"\n')
finally:
	f.close()

#Mixxx sources to build
sources = Split("""enginebuffercue.cpp input.cpp mixxxmenuplaylists.cpp trackplaylistlist.cpp mixxxkeyboard.cpp configobject.cpp controlobjectthread.cpp
 controlobjectthreadwidget.cpp controlobjectthreadmain.cpp controlevent.cpp controllogpotmeter.cpp controlobject.cpp controlnull.cpp controlpotmeter.cpp
 controlpushbutton.cpp controlttrotary.cpp controlbeat.cpp dlgpreferences.cpp dlgprefsound.cpp dlgprefmidi.cpp dlgprefplaylist.cpp dlgprefcontrols.cpp dlgbpmtap.cpp dlgprefbpm.cpp dlgbpmscheme.cpp dlgabout.cpp
 dlgprefeq.cpp dlgprefcrossfader.cpp enginebuffer.cpp enginebufferscale.cpp enginebufferscalelinear.cpp engineclipping.cpp enginefilterblock.cpp enginefilteriir.cpp  enginefilter.cpp engineobject.cpp
 enginepregain.cpp enginevolume.cpp main.cpp midiobject.cpp midiobjectnull.cpp mixxx.cpp mixxxview.cpp
 soundsourcemp3.cpp soundsourceoggvorbis.cpp enginechannel.cpp enginemaster.cpp wwidget.cpp wpixmapstore.cpp wlabel.cpp wnumber.cpp wnumberpos.cpp wnumberrate.cpp wnumberbpm.cpp wknob.cpp wdisplay.cpp wvumeter.cpp wpushbutton.cpp wslidercomposed.cpp wslider.cpp  wstatuslight.cpp enginedelay.cpp engineflanger.cpp enginespectralfwd.cpp mathstuff.cpp readerextract.cpp readerextractwave.cpp
 readerevent.cpp rtthread.cpp windowkaiser.cpp probabilityvector.cpp reader.cpp enginevumeter.cpp peaklist.cpp rotary.cpp log.cpp
 track.cpp trackcollection.cpp trackplaylist.cpp wtracktableview.cpp wtracktablemodel.cpp wpromotracksmodel.cpp proxymodel.cpp xmlparse.cpp trackimporter.cpp parser.cpp parserpls.cpp parserm3u.cpp
 enginetemporal.cpp visual/visualbuffertemporal.cpp wavesummary.cpp bpmdetector.cpp bpmdetect.cpp bpmscheme.cpp  peakfinder.cpp wavesegmentation.cpp soundsourceproxy.cpp woverview.cpp enginebeatseek.cpp
 enginebufferscalereal.cpp powermate.cpp  hercules.cpp joystick.cpp mouse.cpp
 wvisualsimple.cpp wvisualwaveform.cpp visual/visualbackplane.cpp visual/texture.cpp visual/visualbox.cpp visual/visualbuffer.cpp visual/visualbuffersignal.cpp
 visual/visualbuffersignalhfc.cpp visual/visualbuffermarks.cpp visual/visualchannel.cpp visual/visualcontroller.cpp visual/visualdisplay.cpp visual/visualdisplaybuffer.cpp
 visual/light.cpp visual/material.cpp visual/picking.cpp visual/pickable.cpp visual/visualobject.cpp
 imginvert.cpp imgloader.cpp imgcolor.cpp wskincolor.cpp
 trackinfoobject.cpp soundsource.cpp
 midiledhandler.cpp
 sounddevice.cpp soundmanager.cpp sounddeviceportaudio.cpp
 dlgprefrecord.cpp recording/enginerecord.cpp recording/writeaudiofile.cpp
 enginevinylsoundemu.cpp enginesidechain.cpp wtracktablefilter.cpp
 wplaylistlistmodel.cpp libraryscanner.cpp libraryscannerdlg.cpp enginefilterbutterworth8.cpp enginexfader.cpp playerinfo.cpp wabstractcontrol.cpp
 enginebufferscaledummy.cpp """)

#Crap we don't use anymore:
#playerportaudio.cpp player.cpp playerproxy.cpp

#Compile platform specific hardware support
if platform == 'linux':
	sources += Split("""powermatelinux.cpp herculeslinux.cpp joysticklinux.cpp mouselinux.cpp """)
#elif platform == 'win32':
#	sources += Split("""powermatewin.cpp mousewin.cpp """)

#Compile platform specific MIDI support
if platform == 'linux':
	sources += Split("""midiobjectalsaseq.cpp """)  #ALSA Sequencer MIDI support for Linux
	env.Append(CXXFLAGS = '-D__ALSASEQMIDI__')
elif platform == 'win32':
	sources += Split("""midiobjectwin.cpp """)	  #Windows MIDI support
	env.Append(CXXFLAGS = '-D__WINMIDI__')
elif platform == 'osx':
	sources += Split("""midiobjectcoremidi.cpp """) #CoreMidi support for OS X
	env.Append(CXXFLAGS = '-D__COREMIDI__')


#Set up the library path on Windows:
if platform == 'win32':
	env.Append(CPPPATH='../../../mixxx-winlib') #If you add more directories, separate them with a semicolon (;)
	env.Append(LIBPATH='../../../mixxx-winlib')
	env.Append(LINKFLAGS = ['/nodefaultlib:libc.lib', '/nodefaultlib:libcd.lib', '/subsystem:windows', '/entry:mainCRTStartup'])

#Check for dependencies if we're not doing a clean...

if not env.GetOption('clean') and not SCons.Util.containsAny(os.sys.argv, ['-h', '--help']):
	conf = Configure(env, custom_tests = { 'CheckForPKGConfig' : CheckForPKGConfig, 'CheckForPKG' : CheckForPKG })
	
#TODO: Add all of the other configure checks as custom_tests properly.
	
# On Posix default SCons.LIBPREFIX = 'lib', on Windows default SCons.LIBPREFIX = ''

	if not conf.CheckLibWithHeader('portaudio', 'portaudio.h', 'C'):
		print 'Did not find libportaudio.a, portaudio.lib, or the PortAudio-v19 development header files - exiting!'
		Exit(1)

	if not conf.CheckLib(['mad','libmad']):
		print 'Did not find libmad.a, libmad.lib, or the libmad development header files - exiting!'
		Exit(1)

	if not conf.CheckLib(['id3tag','libid3tag-release']):
		print 'Did not find libid3tag.a, libid3tag.lib, or the libid3tag development header files - exiting!'
		Exit(1)

	#Check for Ogg and Vorbis
	CheckOggVorbis()

	#Check for OpenGL (it's messy to do it for all three platforms)
	CheckOpenGL()
	
	#Check if FFMPEG was enabled
	CheckFFMPEG(conf, sources)

	#Check for LADSPA header, if it was passed as a flag
	flags_ladspa = getFlags(env, 'ladspa', 0)
	if int(flags_ladspa):
		if not conf.CheckCHeader('ladspa.h'):
			print 'Did not find the LADSPA header file (ladspa.h) - exiting!'
			Exit(1)

	#Platform-specific checks for Linux and Win32...
	if platform == 'linux' or platform == 'win32':
		#Check for libsndfile
		#if not conf.CheckLibWithHeader(['sndfile', 'libsndfile'], 'sndfile.h', 'C'):
		if not conf.CheckLib(['sndfile', 'libsndfile']):
			print "Did not find libsndfile or it\'s development headers, exiting!"
			Exit(1)
		else:
			env.Append(CXXFLAGS = '-D__SNDFILE__')
			sources.append('soundsourcesndfile.cpp') ## TODO: Convert this to a SharedLibrary, so it can be installed without having to run scons twice after a clean
			# libsndfile = env.SharedLibrary(
			# "libsndfile",
			# source=["soundsourcesndfile.cpp", "trackinfoobject.cpp"])

	#Platform-specific checks for Linux...
	if platform == 'linux':
		#Check for g++ (yeah, SCONS is a bit dumb here)
		if os.system("which g++ > /dev/null"): #Checks for non-zero return code
			print "Did not find gcc/g++, exiting!"
			Exit(1)
		
		#Check for pkg-config
		if not conf.CheckForPKGConfig('0.15.0'):
			print 'pkg-config >= 0.15.0 not found.'
			Exit(1)
		
		#Check for QT >= 4.3	
		if not conf.CheckForPKG('QtCore', '4.3'):
			print 'QT >= 4.3 not found.'
			Exit(1)
		else:
			#Grabs the QT4 include paths
			env.ParseConfig('pkg-config QtCore --silence-errors --cflags --libs')
			env.ParseConfig('pkg-config Qt3Support --silence-errors --cflags') #QT3 support breaks the build
			env.ParseConfig('pkg-config QtGui --silence-errors --cflags --libs')
			env.ParseConfig('pkg-config QtXml --silence-errors --cflags --libs')
			env.ParseConfig('pkg-config QtOpenGL --silence-errors --cflags --libs')
			# Might be missing $QTDIR/include/Qt still...

		#Check for libasound (libasound2?) (needed for ALSA seq MIDI support)
		if not conf.CheckLib('asound') and not conf.CheckForPKG('alsa', '1.0.10'):
			print "Did not find libasound (aka. libasound2), exiting!"
			Exit(1)

		#Check for libdjconsole, if it was passed as a flag
		flags_djconsole = getFlags(env, 'djconsole', 0)
		flags_djconsole_legacy = getFlags(env, 'djconsole_legacy', 0)
		if int(flags_djconsole):
			if not conf.CheckLibWithHeader('djconsole', 'libdjconsole/djconsole.h', 'C++'):
				print "Did not find libdjconsole or it\'s development headers, exiting!"
				Exit(1)
			env.ParseConfig('pkg-config libdjconsole --silence-errors --cflags --libs')
			env.Append(CXXFLAGS = '-D__LIBDJCONSOLE__')
		elif int(flags_djconsole_legacy):
			# legacy support can not be enabled if libDJConsole support is enabled via djconsole=1
			env.Append(CXXFLAGS = '-D__DJCONSOLE_LEGACY__')

		#Another check for PortAudio-v19
		env.ParseConfig('pkg-config --cflags --libs portaudio-2.0')
		#If the above line looks like magic, it's because it really is. (Read about ParseConfig, it's nifty)

	#Platform-specific checks for OS X
	if platform == 'osx':
	#Check for libsndfile
		#if not conf.CheckLibWithHeader(['sndfile', 'libsndfile'], 'sndfile.h', 'C'):
		if not conf.CheckLib(['sndfile', 'libsndfile']):
			print "Did not find libsndfile or it\'s development headers, exiting!"
			Exit(1)
		else:
			env.Append(CXXFLAGS = '-D__SNDFILE__')
			sources.append('soundsourcesndfile.cpp') ## TODO: Convert this to a SharedLibrary, so it can be installed without having to run scons twice after a clean
			# libsndfile = env.SharedLibrary(
			# "libsndfile",
			# source=["soundsourcesndfile.cpp", "trackinfoobject.cpp"])

		#Check for QT4 (framework)
		"""if not os.path.exists('/Library/Frameworks/QtCore.framework/Versions/4/Headers/QtCore') or :
			print 'Did not find QT4 framework, going to look for libs instead (use qtdir flag)...'
		else:
			env.Append(LINKFLAGS = '-framework QtCore -framework QtOpenGL -framework Qt3Support -framework QtGui -framework QtXml -framework QtNetwork -framework QtSql')
			env.Append(CXXFLAGS = '-I/Library/Frameworks/QtCore.framework/Headers/')
			env.Append(CXXFLAGS = '-I/Library/Frameworks/QtOpenGL.framework/Headers/')
			env.Append(CXXFLAGS = '-I/Library/Frameworks/Qt3Support.framework/Headers/')
			env.Append(CXXFLAGS = '-I/Library/Frameworks/QtGui.framework/Headers/')
			env.Append(CXXFLAGS = '-I/Library/Frameworks/QtXml.framework/Headers/')
"""
		#Check for QT libs (rather than framework)
		if not os.path.exists(flags_qtdir):
			print 'Did not find QT4 path (qtdir: ' + flags_qtdir + ' not found), exiting!'
		else:
			env.Append(LIBPATH=flags_qtdir + '/lib/')
			env.Append(CPPPATH=flags_qtdir + '/include/')
			env.Append(LIBS = 'Qt3Support');
			env.Append(LIBS = 'QtXml');
			env.Append(LIBS = 'QtGui');
			env.Append(LIBS = 'QtCore');
			env.Append(LIBS = 'QtOpenGL');
			env.Append(LIBS = 'QtNetwork');
			env.Append(LIBS = 'QtSql');
			
			
		#Check for CoreMIDI
		if not conf.CheckCXXHeader('/System/Library/Frameworks/CoreMIDI.framework/Headers/CoreMIDI.h'):
			print 'Did not find CoreMIDI framework, exiting! (Please install it)'
			Exit(1)
		else:
			env.Append(LINKFLAGS = '-framework CoreMIDI -framework CoreFoundation -framework CoreAudio -framework Carbon -framework Quicktime -framework AudioToolbox -framework AudioUnit') #Have to add the rest of these frameworks somewhere...


	env = conf.Finish()


#Declare the flags for Mixxx's config/track listing files:
if platform == 'linux':
	env.Append(CXXFLAGS = '-D__UNIX__ -D__LINUX__ -DBPMSCHEME_FILE=\\".mixxxbpmscheme.xml\\" -DSETTINGS_FILE=\\".mixxx.cfg\\" -DTRACK_FILE=\\".mixxxtrack.xml\\"')
	env.Append(CXXFLAGS = '-DUNIX_SHARE_PATH=\\"' + ARGUMENTS.get('prefix', '/usr/local') + '/share/mixxx\\"')
elif platform == 'osx':
	env.Append(CXXFLAGS = '-D__MACX__ -DBPMSCHEME_FILE=\\".mixxxbpmscheme.xml\\" -DSETTINGS_FILE=\\".mixxx.cfg\\" -DTRACK_FILE=\\".mixxxtrack.xml\\"')
elif platform == 'win32':
	env.Append(CXXFLAGS = '-D__WIN32__ -DBPMSCHEME_FILE=\\"mixxxbpmschemes.xml\\" -DSETTINGS_FILE=\\"mixxx.cfg\\" -DTRACK_FILE=\\"mixxxtrack.xml\\"')

#... and yes, we need to double-escape those quotes
env.Append(CXXFLAGS = '-D__PORTAUDIO__'); #Turn on PortAudio support in Mixxx
env.Append(CPPPATH = ['.', '../', '../../']) #Fun fun fun with paths


if platform == 'linux':
	env.Append(LIBS = 'Qt3Support');
	env.Append(LIBS = 'QtXml');
	env.Append(LIBS = 'QtGui');
	env.Append(LIBS = 'QtCore');
	env.Append(LIBS = 'QtOpenGL');

if platform == 'win32':
	env.Append(LIBS = 'Qt3Support4'); #Win32 needs this instead of 'Qt3Support'
	env.Append(LIBS = 'QtXml4');
	env.Append(LIBS = 'QtGui4');
	env.Append(LIBS = 'QtCore4');
	env.Append(LIBS = 'QtOpenGL4');
	env.Append(LIBS = 'WinMM'); #Needed for Midi stuff
	env.Append(LIBS = 'ogg_static')
	env.Append(LIBS = 'vorbis_static')
	env.Append(LIBS = 'vorbisfile_static')
	env.Append(LIBS = 'imm32')
	env.Append(LIBS = 'wsock32')
	env.Append(LIBS = 'delayimp')
	env.Append(LIBS = 'winspool')
	env.Append(LIBS = 'shell32')

env.Append(CXXFLAGS = '-DQT3_SUPPORT -DQT3_SUPPORT_WARNINGS -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_TABLET_SUPPORT') #Stolen from Mixxx's build output

# Manually add the include paths for win32 and OS X (we use pkg-config on Linux)
if not platform == 'linux':
	env.Append(CXXFLAGS = '-I$QTDIR/include/Qt3Support -I$QTDIR/include/QtCore -I$QTDIR/include/QtGui -I$QTDIR/include/QtXml -I$QTDIR/include/QtOpenGL -I$QTDIR/include/Qt -I"$VCINSTALLDIR/include/atl"')

if not platform == 'win32':
	env.Append(CCFLAGS = Split(""" -pipe -Wall -W -g -D_REENTRANT """)) # omghax
	env.Append(LINKFLAGS = Split(""" -pipe -Wall -W -g"""))
if platform == 'win32':
	env.Append(CXXFLAGS = '-DWIN32 -D__WIN__ -DUNICODE -D_WINDOWS') #for soundtouch
	env.Append(CCFLAGS  = '-DWIN32 -D__WIN__ -DUNICODE -D_WINDOWS') #for soundtouch

#Uic these guys (they're moc'd automatically after this) - Generates the code for the QT UI forms
env.Uic4('dlgpreferencesdlg.ui')
env.Uic4('dlgprefsounddlg.ui')
env.Uic4('dlgprefmididlg.ui')
env.Uic4('dlgprefplaylistdlg.ui')
env.Uic4('dlgprefcontrolsdlg.ui')
env.Uic4('dlgprefeqdlg.ui')
env.Uic4('dlgprefcrossfaderdlg.ui')
env.Uic4('dlgprefbpmdlg.ui')
env.Uic4('dlgbpmschemedlg.ui')
env.Uic4('dlgbpmtapdlg.ui')
env.Uic4('dlgprefvinyldlg.ui')
env.Uic4('dlgprefrecorddlg.ui')
env.Uic4('dlgaboutdlg.ui')

#Add the QRC file which compiles in some extra resources (prefs icons, etc.)
env.Qrc('mixxx.qrc')
sources += Split(""" qrc_mixxx.cc """)

if platform == 'win32':
	env.RES('mixxx.rc')
	sources += Split(""" mixxx.res """)

#Tell SCons to build libraries that are bundled with Mixxx
#===================================================

#SoundTouch
env.Append(CPPPATH=['../../lib/soundtouch']) #Needed two ../../'s because we're compiling from "src/.obj"
sources += Split("""enginebufferscalest.cpp ../../lib/soundtouch/SoundTouch.cpp ../../lib/soundtouch/TDStretch.cpp ../../lib/soundtouch/RateTransposer.cpp ../../lib/soundtouch/AAFilter.cpp ../../lib/soundtouch/FIFOSampleBuffer.cpp ../../lib/soundtouch/FIRFilter.cpp """)
if platform == 'win32':
	sources += Split("""../../lib/soundtouch/cpu_detect_x86_win.cpp ../../lib/soundtouch/mmx_win.cpp ../../lib/soundtouch/sse_win.cpp ../../lib/soundtouch/3dnow_win.cpp""")
else:
	sources += Split("""../../lib/soundtouch/cpu_detect_x86_gcc.cpp""")

#RubberBand for time stretching

#env.Append(CPPPATH=['../../lib/rubberband/src']) #Needed two ../../'s because we're compiling from "src/.obj"
#env.Append(CPPPATH=['../../lib/rubberband/rubberband']) #Needed two ../../'s because we're compiling from "src/.obj"
#env.Append(CXXFLAGS=['-DFFTW_DOUBLE_ONLY'])
#sources += Split("""enginebufferscalerubberband.cpp
#					../../lib/rubberband/src/AudioCurve.cpp ../../lib/rubberband/src/ConstantAudioCurve.cpp
#					../../lib/rubberband/src/FFT.cpp ../../lib/rubberband/src/PercussiveAudioCurve.cpp
#					../../lib/rubberband/src/HighFrequencyAudioCurve.cpp ../../lib/rubberband/src/Resampler.cpp
#					../../lib/rubberband/src/RubberBandStretcher.cpp ../../lib/rubberband/src/SpectralDifferenceAudioCurve.cpp
#					../../lib/rubberband/src/StretchCalculator.cpp ../../lib/rubberband/src/StretcherChannelData.cpp
#					../../lib/rubberband/src/StretcherImpl.cpp ../../lib/rubberband/src/StretcherProcess.cpp
#					../../lib/rubberband/src/sysutils.cpp ../../lib/rubberband/src/Thread.cpp""")

#KissFFT
env.Append(CPPPATH=['../../lib/kissfft'])
sources += Split("""../../lib/kissfft/kiss_fft.c""")

#libsamplerate
env.Append(CPPPATH='../../lib/libsamplerate')
sources += Split("""enginebufferscalesrc.cpp ../../lib/libsamplerate/samplerate.c ../../lib/libsamplerate/src_linear.c ../../lib/libsamplerate/src_sinc.c ../../lib/libsamplerate/src_zoh.c""")

#fidlib (for EQs)
env.Append(CPPPATH='../../lib/fidlib-0.9.9/')
sources += Split("""../../lib/fidlib-0.9.9/fidlib.c """)
#Platform-specific compile/link flags needed for fidlib
if platform == 'linux' or platform == 'osx':
	env.Append(CCFLAGS = '-DT_LINUX')
elif platform == 'win32':
	env.Append(CCFLAGS = '-DT_MSVC')
	env.Append(CXXFLAGS = '-DT_MSVC')
	env.Append(LINKFLAGS = ['/nodefaultlib:LIBCMT.lib', '/nodefaultlib:LIBCMTD.lib'])


#Parse command-line build flags
build_flags = ""

print "\nFeatures Summary:\n================"

#Python/lua scripting
#flags_script = ARGUMENTS.get('script', 0) #Default value is 0
#if int(flags_script):
#	env.Append(CXXFLAGS = '-D__SCRIPT__ -D__LUA__ -D__PYTHON__')
#	sources += Split("""script/*.cpp script/lua/*.cpp script/python/*.cpp""")
#	env.ParseConfig('python-config --include --ldflags')
#	env.Append(LIBS = 'lua')
#	env.Append(LIBS = 'lualib')
#	env.Append(LIBS = 'tulua')
#	print "Python and Lua scripting... enabled"
#else:
#	print "Python and Lua scripting... disabled"
 #TODO: FINISH THIS!

#Hercules support through libdjconsole on Linux
#(handled somewhere else above this in the file...
# just printing the summary here)
flags_djconsole = getFlags(env, 'djconsole', 0)
if int(flags_djconsole) == 0:
	print "libdjconsole support... disabled"
else:
	print "libdjconsole support... enabled"
	build_flags += 'djconsole '

#High quality EQs
flags_hifieq = getFlags(env, 'hifieq', 1)
if int(flags_hifieq) == 0:
	env.Append(CXXFLAGS = '-D__LOFI__ -D__NO_INTTYPES__') #Enables old crappy EQs
	print "High quality EQs... disabled"
else:
	print "High quality EQs... enabled"
	build_flags += 'hifieq '

#Experimental IPOD support
flags_ipod = getFlags(env, 'ipod', 0)
if int(flags_ipod):
	env.Append(CXXFLAGS = '-D__IPOD__')
	# env.Append(LIBS = 'libgpod-1.0')
	# env.Append(LIBS = 'glib-2.0')
	env.ParseConfig('pkg-config libgpod-1.0 --silence-errors --cflags --libs')
	env.ParseConfig('pkg-config glib-2.0 --silence-errors --cflags --libs')
	sources += Split("""wipodtracksmodel.cpp """) #IPOD
	print "iPod support... enabled"
	build_flags += 'ipod '
else:
	print "iPod support... disabled"

#Experimental Shoutcast
flags_shoutcast = getFlags(env, 'shoutcast', 0)
if int(flags_shoutcast):
#TODO: check for libshout
	env.Append(LIBS = 'shout');
	env.Append(LIBS = 'vorbisenc');
	env.Append(CXXFLAGS = '-D__SHOUTCAST__')
	sources += Split(""" dlgprefshoutcast.cpp engineshoutcast.cpp encodervorbis.cpp """ )
	env.Uic4('dlgprefshoutcastdlg.ui')
	print "Shoutcast support... enabled"
	build_flags += 'shoutcast '
else:
	print "Shoutcast support... disabled"

#LADSPA
flags_ladspa = getFlags(env, 'ladspa', 0)
if int(flags_ladspa):
	env.Append(CXXFLAGS = '-D__LADSPA__')
	sources += Split("""engineladspa.cpp ladspaloader.cpp ladspalibrary.cpp ladspaplugin.cpp ladspainstance.cpp ladspacontrol.cpp ladspainstancestereo.cpp ladspainstancemono.cpp ladspaview.cpp ladspapreset.cpp ladspapresetmanager.cpp ladspapresetknob.cpp ladspapresetinstance.cpp dlgladspa.cpp ladspapresetslot.cpp""")
	print "LADSPA support... enabled"
	build_flags += 'ladspa '
else:
	print "LADSPA support... disabled"

#Vinyl Control
flags_vinylcontrol = getFlags(env, 'vinylcontrol', 1)
if int(flags_vinylcontrol):
	env.Append(CXXFLAGS = '-D__VINYLCONTROL__')
	sources += Split(""" vinylcontrol.cpp vinylcontrolproxy.cpp vinylcontrolscratchlib.cpp vinylcontrolxwax.cpp dlgprefvinyl.cpp enginevinylcontrol.cpp """)
	env.Append(CPPPATH='../../lib/xwax')
	if platform == 'win32':
		sources += Split("""../../lib/xwax/timecoder_win32.c """)
	else:
		sources += Split("""../../lib/xwax/timecoder.c """)
	env.Append(CPPPATH='../../lib/scratchlib')
	sources += Split("""../../lib/scratchlib/DAnalyse.cpp """)
	print "Vinyl Control... enabled"
	build_flags += 'vinylcontrol '
else:
	print "Vinyl Control... disabled"

flags_msvcdebug = getFlags(env, 'msvcdebug', 1)
if int(flags_msvcdebug) and platform == 'win32':
	env.Append(LINKFLAGS = '/DEBUG')
	env.Append(CXXFLAGS = '/ZI')
	print "MSVC Debugging... enabled"
	build_flags += 'msvcdebug '
else:
	print "MSVC Debugging... disabled"

flags_script = getFlags(env, 'script', 0)
if int(flags_script):
	if platform == 'win32':
		env.Append(LIBS = 'QtScript4')
	else:
		env.Append(LIBS = 'QtScript')
	print "SuperCoolAwesomeScript (name contest pending)... enabled"
	build_flags += 'script '
	sources += Split("""script/scriptengine.cpp script/scriptcontrolqueue.cpp
			script/scriptstudio.cpp script/scriptrecorder.cpp
			script/playinterface.cpp script/macro.cpp
			script/scriptcontrolevent.cpp script/trackcontrolevent.cpp
			script/numbercontrolevent.cpp script/numberrecorder.cpp
			script/macrolist.cpp script/trackrecorder.cpp
			script/sdatetime.cpp script/signalrecorder.cpp
			script/macrolistitem.cpp script/qtscriptinterface.cpp""")
	env.Append(CXXFLAGS = '-I$QTDIR/include/QtScript')
	env.Append(CXXFLAGS = '-D__SCRIPT__')
	
	env.Uic4('script/scriptstudio.ui')
else:
	flags_script = 0
	print "SuperCoolAwesomeScript (name contest pending)... disabled"

#Optimization
if platform == 'win32':
	flags_optimize = getFlags(env, 'optimize', 0)   #Default to off on win32
else:
	flags_optimize = getFlags(env, 'optimize', 1)   #Default to on for Linux/OS X
if int(flags_optimize):
	if platform == 'win32':
		if int(flags_msvcdebug):
			print "Optimizations... DISABLED DUE TO DEBUG"
		else:
			print "Optimizations... enabled"
			env.Append(CXXFLAGS = '/O2 /GL')
			env.Append(LINKFLAGS = '/LTCG:STATUS')
	else:
		print "Optimizations... enabled"
		build_flags += 'optimize=' + str(flags_optimize) + ' '
		if flags_optimize=='1':
			env.Append(CXXFLAGS = '-O3')
		elif flags_optimize=='2':
			print "  P4 MMX/SSE optimizations enabled."
			env.Append(CXXFLAGS = '-O3 -march=pentium4 -mmmx -msse2 -mfpmath=sse -fomit-frame-pointer -ffast-math -funroll-loops')
		elif flags_optimize=='3':
			print "  Intel Core Solo/Duo optimizations enabled."
			env.Append(CXXFLAGS = '-O3 -march=prescott -mmmx -msse3 -mfpmath=sse -fomit-frame-pointer -ffast-math -funroll-loops')
		elif flags_optimize=='4':
			print "  Intel Core 2 optimizations enabled."
			env.Append(CXXFLAGS = '-O3 -march=nocona -mmmx -msse3 -mfpmath=sse -fomit-frame-pointer -ffast-math -funroll-loops')
else:
	print "Optimizations... disabled"




# Profiling and Optimization
if not platform == 'win32':
	flags_gprof = getFlags(env, 'gprof', 0)
	if int(flags_gprof):
		env.Append(CCFLAGS = '-pg')
		env.Append(LINKFLAGS = '-pg')
		print "gprof profiling support... enabled"
		build_flags += 'gprof '
	else:
		print "gprof profiling support... disabled"
	flags_tuned = getFlags(env, 'tuned', 0)
	if int(flags_tuned):
		ccv = env['CCVERSION'].split('.')
		if int(ccv[0]) >= 4 and int(ccv[1]) >= 2:
			env.Append(CCFLAGS = '-march=native')
			env.Append(LINKFLAGS = '-march=native')
			print "Optimizing for this CPU... yes"
			build_flags += 'tuned '
		else:
			print "Optimizing for this CPU... no (requires gcc >= 4.2.0)"
	else:
		print "Optimizing for this CPU... no"

#Visual Studio 2005 hacks (MSVS Express Edition users shouldn't enable this)
flags_msvshacks = getFlags(env, 'msvshacks', 0)
if int(flags_msvshacks):
	env.Append(CXXFLAGS = '-D__MSVS2005__')
	print "MSVS 2005 hacks... enabled"
	build_flags += 'msvshacks '
else:
	print "MSVS 2005 hacks... disabled"

#force 32-bit compile on GCC
flags_force32 = getFlags(env, 'force32', 0)
if int(flags_force32):
	env.Append(CCFLAGS = '-m32')
	env.Append(CXXFLAGS = '-m32')
	print "Force 32-bit compile... enabled"
else:
	print "Force 32-bit compile... disabled"


#Case Metrics
if platform == 'win32' or platform == 'linux':
	flags_cmetrics = getFlags(env, 'cmetrics', 1)
else:
	flags_cmetrics = getFlags(env, 'cmetrics', 0) # Off on OS X for now...
if int(flags_cmetrics):
	env.Append(CXXFLAGS = '-D__C_METRICS__')
	if platform == 'win32':
		env.Append(LIBS = 'cmetrics')
	else:
		client = 'MIXXX'
		server = 'casemetrics.net' #NOTE: Permission to use this server is granted only to mixxx, any other use must obtain prior permission
		Export('env platform client server flags_force32')
		env.Append(CPPPATH='../../lib/cmetrics')
		sources += SConscript('../../lib/cmetrics/SConscript')
	print "Case Metrics profiling... enabled"
	build_flags += 'cmetrics '
else:
	print "Case Metrics profiling... disabled"

### Put flags info into a file
f = open("../.mixxx_flags.svn","w")
try:
	f.write('#define BUILD_FLAGS "' + build_flags + '"\n')
finally:
	f.close()
	
# Print the build flags (useful if the flags have been cached, ie. if you just run "scons"
# and want to see the flags that you used last time)
print "================"
print "Building with flags: " + build_flags
print "================\n"

#Save the options to cache
opts.Save(cachefile, env)



#Tell SCons to build Mixxx
#=========================
if platform == 'win32':
	mixxx_bin = env.Program('mixxx', sources, LINKCOM  = [env['LINKCOM'], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;1'])
else:
	mixxx_bin = env.Program('mixxx', sources)

#Set up the MSVC target to build a Visual Studio project/solution file
if 'msvc' in COMMAND_LINE_TARGETS:
	includes = glob.glob('src/*.h')
	includes += glob.glob('src/visual/*.h')
	#Make the project file aware of any command-line arguments that were passed...
	cmdargs = ""
	for k in SCons.Script.ARGUMENTS:
		cmdargs += " " + k + "=" + SCons.Script.ARGUMENTS[k]
	env.Append(MSVSSCONSFLAGS = cmdargs)
	#env.Append(MSVSSCONSFLAGS = ' qtdir=' + flags_qtdir)

	# This is the right way to do it but scons is stupid and doesn't copy flags in... Adam
	# Set up environment for debug target
	# TODO Handle lib versions ie /MDd /Md etc...
	#debugenv = env.Clone()
	#debugenv.Prepend(LINKFLAGS = ['/DEBUG','/PDB:dist/mixxx.pdb']) # Generate MS VC Program Debug Database
	#debugenv.Append(CXXFLAGS = '/ZI')

	msvc = env.MSVSProject(target = 'mixxx' + env['MSVSPROJECTSUFFIX'], srcs = flatten(sources), incs = flatten(includes), variant = 'Debug', runfile = '../dist/mixxx')

	# Reenable this once bug in scons is fixed...
	#msvc = env.MSVSProject(target = 'mixxx' + env['MSVSPROJECTSUFFIX'], srcs = flatten(sources), incs = flatten(includes), variant = 'Release', runfile = '../dist/mixxx')

	env.Alias('msvc', msvc)

#Set up the install target
#=========================
"""
flags_prefix = ARGUMENTS.get('prefix', '/usr/local')
if not os.path.exists(flags_prefix):
	print "Error: Prefix path does not exist!"
	Exit(1)
else:
	unix_share_path = flags_prefix + "/share"
	unix_bin_path   = flags_prefix + "/bin"
"""

#Mixxx binary
binary_files = mixxx_bin;

#Skins
skin_files = glob.glob('../skins/*')

#MIDI mappings
midimappings_files = glob.glob('../midi/*')

#Keyboard mapping(s)
keyboardmappings_files = glob.glob('../keyboard/*')

#Promo tracks
promotracks_files = glob.glob('../../promo/*')

#Documentation
docs_files = glob.glob('../../LICENSE')
docs_files += glob.glob('../../README')
docs_files += glob.glob('../../Mixxx-Manual.pdf')

#.desktop file for KDE/GNOME menu
dotdesktop_files = glob.glob('../mixxx.desktop')

#Icon file for menu entry
icon_files = glob.glob('../mixxx-icon.png')

#Images for preferences dialog
image_files = glob.glob('../images/preferences/*')  # These are compiled in to the "mixxx" binary through mixxx.qrc

#Windows DLLs
dll_files = glob.glob('../../../mixxx-winlib/*.dll') # TODO: Use reference to SharedLibrary for libsndfile and others, glob only gets all files on 2+ builds after a clean.
# dll_files = libsndfile
dll_files += Split("""$QTDIR/lib/Qt3Support4.dll $QTDIR/lib/QtCore4.dll $QTDIR/lib/QtGui4.dll $QTDIR/lib/QtNetwork4.dll $QTDIR/lib/QtOpenGL4.dll $QTDIR/lib/QtSql4.dll $QTDIR/lib/QtXml4.dll """)

if int(flags_script):
	dll_files += Split("""$QTDIR/lib/QtScript4.dll""")

if platform == 'linux':
	flags_prefix = ARGUMENTS.get('prefix', '/usr/local')
	if not os.path.exists(flags_prefix):
		print "Error: Prefix path does not exist!"
		Exit(1)
	else:
		#install_root is used in Debian/Ubuntu packaging (check the debian/rules file in the Ubuntu package)
		#Basically, the flags_prefix is compiled into strings in Mixxx, whereas the install_root is not. When you're
		#building a Debian package, pbuilder wants to install Mixxx to a temporary directory, but you still need
		#the compiled-in strings using /usr as the prefix. That's why we have install_root and flags_prefix.
		install_root = ARGUMENTS.get('install_root', flags_prefix)
		print "Install root: " + install_root
		if install_root != flags_prefix:
			unix_share_path = install_root + "/share"
			unix_bin_path   = install_root + "/bin"			
		else:
			unix_share_path = flags_prefix + "/share"
			unix_bin_path   = flags_prefix + "/bin"

		binary = env.Install(unix_bin_path, binary_files)
		skins = env.Install(unix_share_path + "/mixxx/skins", skin_files)
		midimappings = env.Install(unix_share_path + "/mixxx/midi", midimappings_files)
		keyboardmappings = env.Install(unix_share_path + "/mixxx/keyboard", keyboardmappings_files)
		dotdesktop = env.Install(unix_share_path + "/applications", dotdesktop_files)
		docs = env.Install(unix_share_path + "/doc/mixxx", docs_files)
		icon = env.Install(unix_share_path + "/pixmaps", icon_files)
		promotracks = env.Install(unix_share_path + "/mixxx/promo", promotracks_files)

		#Makes each of those Install builders get fired off when you run "scons install" :)
		env.Alias('install', binary)
		env.Alias('install', skins)
		env.Alias('install', midimappings)
		env.Alias('install', keyboardmappings)
		env.Alias('install', docs)
		env.Alias('install', dotdesktop)
		env.Alias('install', icon)
		env.Alias('install', promotracks)
		
		#Delete the old Mixxx installation (because SCONS won't overwrite it)
		#if 'install' in COMMAND_LINE_TARGETS:
			#os.system('scons -c install')
			#Delete(unix_share_path + "/mixxx/skins")
			#print "Copying skins..."
			#env.Command(unix_share_path + "/mixxx/skins", skin_files, Copy("$TARGET", "$SOURCE"), source_scanner = DirScanner)
			#Copy(unix_share_path + "/.ixxx/skins", skin_files)
			#Delete(unix_bin_path + "mixxx")
			
			#Delete(unix_share_path + "/mixxx/midi")
			#Delete(unix_share_path + "/mixxx/keyboard")

#Build the Mixxx.app directory
if platform == 'osx':

	#Files needed to create the OS X package
	osx_plist_file = glob.glob('../osx/Info.plist')
	osx_pkginfo_file = glob.glob('../osx/PkgInfo')
	osx_icns_file = glob.glob('../osx/application.icns')
	
	osx_dist_path = "../../Mixxx.app"
	osx_share_path = osx_dist_path
	binary = env.Install(osx_dist_path + "/Contents/MacOS", binary_files)
	skins = env.Install(osx_dist_path + "/skins", skin_files)
	midimappings = env.Install(osx_dist_path + "/midi", midimappings_files)
	keyboardmappings = env.Install(osx_dist_path + "/keyboard", keyboardmappings_files)
	docs = env.Install(osx_dist_path + "/doc", docs_files)
	promotracks = env.Install(osx_dist_path + "/promo", promotracks_files)
	osx_plist = env.Install(osx_dist_path + "/Contents", osx_plist_file)
	osx_pkginfo = env.Install(osx_dist_path + "/Contents", osx_pkginfo_file)
	osx_icns = env.Install(osx_dist_path + "/Contents/Resources", osx_icns_file)

	
	#Makes each of those Install builders get fired off when you run "scons install" :)
	env.Alias('install', binary)
	env.Alias('install', skins)
	env.Alias('install', midimappings)
	env.Alias('install', keyboardmappings)
	env.Alias('install', promotracks)
	env.Alias('install', osx_plist)
	env.Alias('install', osx_pkginfo)
	env.Alias('install', osx_icns)

		
if platform == 'win32':
	skins = env.Install("../../dist/skins", skin_files)
	midimappings = env.Install("../../dist/midi", midimappings_files)
	keyboardmappings = env.Install("../../dist/keyboard", keyboardmappings_files)
	docs = env.Install("../../dist/doc/", docs_files)
	promotracks = env.Install("../../dist/promo/", promotracks_files)
	#icon = env.Install("../../dist", icon_files)
	dlls = env.Install("../../dist/", dll_files)
	binary = env.Install("../../dist/", binary_files)

	#Always trigger these install builders when compiling on Windows
	env.Alias('mixxx', skins)
	env.Alias('mixxx', midimappings)
	env.Alias('mixxx', keyboardmappings)
	env.Alias('mixxx', promotracks)
	env.Alias('mixxx', docs)
	env.Alias('mixxx', dlls)
	#env.Alias('mixxx', icon)
	env.Alias('mixxx', binary)



def BuildRelease(target, source, env):
	print
	print "==== Mixxx Post-Build Checks ===="
	print
	print "You have built version ",
	os.system('grep -m 1 VERSION src/defs.h | cut -d \' \' -f 3')
	print
	print "Binary has size ",
	os.system('ls -lh dist/mixxx.exe | cut -d \' \' -f 5')
	print
	print "Installer file ",
	os.system('grep OutFile Mixxx.nsi | cut -d \' \' -f 2')
	print
	print "Top line of README, check version:"
	os.system('head -n 1 README')
	print
	print "Top 2 lines of LICENSE, check version and copyright dates:"
	os.system('head -n 2 LICENSE')
	print
	print "More checks here soon... :)"
	print

	if (raw_input("Go ahead and build installer (yes/[no])? ") == "yes"):
		print "Now building installer..."
		os.system('"c:/Program Files/NSIS/makensis.exe" Mixxx.nsi')
	else:
		print "Aborted building installer"

# Do release things
versionbld = Builder(action = BuildRelease, suffix = '.foo', src_suffix = '.bar')
env.Append(BUILDERS = {'BuildRelease' : versionbld})

if 'makerelease' in COMMAND_LINE_TARGETS:
	makerelease = env.BuildRelease('', binary_files)
	env.Alias('makerelease', makerelease)
	
#Build the Ubuntu package
def BuildUbuntuPackage(target, source, env):
	print
	print "==== Mixxx Post-Build Checks ===="
	print
	print "You have built version ",
	p = os.popen('grep -m 1 VERSION src/defs.h | cut -d \' \' -f 3 | tr -d \'\"\' | tr -d \'\n\'')
	version = p.readline()
	p.close()
	print
	print
	print "Top line of README, check version:"
	os.system('head -n 1 README')
	print
	print "Top 2 lines of LICENSE, check version and copyright dates:"
	os.system('head -n 2 LICENSE')
	print
	print "Top line of debian/ubuntu changelog, check version:"
	os.system('head -n 1 src/debian/changelog')
	print

	if ("yes" == "yes"):
		print "Now building DEB package..."
		
		mixxx_dir = 'mixxx-' + version
		mixxx_tarball = 'mixxx_' + version + '.orig.tar.gz' #The underscore is super important here
															#to make the deb package work
		
		if not os.path.exists('ubuntu'):
			os.mkdir('ubuntu')
		print "Exporting source tree from HEAD"
		
		os.system('svn export --force -rHEAD . ubuntu/mixxx-' + version)
		
		print "Copying promo tracks dir"
		os.system('cp -r promo ubuntu/mixxx-' + version)
		
		os.chdir('ubuntu')
		
		#Temporarily move the debian directory out of the source directory
		#because it can't be included in the source tarball (which we create next).
		#print "Moving debian directory"
		#os.system('rm -f debian')
		#os.system('mv mixxx-' + version + '/src/debian .')
		
		print "Tarring source directory..."
		os.system("rm -f mixxx_" + version + ".orig.tar.gz") #Remove old tarball
		os.system('tar --exclude=debian --exclude=debian/* -cvzf  mixxx_' + version + '.orig.tar.gz ' + mixxx_dir)
		
		#Move the debian directory into the right spot.
		#os.system('mv debian mixxx-' + version)
		os.system('rm -rf ' + mixxx_dir + '/debian')
		os.system('mv ' + mixxx_dir + '/src/debian ' + mixxx_dir)
		
		#Run pbuilder
		os.chdir(mixxx_dir)
		os.system('pdebuild')
		
		#/var/cache/pbuilder/result
		print
		print "Signing the .deb changes file..."
		os.system('sudo debsign /var/cache/pbuilder/result/*.changes')
		
		print "Done! Package and tarballs are in /var/cache/pbuilder/result"
		
	else:
		print "Aborted building installer"

#Build the Ubuntu package if "makeubuntu" was passed as an argument
versiondebbld = Builder(action = BuildUbuntuPackage, suffix = '.foo', src_suffix = '.bar')
env.Append(BUILDERS = {'BuildUbuntuPackage' : versiondebbld})

if 'makeubuntu' in COMMAND_LINE_TARGETS:
	makeubuntu = env.BuildUbuntuPackage('', binary_files)
	env.Alias('makeubuntu', makeubuntu)
