"""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.
"""

DEBUG=0

import sys
sys.stdout = sys.stderr

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

# .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__'

# A resource with this name sets the "owner" (creator) of the destination
# XXXX Should look for id=0
OWNERNAME = "owner resource"

# OpenResFile mode parameters
READ = 1
WRITE = 2

def findtemplate():
	"""Locate the applet template along sys.path"""
	for p in sys.path:
		template = os.path.join(p, TEMPLATE)
		try:
			template, d1, d2 = macfs.ResolveAliasFile(template)
			break
		except (macfs.error, ValueError):
			continue
	else:
		die("Template %s not found on sys.path" % `TEMPLATE`)
		return
	template = template.as_pathname()
	return template

def main():
	
	# Find the template
	# (there's no point in proceeding if we can't find it)
	
	template = findtemplate()
	if DEBUG:
		print 'Using template', template
			
	# Ask for source text if not specified in sys.argv[1:]
	
	if not sys.argv[1:]:
		srcfss, ok = macfs.PromptGetFile('Select Python source file:', 'TEXT')
		if not ok:
			return
		filename = srcfss.as_pathname()
		tp, tf = os.path.split(filename)
		if tf[-3:] == '.py':
			tf = tf[:-3]
		else:
			tf = tf + '.applet'
		dstfss, ok = macfs.StandardPutFile('Save application as:', tf)
		if not ok: return
		process(template, filename, dstfss.as_pathname())
	else:
		
		# Loop over all files to be processed
		for filename in sys.argv[1:]:
			process(template, filename, '')

def process(template, filename, output):
	
	if DEBUG:
		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):
		die("Syntax error in script %s" % `filename`)
		return
	
	# Set the destination file name
	
	if string.lower(filename[-3:]) == ".py":
		destname = filename[:-3]
		rsrcname = destname + '.rsrc'
	else:
		destname = filename + ".applet"
		rsrcname = filename + '.rsrc'
	
	if output:
		destname = output
		
	# Try removing the output file
	try:
		os.unlink(output)
	except os.error:
		pass
		

	# Create FSSpecs for the various files
		
	template_fss = macfs.FSSpec(template)
	template_fss, d1, d2 = macfs.ResolveAliasFile(template_fss)
	dest_fss = macfs.FSSpec(destname)
	
	# Copy data (not resources, yet) from the template
	
	tmpl = open(template, "rb")
	dest = open(destname, "wb")
	data = tmpl.read()
	if data:
		dest.write(data)
	dest.close()
	tmpl.close()
	
	# Open the output resource fork
	
	try:
		output = FSpOpenResFile(dest_fss, WRITE)
	except MacOS.Error:
		if DEBUG:
			print "Creating resource fork..."
		CreateResFile(destname)
		output = FSpOpenResFile(dest_fss, WRITE)
		
	# Copy the resources from the target specific resource template, if any
	typesfound, ownertype = [], None
	try:
		input = FSpOpenResFile(rsrcname, READ)
	except (MacOS.Error, ValueError):
		pass
	else:
		typesfound, ownertype = copyres(input, output, [], 0)
		CloseResFile(input)
		
	# Check which resource-types we should not copy from the template
	skiptypes = []
	if 'SIZE' in typesfound: skiptypes.append('SIZE')
	if 'BNDL' in typesfound: skiptypes = skiptypes + ['BNDL', 'FREF', 'icl4', 
			'icl8', 'ics4', 'ics8', 'ICN#', 'ics#']
	skipowner = (ownertype <> None)
	
	# Copy the resources from the template
	
	input = FSpOpenResFile(template_fss, READ)
	dummy, tmplowner = copyres(input, output, skiptypes, skipowner)
	if ownertype == None:
		ownertype = tmplowner
	CloseResFile(input)
	if ownertype == None:
		die("No owner resource found in either resource file or template")	
	
	# Now set the creator, type and bundle bit of the destination
	dest_finfo = dest_fss.GetFInfo()
	dest_finfo.Creator = ownertype
	dest_finfo.Type = 'APPL'
	dest_finfo.Flags = dest_finfo.Flags | MACFS.kHasBundle
	dest_finfo.Flags = dest_finfo.Flags & ~MACFS.kHasBeenInited
	dest_fss.SetFInfo(dest_finfo)
	
	# 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.RemoveResource()
	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 output file
	
	CloseResFile(output)
	
	macostools.touched(dest_fss)
	if DEBUG:
		print "Applet created:", destname


# Copy resources between two resource file descriptors.
# skip a resource named '__main__' or (if skipowner is set) 'Owner resource'.
# Also skip resources with a type listed in skiptypes.
#
def copyres(input, output, skiptypes, skipowner):
	ctor = None
	alltypes = []
	UseResFile(input)
	ntypes = Count1Types()
	for itype in range(1, 1+ntypes):
		type = Get1IndType(itype)
		if type in skiptypes:
			continue
		alltypes.append(type)
		nresources = Count1Resources(type)
		for ires in range(1, 1+nresources):
			res = Get1IndResource(type, ires)
			id, type, name = res.GetResInfo()
			lcname = string.lower(name)
			if (type, lcname) == (RESTYPE, RESNAME):
				continue # Don't copy __main__ from template
			# XXXX should look for id=0
			if lcname == OWNERNAME:
				if skipowner:
					continue # Skip this one
				else:
					ctor = type
			size = res.size
			attrs = res.GetResAttrs()
			if DEBUG:
				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:
				if DEBUG:
					print "Overwriting..."
				res2.RemoveResource()
			res.AddResource(type, id, name)
			res.WriteResource()
			attrs = attrs | res.GetResAttrs()
			if DEBUG:
				print "New attrs =", hex(attrs)
			res.SetResAttrs(attrs)
			UseResFile(input)
	return alltypes, ctor


# Show a message and exit

def die(str):
	message(str)
	sys.exit(1)


# Show a message

def message(str, id = 256):
	from Dlg import *
	d = GetNewDialog(id, -1)
	if not d:
		print "Error:", `str`
		print "DLOG id =", id, "not found."
		return
	tp, h, rect = d.GetDialogItem(2)
	SetDialogItemText(h, str)
	d.SetDialogDefaultItem(1)
	while 1:
		n = ModalDialog(None)
		if n == 1: break
	del d


if __name__ == '__main__':
	main()
