"""Create an applet from a Python script.

This puts up a dialog asking for a Python source file ('TEXT').
The output is a file with the same name but its ".py" suffix dropped.
It is created by copying an applet template and then adding a 'PYC '
resource named __main__ containing the compiled, marshalled script.
"""

import sys
sys.stdout = sys.stderr

import string
import os
import marshal
import imp
import macfs
import MacOS
from Res import *

# .pyc file (and 'PYC ' resource magic number)
MAGIC = imp.get_magic()

# Template file (searched on sys.path)
TEMPLATE = "PythonApplet"

# Specification of our resource
RESTYPE = 'PYC '
RESNAME = '__main__'

# OpenResFile mode parameters
READ = 1
WRITE = 2

def main():
	
	# Find the template
	# (there's no point in proceeding if we can't find it)
	
	for p in sys.path:
		template = os.path.join(p, TEMPLATE)
		try:
			tmpl = open(template, "rb")
			tmpl.close()
			break
		except IOError:
			continue
	else:
		# XXX Ought to put up a dialog
		print "Template", `template`, "not found"
		return
	
	# Ask for source text if not specified in sys.argv[1:]
	
	if not sys.argv[1:]:
		srcfss, ok = macfs.StandardGetFile('TEXT')
		if not ok:
			return
		filename = srcfss.as_pathname()
		if not sys.argv: sys.argv.append('')
		sys.argv.append(filename)
	
	# Loop over all files to be processed
	
	for filename in sys.argv[1:]:
		process(template, filename)

undefs = ('????', '    ', '\0\0\0\0')

def process(template, filename):
	
	print "Processing", `filename`, "..."
	
	# Read the source and compile it
	# (there's no point overwriting the destination if it has a syntax error)
	
	fp = open(filename)
	text = fp.read()
	fp.close()
	try:
		code = compile(text, filename, "exec")
	except (SyntaxError, EOFError):
		print "Syntax error in script", `filename`
		return
	
	# Set the destination file name
	
	if string.lower(filename[-3:]) == ".py":
		destname = filename[:-3]
	else:
		destname = filename + ".applet"
	
	# Copy the data from the template (creating the file as well)
	
	tmpl = open(template, "rb")
	dest = open(destname, "wb")
	data = tmpl.read()
	if data:
		dest.write(data)
	dest.close()
	tmpl.close()
	
	# Copy the creator and type of the template to the destination
	# unless it already has one
	
	tctor, ttype = MacOS.GetCreatorAndType(template)
	ctor, type = MacOS.GetCreatorAndType(destname)
	if type in undefs: type = ttype
	if ctor in undefs: ctor = tctor
	MacOS.SetCreatorAndType(destname, ctor, type)
	
	# Open the input and output resource forks
	
	input = FSpOpenResFile(template, READ)
	try:
		output = FSpOpenResFile(destname, WRITE)
	except MacOS.Error:
		print "Creating resource fork..."
		CreateResFile(destname)
		output = FSpOpenResFile(destname, WRITE)
	
	# Copy the resources from the template,
	# except a 'PYC ' resource named __main__
	
	UseResFile(input)
	ntypes = Count1Types()
	for itype in range(1, 1+ntypes):
		type = Get1IndType(itype)
		nresources = Count1Resources(type)
		for ires in range(1, 1+nresources):
			res = Get1IndResource(type, ires)
			id, type, name = res.GetResInfo()
			if (type, name) == (RESTYPE, RESNAME):
				continue # Don't copy __main__ from template
			size = res.SizeResource()
			attrs = res.GetResAttrs()
			print id, type, name, size, hex(attrs)
			res.LoadResource()
			res.DetachResource()
			UseResFile(output)
			try:
				res2 = Get1Resource(type, id)
			except MacOS.Error:
				res2 = None
			if res2:
				print "Overwriting..."
				res2.RmveResource()
			res.AddResource(type, id, name)
			#res.SetResAttrs(attrs)
			res.WriteResource()
			UseResFile(input)
	CloseResFile(input)
	
	# Make sure we're manipulating the output resource file now
	
	UseResFile(output)
	
	# Delete any existing 'PYC 'resource named __main__
	
	try:
		res = Get1NamedResource(RESTYPE, RESNAME)
		res.RmveResource()
	except Error:
		pass
	
	# Create the raw data for the resource from the code object
	
	data = marshal.dumps(code)
	del code
	data = (MAGIC + '\0\0\0\0') + data
	
	# Create the resource and write it
	
	id = 0
	while id < 128:
		id = Unique1ID(RESTYPE)
	res = Resource(data)
	res.AddResource(RESTYPE, id, RESNAME)
	res.WriteResource()
	res.ReleaseResource()
	
	# Close the resource file
	
	CloseResFile(output)
	
	print "Done with", `filename`, "..."


if __name__ == '__main__':
	main()
