#!/usr/bin/python

import sys
import os.path

if len (sys.argv) != 3:
	print >>sys.stderr, "usage: ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt"
	sys.exit (1)

files = [file (x) for x in sys.argv[1:]]

headers = [[files[0].readline (), files[0].readline ()]]
headers.append (["UnicodeData.txt does not have a header."])
while files[0].readline ().find ('##################') < 0:
	pass


def print_joining_table(f):

	print
	print "static const uint8_t joining_table[] ="
	print "{"

	min_u = 0x110000
	max_u = 0
	num = 0
	last = -1
	block = ''
	for line in f:

		if line[0] == '#':
			if line.find (" characters"):
				block = line[2:].strip ()
			continue

		fields = [x.strip () for x in line.split (';')]
		if len (fields) == 1:
			continue

		u = int (fields[0], 16)
		if u == 0x200C or u == 0x200D:
			continue
		if u < last:
			raise Exception ("Input data character not sorted", u)
		min_u = min (min_u, u)
		max_u = max (max_u, u)
		num += 1

		if block:
			print "\n  /* %s */\n" % block
			block = ''

		if last != -1:
			last += 1
			while last < u:
				print "  JOINING_TYPE_X, /* %04X */" % last
				last += 1
		else:
			last = u

		if fields[3] in ["ALAPH", "DALATH RISH"]:
			value = "JOINING_GROUP_" + fields[3].replace(' ', '_')
		else:
			value = "JOINING_TYPE_" + fields[2]
		print "  %s, /* %s */" % (value, '; '.join(fields))

	print
	print "};"
	print
	print "#define JOINING_TABLE_FIRST	0x%04X" % min_u
	print "#define JOINING_TABLE_LAST	0x%04X" % max_u
	print

	occupancy = num * 100 / (max_u - min_u + 1)
	# Maintain at least 40% occupancy in the table */
	if occupancy < 40:
		raise Exception ("Table too sparse, please investigate: ", occupancy)

def print_shaping_table(f):

	shapes = {}
	ligatures = {}
	names = {}
	for line in f:

		fields = [x.strip () for x in line.split (';')]
		if fields[5][0:1] != '<':
			continue

		items = fields[5].split (' ')
		shape, items = items[0][1:-1], tuple (int (x, 16) for x in items[1:])

		if not shape in ['initial', 'medial', 'isolated', 'final']:
			continue

		c = int (fields[0], 16)
		if len (items) != 1:
			# We only care about lam-alef ligatures
			if len (items) != 2 or items[0] != 0x0644 or items[1] not in [0x0622, 0x0623, 0x0625, 0x0627]:
				continue

			# Save ligature
			names[c] = fields[1]
			if items not in ligatures:
				ligatures[items] = {}
			ligatures[items][shape] = c
			pass
		else:
			# Save shape
			if items[0] not in names:
				names[items[0]] = fields[1]
			else:
				names[items[0]] = os.path.commonprefix ([names[items[0]], fields[1]]).strip ()
			if items[0] not in shapes:
				shapes[items[0]] = {}
			shapes[items[0]][shape] = c

	print
	print "static const uint16_t shaping_table[][4] ="
	print "{"

	keys = shapes.keys ()
	min_u, max_u = min (keys), max (keys)
	for u in range (min_u, max_u + 1):
		s = [shapes[u][shape] if u in shapes and shape in shapes[u] else 0
		     for shape in  ['initial', 'medial', 'final', 'isolated']]
		value = ', '.join ("0x%04X" % c for c in s)
		print "  {%s}, /* U+%04X %s */" % (value, u, names[u] if u in names else "")

	print "};"
	print
	print "#define SHAPING_TABLE_FIRST	0x%04X" % min_u
	print "#define SHAPING_TABLE_LAST	0x%04X" % max_u
	print

	ligas = {}
	for pair in ligatures.keys ():
		for shape in ligatures[pair]:
			c = ligatures[pair][shape]
			if shape == 'isolated':
				liga = (shapes[pair[0]]['initial'], shapes[pair[1]]['final'])
			elif shape == 'final':
				liga = (shapes[pair[0]]['medial'], shapes[pair[1]]['final'])
			else:
				raise Exception ("Unexpected shape", shape)
			if liga[0] not in ligas:
				ligas[liga[0]] = []
			ligas[liga[0]].append ((liga[1], c))
	max_i = max (len (ligas[l]) for l in ligas)
	print
	print "static const struct ligature_set_t {"
	print " uint16_t first;"
	print " struct ligature_pairs_t {"
	print "   uint16_t second;"
	print "   uint16_t ligature;"
	print " } ligatures[%d];" % max_i
	print "} ligature_table[] ="
	print "{"
	keys = ligas.keys ()
	keys.sort ()
	for first in keys:

		print "  { 0x%04X, {" % (first)
		for liga in ligas[first]:
			print "    { 0x%04X, 0x%04X }, /* %s */" % (liga[0], liga[1], names[liga[1]])
		print "  }},"

	print "};"
	print



print "/* == Start of generated table == */"
print "/*"
print " * The following table is generated by running:"
print " *"
print " *   ./gen-arabic-table.py ArabicShaping.txt UnicodeData.txt"
print " *"
print " * on files with these headers:"
print " *"
for h in headers:
	for l in h:
		print " * %s" % (l.strip())
print " */"
print
print "#ifndef HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
print "#define HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH"
print

print_joining_table (files[0])
print_shaping_table (files[1])

print
print "#endif /* HB_OT_SHAPE_COMPLEX_ARABIC_TABLE_HH */"
print
print "/* == End of generated table == */"

