import sys, string
from xml.sax import handler, make_parser

class State():
	def __init__(self, id, initial = False, final = False):
		self.id = id
		self.initial = initial
		self.final = final
	def __str__(self):
		s = self.id + '[label = "q' + self.id + '",'
		if self.initial:
			s += "style = \"filled\", fillcolor = \"grey\","
		if self.final:
			s += "shape = \"doublecircle\""
		else:
			s += "shape = \"circle\""
		return s + "];"
		
class Transition():
	def __init__(self, fro = -1, to = -1, read = 'null'):
		self.fro = fro
		self.to = to
		self.read = read
	def __str__(self):
		return str(self.fro) + " -> " + str(self.to) + "[label=\"" + self.read + "\"];"

class MySaxDocumentHandler(handler.ContentHandler):				# [1]
	def __init__(self, outfile):								# [2]
		self.outfile = outfile
		self.level = 0
		self.inState = False
		self.inTrans = False
		self.inTo = False
		self.inFrom = False
		self.inRead = False
		self.curState = None
		self.curTrans = None
		self.states = []
		self.transitions = []
		self.toData = []
		self.fromData = []
		self.readData = []
	def startDocument(self):									# [3]
		pass
#		print "--------	 Document Start --------"
	def endDocument(self):										# [4]
		pass
#		print "--------	 Document End --------"
	def startElement(self, name, attrs):						# [5]
		self.level += 1
#		self.printLevel()
#		self.outfile.write('Element: %s\n' % name)
		self.level += 2
#		for attrName in attrs.keys():							# [6]
#			self.printLevel()
#			self.outfile.write('Attribute -- Name: %s  Value: %s\n' % \
#				(attrName, attrs.get(attrName)))
		self.level -= 2
		if name == 'transition':
			self.inTrans = True
			self.curTrans = Transition()
		if name == 'state':
			self.inState = True
			self.curState = State(attrs.get('id'))
		if name == 'initial' and self.inState:
			self.curState.initial = True
		if name == 'final' and self.inState:
			self.curState.final = True
		if name == 'from':
			self.inFrom = True
			self.fromData = []
		if name == 'to':
			self.inTo = True
			self.toData = []
		if name == 'read':
			self.inRead = True
			self.readData = []
	def endElement(self, name):									# [7]
		if name == 'state':
			self.inState = False
			self.states.append(self.curState)
		if name == 'transition':
			self.inTrans = False
			self.transitions.append(self.curTrans)
		if name == 'to':
			self.inTo = False
			self.curTrans.to = int("".join(self.toData))
		if name == 'from':
			self.inFrom = False
			self.curTrans.fro = int("".join(self.fromData))
		if name == 'read':
			self.inRead = False
			self.curTrans.read = "".join(self.readData)
		self.level -= 1
	def characters(self, chrs):									# [8]
		if self.inTo:
			self.toData.append(chrs)
		if self.inFrom:
			self.fromData.append(chrs)
		if self.inRead:
			self.readData.append(chrs)
	def printLevel(self):										# [9]
		for idx in range(self.level):
			self.outfile.write('  ')

def test(inFileName):
	outFile = sys.stdout
	# Create an instance of the Handler.
	handler = MySaxDocumentHandler(outFile)
	# Create an instance of the parser.
	parser = make_parser()
	# Set the content handler.
	parser.setContentHandler(handler)
	inFile = open(inFileName, 'r')
	# Start the parse.
	parser.parse(inFile)										# [10]
	# Alternatively, we could directly pass in the file name.
	#parser.parse(inFileName)
	inFile.close()
	# Print out a list of interests.
	print "digraph sample {"
	for s in handler.states:
		print s
	for t in handler.transitions:
		print t
	print "}"

def main():
	args = sys.argv[1:]
	if len(args) != 1:
		print 'usage: python test.py infile.xml'
		sys.exit(-1)
	test(args[0])

if __name__ == '__main__':
	main()
