from xml.dom import minidom
import sys
import getopt

# language helper
#
# by Ethan Yonker (Dees_Troy)
#
# This script reads the English and supplied other language files and
# compares the 2 and reorders and rewrites the other language to a new
# XML file such that all the strings are placed in the same order as
# the English file. It will place commented out string lines for items
# that are not present in the new file and will not include any strings
# in the new file that are no longer present in the English source.
# There is also a version tag that may be compared if present between
# the English and other language in case a translation string changes.



# this helps us avoid ascii unicode errors when writing the final XML
def toprettyxml(xdoc, encoding):
    #"""Return a pretty-printed XML document in a given encoding."""
    unistr = xdoc.toprettyxml().replace(u'<?xml version="1.0" ?>',
                          u'<?xml version="1.0" encoding="%s"?>' % encoding)
    return unistr.encode(encoding, 'xmlcharrefreplace')

HELP = """
  language_helper.py   -o file.xml    other language to compare to English
                     [ -f file.xml ]  output file (defaults to new.xml)
                       -h             help info
"""

enfile = "en.xml"
otherfile = ""
outfile = "new.xml"

try:
	opts, args = getopt.getopt(sys.argv[1:], "hfo:koz", ["device="])
except getopt.GetoptEror:
	print HELP
	sys.stdout.flush()
	sys.exit(2)

for opt, arg in opts:
	if opt == "-h":
		print HELP
		sys.stdout.flush()
		sys.exit()
	elif opt == "-o":
		otherfile = arg
	elif opt == "-f":
		outfile = arg

if otherfile == "":
	print HELP
	exit()

print "Comparing %s and %s" % (enfile, otherfile)
print ""

# Open English
endoc = minidom.parse(enfile)

# Open other language
otherdoc = minidom.parse(otherfile)
otherstrings = otherdoc.getElementsByTagName('string')

# create minidom-document
doc = minidom.Document()

# language tag
language = doc.createElement('language')
doc.appendChild(language)

# display tag (name of the language that shows in the GUI)
otherlang = ""
otherdisplay = otherdoc.getElementsByTagName('display')
for disnode in otherdisplay:
	if disnode.nodeType == disnode.ELEMENT_NODE:
		language.appendChild(disnode)
		otherlang = disnode.firstChild.data.encode("utf-8")
		print otherlang

# resources
resources = doc.createElement('resources')
language.appendChild(resources)

enres = endoc.getElementsByTagName('resources')
for resnode in enres:
	resc = resnode.childNodes
	for child in resc:
		if child.nodeType == child.ELEMENT_NODE:
			if child.tagName != "string":
				otherres = otherdoc.getElementsByTagName('resources')
				found = False
				for othernode in otherres:
					otherresc = othernode.childNodes
					for otherchild in otherresc:
						if otherchild.nodeType == otherchild.ELEMENT_NODE:
							if otherchild.tagName == child.tagName:
								if otherchild.attributes['name'].value == child.attributes['name'].value:
									found = True
									resources.appendChild(otherchild)
									break
					if found == True:
						break
				if found == False:
					print "Failed to find %s in %s, using what we got from English" % (child.toxml(), otherlang)
					resources.appendChild(child)
			else:
				found = False
				for others in otherstrings:
					if child.attributes['name'].value == others.attributes['name'].value:
						found = True
						enver = "1"
						if child.hasAttribute('version'):
							enver = child.attributes['version'].value
						otherver = "1"
						if others.hasAttribute('version'):
							otherver = others.attributes['version'].value
						if enver != otherver:
							ver_err = "English has version " + enver + " but " + otherlang + " has version " + otherver + " for '" + child.attributes['name'].value + "'"
							print ver_err
							version_comment = doc.createComment(ver_err)
							resources.appendChild(version_comment)
							resources.appendChild(others)
						else:
							resources.appendChild(others)
						break
				if found == False:
					print "'%s' present in English and not in %s" % (child.attributes['name'].value.encode("utf-8"), otherlang)
					notfound_err = "NOT FOUND " + child.toxml().replace('--', '\-\-')
					notfound_comment = doc.createComment(notfound_err)
					resources.appendChild(notfound_comment)
		elif child.nodeType == child.COMMENT_NODE:
			resources.appendChild(child)

# Done, output the xml to a file
file_handle = open(outfile,"wb")
itspretty = toprettyxml(doc, "utf-8")
file_handle.write(itspretty)
file_handle.close()
