################ needed imports
import os
import sys

################ global config values
version = '0.1.0'
if ARGUMENTS.get('version', 0):
	version = ARGUMENTS.get('version', 0)

################ base paths (needed for Win32 OS)
sdlbase = 'd:\\sdl-devel\\SDL'
sdlimagebase = 'd:\\sdl-devel\\SDL_image'
sdlnetbase = 'd:\\sdl-devel\\SDL_net'
sdlmixerbase = 'd:\\sdl-devel\\SDL_mixer'
fftw3base = 'd:\\fftw3'
glbase = 'd:\\Dev-Cpp\\include\\gl'
# glbase = '/Microsoft Visual Studio/vc98/Include/gl/'

################ change base of dirs (unix OS)
installbindir = '/usr/local/bin'
installdatadir = '/usr/local/share/dangerdeep'
if ARGUMENTS.get('installbindir', 0):
	installbindir = ARGUMENTS.get('installbindir', 0)
if ARGUMENTS.get('installdatadir', 0):
	installdatadir = ARGUMENTS.get('installdatadir', 0)

################ command line config
debug = int(ARGUMENTS.get('debug', 0))
devel = int(ARGUMENTS.get('devel', 0))
cvedit = int(ARGUMENTS.get('cvedit', 0))
usex86sse = int(ARGUMENTS.get('usex86sse', 0))
useefence = int(ARGUMENTS.get('useefence', 0))

################ set environment

osspecificsrc = []
extralibs = []

fftwlib = 'fftw3'
if sys.platform == 'win32':
	print "Compiling for Win32 Environment"
	env = Environment(ENV = os.environ, tools = ['mingw'])
	env.Append(CPPPATH = [sdlbase + '\\include\\SDL', sdlimagebase + '\\include', sdlnetbase + '\\include', sdlmixerbase + '\\include', fftw3base, glbase])
	libpath = [sdlbase + '\\lib', sdlimagebase + '\\lib', sdlnetbase + '\\lib', sdlmixerbase + '\\lib', fftw3base]
	gllibs = ['opengl32', 'glu32']
	sdllibs = ['SDL', 'SDL_image']
	env.Append(CPPDEFINES = ['_REENTRANT'])
	env.Append(CCFLAGS = '-Wall -O2') # for mingw!
	if (usex86sse >= 1):
		env.Append(CPPDEFINES = ['USE_SSE'])
		osspecificsrc += ['water_sse.cpp']
		print 'Using x86 SSE/MMX optimizations.'
	datadir = './data'
	build_dir = 'win32'
elif sys.platform == 'darwin':
	print "Compiling for MacOSX"
	env = Environment(ENV = os.environ)
	env.Append(CPPPATH = ['/System/Library/Frameworks/AGL.framework/Versions/A/Headers', '/System/Library/Frameworks/OpenGL.framework/Versions/A/Headers', '/usr/include/SDL'])
	libpath = ['/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries', '/sw/lib', '/usr/local/lib', '/usr/lib']
	gllibs = []
	sdllibs = ['SDL', 'SDL_image']
	env.Append(CCFLAGS = '-Wall -g -O2 -fno-coalesce `sdl-config --cflags`')
	env.Append(LINKFLAGS = '-F/Library/Frameworks -framework AGL -framework OpenGL -framework GLUT -framework Cocoa')
	datadir = installdatadir
	build_dir = 'macosx'
	osspecificsrc = Split("""Mac/SDLMain.m""")
else:
	print "Compiling for Unix/Posix/Linux Environment"
	env = Environment(ENV = os.environ)
	env.Append(CPPPATH = ['/usr/include/SDL', '/usr/include/GL'])
	libpath = ['/usr/X11R6/lib']
	gllibs = ['GL', 'GLU']
	sdllibs = ['SDL', 'SDL_image']
	ccflags = '-Wall `sdl-config --cflags`'
	if (debug >= 3):
		ccflags += ' -g -pg -O3'	# profiling
	elif (debug == 2):
		ccflags += ' -g -O0'
		env.Append(CPPDEFINES = ['DEBUG'])
	elif (debug == 1):
		ccflags += ' -g -O1'
		env.Append(CPPDEFINES = ['DEBUG'])
	elif (debug == -1):
		ccflags += ' -g -O3 -march=athlon-xp -march=athlon-xp -mfpmath=sse -mmmx -msse -m3dnow'
	elif (debug == -2):	# special g++4.0+ auto vectorization
		ccflags += ' -g -O3 -march=athlon-xp -march=athlon-xp -mfpmath=sse -mmmx -msse -m3dnow -ftree-vectorize -ftree-vectorizer-verbose=2'
	else:
		ccflags += ' -g -O2' # debug symbols will be stripped by the linker for a debian package
	if (useefence >= 1):
		extralibs += ['efence']
		print 'Linking to ElectricFence library!'
	if (cvedit == 1):
		env.Append(CPPDEFINES = ['CVEDIT'])
	# check for mmx/sse support
	cpuinfof = open('/proc/cpuinfo', 'r')
	cpuinfol = cpuinfof.readlines()
	mmxsupported = False
	ssesupported = False
	for i in cpuinfol:
		if i.startswith('flags'):
			m = Split(i)
			for j in m:
				if j == 'mmx':
					mmxsupported = True
				elif j == 'sse':
					ssesupported = True
			break
	if (usex86sse == 0) and (mmxsupported and ssesupported):
		usex86sse = 1
	if usex86sse >= 1:
		env.Append(CPPDEFINES = ['USE_SSE'])
		osspecificsrc += ['water_sse.cpp']
		print 'Using x86 SSE/MMX optimizations.'
	env.Append(CCFLAGS = ccflags)
	datadir = installdatadir
	build_dir = 'linux'
	# check for broken libGL, ignore undefined symbols then
	if (os.system('grep glBindProgram /usr/include/GL/gl*.h > /dev/null') == 0):
		gllibdirs = ['/usr/X11R6/lib/', '/usr/lib/', '/usr/local/lib/']
		gllibdir = ''
		for i in gllibdirs:
			if (os.system('test -f '+i+'libGL.so') == 0):
				gllibdir = i
				break
		if (i == ''):
			print 'ERROR: no libGL.so detected!'
		else:
			print 'Found GL library "'+gllibdir+'libGL.so"'
		if (os.system('grep glBindProgram '+gllibdir+'libGL.so > /dev/null') != 0):
			print 'GL headers declare glBindProgram, but libGL.so has no such symbol! Ignoring all undefined symbols...'
			# I'm not sure which option will hopefully fix the problem... so i use both...
			env.Append(LINKFLAGS = '--unresolved-symbols=ignore-all')
			env.Append(LINKFLAGS = '-Xlinker --unresolved-symbols -Xlinker ignore-all')

###### optionally change install and data dirs
if ARGUMENTS.get('datadir', 0):
	datadir = ARGUMENTS.get('datadir', 0)

print 'Install binary path: ' + installbindir
print 'Install data path: ' + installdatadir
print 'Using data dir: ' + datadir

target_dir = '#build' + os.sep + build_dir
source_base_dir = 'src'

################ configure
conf = Configure(env)
if (devel == 0):
	if not conf.CheckCHeader('gl.h'):
		print 'GL library must be installed!'
		Exit(1)
	if not conf.CheckCHeader('glu.h'):
		print 'GLU library must be installed!'
		Exit(1)
	if not conf.CheckCHeader('SDL.h'):
		print 'SDL library must be installed!'
		Exit(1)
	if not conf.CheckCHeader('SDL_image.h'):
		print 'SDL_image library must be installed!'
		Exit(1)
	if not conf.CheckCHeader('SDL_net.h'):
		print 'SDL_net library is needed for network code!'
		Exit(1)
	if not conf.CheckCHeader('SDL_mixer.h'):
		print 'SDL_mixer library is needed for sound support!'
		Exit(1)
	if not conf.CheckCHeader('fftw3.h'):
		print 'fftw3 library must be installed!'
		Exit(1)
	if conf.CheckLibWithHeader('fftw3f', 'fftw3.h', 'c'):
		print 'fftw3 library supports float type. Using it...'
		fftwlib = 'fftw3f'
		conf.env.Append(CPPDEFINES = ['WITH_FLOAT_FFTW'])
else:
	fftwlib = 'fftw3f'
	conf.env.Append(CPPDEFINES = ['WITH_FLOAT_FFTW'])	# developers always use float...
env = conf.Finish()

######################### source file lists
gfxlibs = ['oglext'] + gllibs + sdllibs
alllibs = ['dftdmedia', 'tinyxml'] + gfxlibs + ['SDL_mixer', 'SDL_net', fftwlib] + extralibs

################ helper functions
def all_entries_that_start_with_and_not(list, prefix, notprefix):
	list2 = []
	for i in list:
		if i.startswith(prefix) and not(i.startswith(notprefix)):
			list2 += [i]
	return list2


################ show some help when running scons -h
Help("""
	Danger from the Deep, SConstruct file help:
	Type 'scons' to build the binary.
	Type 'scons -c' to clean up.
	Type 'scons install' to install the game (as root).
	Type 'scons tarball' to build a tarball of the source (works only with Linux).
	Extra options (add them to command line, like 'scons extraoption=value'):
	'debug=x' to build debug level x, levels: 0: normal, 1: debug, 2: more debug,
		3: profiling, -1: extreme optimizations, -2: even more extreme optim.
	'usex86sse=x' where x < 0: disable them, 0: autodetect, 1: enable them.
	'useefence=x' when x > 0 use the Electric Fence library (for debugging)
	""")

################ build
libpath = libpath + [target_dir]
env.Append(LIBPATH = libpath)

f = open('files.txt')
allcvsfilesr = f.readlines()
# remove return code '\n' from end of line
allcvsfiles = []
for i in allcvsfilesr:
	allcvsfiles += [i[:len(i)-1]]

datafiles = all_entries_that_start_with_and_not(allcvsfiles, './data', './data/xcf')

Export('env', 'gfxlibs', 'alllibs', 'installbindir', 'installdatadir', 'datadir', 'datafiles', 'version', 'osspecificsrc')

SConscript(source_base_dir + os.sep + 'SConscript', build_dir = target_dir, duplicate = 0)

BuildDir(target_dir, source_base_dir, duplicate=0)

############### option so that "scons tarball" builds a tarball of source and data
# tar building works only on linux
if build_dir == 'linux':
	basetarfilename = 'dangerdeep-' + version
	os.system('rm -rf ' + basetarfilename)
	os.system('ln -s . ' + basetarfilename)
	filestopack = []
	for i in allcvsfiles:
		if not(i.endswith('.xcf')) and not(i.startswith('./data/xcf')):
			if not(i.startswith('.' + os.sep + 'build')):
				filestopack += [basetarfilename + os.sep + i]
	env.Append(TARFLAGS = '-zh')
	env.Append(TARSUFFIX = '.gz')
	tgz = env.Tar(basetarfilename + '.tar.gz', filestopack)
	env.Alias('tarball', tgz)

#also env.Zip is possible...

# fixme: maybe try env.MSVSProject(...) to create MS VS project files

############# eof
