'''togl_setup.py

Compiles and installs Togl.

'''

# created 2000/08/01, Rene Liebscher <R.Liebscher@gmx.de>

import sys,os,string, os.path
import distutils.command.install
import distutils.command.build_ext
from distutils.dep_util import newer_group

# this is also a simple test if we need to build Togl
# without Tkinter it is not neccessary
try:
	import Tkinter
	tk = Tkinter.Tk()
	if tk.getvar('tk_version') < '8.1' or tk.getvar('tcl_version') < '8.1':
		Togl = 'Togl-1.5'
	else:
		Togl = 'Togl-1.6'
	if tk.getvar( 'tk_version' ) >= '8.4':
		raise ImportError( """Preventing (doomed) attempts to build togl with Tk 8.4""" )
	# if the Togl sources are not included then don't build
	if not os.path.exists(os.path.join('src', Togl)):
		tk = None
except ImportError:
	tk = None
	Togl = None


class build_ext(distutils.command.build_ext.build_ext):

	def run(self):
		distutils.command.build_ext.build_ext.run(self)
		# togl_build can read instance variables of build_ext
		# for example: compiler, built_temp, force, debug, dry_run, ...
		if tk is not None and self.distribution.BUILD_TOGL:
			togl_build(self, self.distribution.include_dirs, self.distribution.library_dirs, self.distribution.togl_libs)


class install(distutils.command.install.install):

	togl_outfiles = None

	def run(self):
		distutils.command.install.install.run(self)
		# togl_install can read instance variables of install_lib
		# it has to return the filenames of all installed files
		if tk is not None and self.distribution.BUILD_TOGL:
			self.togl_outfiles = togl_install(self) 


	def get_outputs(self):
		if self.togl_outfiles is None:
			if tk is not None and self.distribution.BUILD_TOGL:
				self.togl_outfiles = togl_install(self,dry_run=1)
			else:
				self.togl_outfiles = []
		return distutils.command.install.install.get_outputs(self) + self.togl_outfiles              



def replace_lib(include_dirs, path):
	components = [path]
	rep = 0
	while 1:
		head, tail = os.path.split(components[0])
		if tail:
			if tail == 'lib':
				rep = 1
				components[0] = 'include'
			else:
				components[0] = tail
			components.insert(0, head)
		else:
			break
	if rep:
		include_dirs.append(apply(os.path.join, components))


# build togl
def togl_build(self, include_dirs, lib_dirs, libs): # a simple function, not a class !!!
	# maybe we should use build as base, but we need an initialized
	# compiler object from build_ext
	# so let us get a instance of 'build' now
	build = self.get_finalized_command ('build')
	
	include_dirs = include_dirs + []
	lib_dirs = lib_dirs + []
	libs = libs + []
	
	extra_compile_args = [] # ['-Wall','-O']
	extra_link_args = [] # ['-s']
	# Name for the shared lib: (distutils will change it to Togl.{so|dll})
	output_name = 'Togl'
	# where to put the built shared object (only for build process)
	output_dir = Togl + '-tk' + tk.getvar('tk_version')
	export_symbols = ['Togl_Init']
	sources = [os.path.join('src',Togl,'togl.c')]
	
	include_dirs.append(os.path.join('src',Togl))
	include_dirs.append(os.path.join(tk.getvar('tk_library'), '..', '..', 'include'))
	replace_lib(include_dirs, tk.getvar('tk_library'))
	
	lib_dirs.append(os.path.normpath(os.path.join(tk.getvar('tk_library'), '..')))
	
	runtime_library_dirs = None

	if sys.platform == 'win32':
		# VC++ 6.0 needs this, why togl doesn't use _WIN32?
		extra_compile_args.append('-DWIN32=1')
		
		libs.append('tcl' + string.replace(tk.getvar('tcl_version'), '.', ''))
		libs.append('tk' + string.replace(tk.getvar('tk_version'), '.', ''))
		if Togl == 'Togl-1.6':
			libs.append('tclstub' + string.replace(tk.getvar('tcl_version'), '.', ''))
			libs.append('tkstub' + string.replace(tk.getvar('tk_version'), '.', ''))
	else:
		include_dirs.append(os.path.normpath(os.path.join(tk.getvar('tcl_library'), '..', '..', 'include')))
		replace_lib(include_dirs, tk.getvar('tcl_library'))
		
		lib_dirs.append(os.path.normpath(os.path.join(tk.getvar('tcl_library'), '..')))
		
		libs.append('tcl' + tk.getvar('tcl_version'))
		libs.append('tk' + tk.getvar('tk_version'))

	# rest of this function was inspired by build_ext.py , build_extensions() 
	
	if self.inplace:
		# ignore build-base -- put the compiled extension into
		# the source tree along with pure Python modules
		pass
	else:
		output_dir = os.path.join (build.build_base, output_dir)

	if os.environ.has_key('CFLAGS'):
		extra_compile_args.extend(string.split(os.environ['CFLAGS']))

	# what is the name of the resulting file
	output_filename = self.compiler.shared_object_filename(
			basename=output_name,
			output_dir=output_dir)

	if not (self.force or newer_group(sources, output_filename, 'newer')):
		self.announce ('skipping "%s" (up-to-date)' % output_name)  
	else:
		self.announce ('building "%s"' % output_name)

		# compile source files        
		objects = self.compiler.compile (sources,
							output_dir=self.build_temp,
							macros=[
								('USE_TCL_STUBS',1),
								('USE_TK_STUBS',1),
							],
							include_dirs=include_dirs,
							debug=self.debug,
							extra_postargs=extra_compile_args)

		# link all together
		self.compiler.link_shared_object (
				objects, 
				output_filename,
				'', # <= output_dir
				libraries=libs,
				library_dirs=lib_dirs,
				runtime_library_dirs=runtime_library_dirs,
				extra_postargs=extra_link_args,
				export_symbols=export_symbols, 
				debug=self.debug,
				build_temp=self.build_temp)

	# building togl shared library

# togl_build    


from distutils.util import change_root
# install togl
#
# It is possibly to do this all in the build step, but then
# it is not included in a RPM distribution.
#
def togl_install(self,dry_run=0): # a simple function, not a class !!!

	outfiles = [] # we have to return all files we have installed
	
	# get path to Tk directory
	togl_dir = os.path.normpath(os.path.join(self.install_lib,'OpenGL','Tk', \
				sys.platform + '-tk' + tk.getvar('tk_version')))
	self.mkpath(togl_dir)       
	# how are the built files called, and 
	# which names should have the installed files
	if sys.platform == 'win32':
		togl = 'Togl.dll'
	else:
		togl = 'Togl.so'
	togl_src = os.path.join(self.build_base,
				Togl + '-tk' + tk.getvar('tk_version'), togl)
	togl_dst = os.path.join(togl_dir,togl)
	# copy togl in tk directory
	if not dry_run:
		from types import TupleType
		out = self.copy_file(togl_src, togl_dst)
		if type(out) is TupleType:
			out = out[0] 
	else:
		out = togl_dst
	outfiles.append(out)

	# make package index for tcl/tk
	if not dry_run: 
		# only if real install
		self.announce('running "pkg_mkIndex %s %s"' % (togl_dir, togl))
		if self.verbose:
			tk.tk.call('pkg_mkIndex','-verbose',togl_dir, togl)
		else:
			tk.tk.call('pkg_mkIndex',togl_dir, togl)
	outfiles.append(os.path.join(togl_dir,'pkgIndex.tcl'))

	return outfiles
