import os

def printOptions(debugMode, engine, useDouble):
	print 'Building OPAL with the following options: '
	if debugMode == True:
		print 'mode = debug'
	else:
		print 'mode = release'
	print 'engine = ' + engine
	if useDouble == True:
		print 'Use double precision = true'
	else:
		print 'Use double precision = false'

def setupBaseEnvironment():
	env = Environment(
		ENV = os.environ, 
		options = opts)
	return env

def setupGenericUNIXEnvironment(env):
	env = Environment(
		ENV = os.environ, 
		options = opts,
		tools = ['gcc', 'gnulink', 'g++'])

	if env['debug'] == True:
		env.Append(CXXFLAGS = ['-O0'])
	else:
		env.Append(CXXFLAGS = ['-O2'])
	return env

def setupIrixEnvironment(env):
	env = Environment(
		ENV = os.environ, 
		options = opts)
		#tools = ['gcc', 'gnulink', 'g++'])

	env.Append(
		CXXFLAGS = ['-ansi', '-LANG:std', '-n32'])
		#CXXFLAGS = ['-ansi', '-LANG:std', '-mabi=n32'])
		#CPPPATH = string.split(os.environ['CPLUS_INCLUDE_PATH'], ':'), 
		#LIBPATH = string.split(os.environ['LIBRARY_PATH'], ':'))
	if env['debug'] == True:
		env.Append(CXXFLAGS = ['-O0'])
	else:
		env.Append(CXXFLAGS = ['-O2'])
	return env

def setupWin32Environment(env):
	env = Environment(
		ENV = os.environ, 
		options = opts)

	env.Append(
               CPPDEFINES = ['/DWIN32', '/D_WIN32', '/W3', '/DOPAL_DLL_EXPORTING'], 
               CPPPATH = [], 
               LIBPATH = [])
	if env['debug'] == True:
		env.Append(CXXFLAGS = ['/MDd', '/Od'], 
			CPPDEFINES = ['/D_DEBUG'])
	else:
		env.Append(CXXFLAGS = ['/MD', '/O2', '/Og', '/Ob2', '/Oi', '/Ot'], 
			CPPDEFINES = ['/DNDEBUG'])
	return env

# Make at least one target (physics engine) required.
Default(None)

# Setup options
opts = Options()
opts.AddOptions(
	BoolOption('debug', 'Build in debug mode', False),
	BoolOption('double', 'Build with reals set to double instead of float', False), 
	PathOption('extra_include_path', 'Additional include directory', '.'), 
	PathOption('extra_lib_path', 'Additional lib directory', '.'))
opts.Add('prefix', 'Install directory', '.')
physicsEngine = ''

if 'ODE' in COMMAND_LINE_TARGETS:
	physicsEngine = 'ODE'

# Setup the base environment
env = setupBaseEnvironment()

# Add platform-specific stuff
if env['PLATFORM'] == 'win32':
	env = setupWin32Environment(env)
elif env['PLATFORM'] == 'irix':
	env = setupIrixEnvironment(env)
else:
	env = setupGenericUNIXEnvironment(env)

env.Append(CPPPATH = env['extra_include_path'], 
	LIBPATH = env['extra_lib_path'])

# Setup the buildDir where intermediate and library files will be placed
buildDir = ''
if env['debug'] == True:
	#buildDir = 'build/debug'
	buildDir = 'build/' + env['PLATFORM'] + '/debug'
else:
	buildDir = 'build/' + env['PLATFORM'] + '/release'

# Add double floating point precision support if desired.
if env['double'] == True:
	env.Append(CPPDEFINES = ['OPAL_USE_DOUBLE'])

if len(COMMAND_LINE_TARGETS) != 0:
	printOptions(env['debug'], physicsEngine, env['double'])
#else:
#	printTargetsMessage()

# Generate command line help text
env.Help(opts.GenerateHelpText(env) + 
	'\nSpecify one or more of the following targets (Note: a physics engine target is required): ' + 
	'\n-> ODE: build with ODE support' + 
	'\n-> install: install libraries and header files to <prefix>' + 
	'\nExample 1 (build debug library with ODE support): scons ODE debug=true' + 
	'\nExample 2 (build with ODE support and install): scons ODE install prefix=/path/to/install/dir' + 
	'\nExample 3 (build with ODE support and specify header/lib paths): scons ODE extra_include_path=/path/to/include extra_lib_path=/path/to/lib' + 
	'\n')

# Export the environment we just created for the SConscripts
Export('env')

# Call the base OPAL src SConscript
objects = SConscript(dirs = ['src'], build_dir = buildDir, duplicate = 0)

# Add in XML-related objects
objects += SConscript(dirs = ['src/external/tinyxml'], build_dir = buildDir + '/external/tinyxml', duplicate = 0)

opalLib = ''
includeDir = 'src/include'

# Setup ODE version
if physicsEngine == 'ODE':
	# Add ODE objects
	objects += SConscript(dirs = ['src/ODE'], build_dir = buildDir + '/ODE', duplicate = 0)

	if env['debug'] == True:
		env.Append(LIBS = ['ode'])
		opalLib = env.SharedLibrary(buildDir + '/opal-ode_d', objects)
	else:
		env.Append(LIBS = ['ode'])
		opalLib = env.SharedLibrary(buildDir + '/opal-ode', objects)

	env.Alias('ODE', opalLib)

# Add more physics engines here...

if 'install' in COMMAND_LINE_TARGETS and physicsEngine == '':
	print 'Cannot install.  You must specify a physics engine target.'
	Exit()

# Add lib installation to 'install' alias
env.Alias('install', env.Install(os.path.join(env['prefix'], 'lib'), opalLib))
