#! /bin/python
#

import types
import os
import sys
import time
import datetime
import plistlib
import getopt
from xml.parsers import expat
from gtk import gdk

pl = dict()
stack = list()
stack.append(pl)

def top(ss):
	return ss[len(ss)-1]

def end_element_handler(tag):
	global stack

	if tag == "section":
		stack.pop()

def start_element_handler(tag, attr):
	global pl, stack

	current = top(stack)
	key = val = None
	if tag == "section":
		key = attr["name"]
		if key == "icons":
			val = dict()
			stack.append(val)
	elif tag == "icon":
		fbase = attr["file"]
		fname = find_file(fbase)
		key = attr["name"]
		if fname != None and key != None:
			val = dict()
			pb = gdk.pixbuf_new_from_file(fname)
			val["colorspace"] = pb.get_colorspace()
			val["alpha"] = pb.get_has_alpha()
			val["bps"] = pb.get_bits_per_sample()
			val["width"] = pb.get_width()
			val["height"] = pb.get_height()
			val["rowstride"] = pb.get_rowstride()
			val["data"] = plistlib.Data(pb.get_pixels())
		elif fname == None:
			print >> sys.stderr, ( "Error: No such icon file %s" % fbase )
			sys.exit(1)
	elif tag == "plist":
		fbase = attr["file"]
		fname = find_file(fbase)
		key = attr["name"]
		if fname != None and key != None:
			val = plistlib.readPlist(fname)
		elif fname == None:
			print >> sys.stderr, ( "Error: No such plist file %s" % fbase )
			sys.exit(1)
	elif tag == "string":
		fbase = attr["file"]
		fname = find_file(fbase)
		key = attr["name"]
		if fname != None and key != None:
			try:
				ff = open(fname)
				val = ff.read()
			except Exception, err:
				print >> sys.stderr, ( "Error: %s"  % str(err) )
				sys.exit(1)
		elif fname == None:
			print >> sys.stderr, ( "Error: No such string file %s" % fbase )
			sys.exit(1)
		
	if val != None:
		if type(current) == types.DictType:
			current[key] = val
		elif type(current) == types.TupleType:
			current.append(val)


def cdata_handler(str):
	return

def resource_parse_file(infile):
	parser = expat.ParserCreate()
	parser.StartElementHandler = start_element_handler
	parser.EndElementHandler = end_element_handler
	parser.CharacterDataHandler = cdata_handler
	parser.ParseFile(infile)

def usage():
	print >> sys.stderr, (
		"Usage: %s [-I <inc path>] <resource list> [resource plist]\n"
		"Summary:\n"
		"    Creates a resource plist from a resource list\n\n"
		"Options:\n"
		"    I - Include path to search for files\n"
		"    <resource list>    Input resources file\n"
		"    <resource plist>  Output resources plist file\n"
		% sys.argv[0]
	)

inc_list = list()

def find_file(name):
	global inc_list

	for inc_dir in inc_list:
		inc = "%s/%s" % (inc_dir, name)
		if os.path.isfile(inc):
			return inc

	if os.path.isfile(name):
		return name

	return None

def main():
	global inc_list

	OPTS = "I:"
	try:
		opts, args = getopt.gnu_getopt(sys.argv[1:], OPTS)
	except getopt.GetoptError, err:
		print >> sys.stderr, str(err)
		usage()
		sys.exit(2)

	for o, a in opts:
		if o == "-I":
			# add to include list
			inc_list.append(a)
		else:
			assert False, "unhandled option"

	if len(args) > 2 or len(args) < 1:
		usage()
		sys.exit(2)

	try:
		infile = open(args[0])
	except Exception, err:
		print >> sys.stderr, ( "Error: %s"  % str(err) )
		sys.exit(1)

	if len(args) > 1:
		try:
			outfile = open(args[1], "w")
		except Exception, err:
			print >> sys.stderr, ( "Error: %s"  % str(err))
			sys.exit(1)
	else:
		outfile = sys.stdout

	resource_parse_file(infile)
	plistlib.writePlist(pl, outfile)

main()

