from collections import namedtuple
import os
from fontTools.cffLib import (
	maxStackLimit,
	TopDictIndex,
	buildOrder,
	topDictOperators,
	topDictOperators2,
	privateDictOperators,
	privateDictOperators2,
	FDArrayIndex,
	FontDict,
	VarStoreData
)
from fontTools.misc.py23 import BytesIO
from fontTools.cffLib.specializer import (
	specializeCommands, commandsToProgram)
from fontTools.ttLib import newTable
from fontTools import varLib
from fontTools.varLib.models import allEqual
from fontTools.misc.psCharStrings import T2CharString, T2OutlineExtractor
from fontTools.pens.t2CharStringPen import T2CharStringPen, t2c_round


def addCFFVarStore(varFont, varModel, varDataList, masterSupports):
	fvarTable = varFont['fvar']
	axisKeys = [axis.axisTag for axis in fvarTable.axes]
	varTupleList = varLib.builder.buildVarRegionList(masterSupports, axisKeys)
	varStoreCFFV = varLib.builder.buildVarStore(varTupleList, varDataList)

	topDict = varFont['CFF2'].cff.topDictIndex[0]
	topDict.VarStore = VarStoreData(otVarStore=varStoreCFFV)


def lib_convertCFFToCFF2(cff, otFont):
	# This assumes a decompiled CFF table.
	cff2GetGlyphOrder = cff.otFont.getGlyphOrder
	topDictData = TopDictIndex(None, cff2GetGlyphOrder, None)
	topDictData.items = cff.topDictIndex.items
	cff.topDictIndex = topDictData
	topDict = topDictData[0]
	if hasattr(topDict, 'Private'):
		privateDict = topDict.Private
	else:
		privateDict = None
	opOrder = buildOrder(topDictOperators2)
	topDict.order = opOrder
	topDict.cff2GetGlyphOrder = cff2GetGlyphOrder
	if not hasattr(topDict, "FDArray"):
		fdArray = topDict.FDArray = FDArrayIndex()
		fdArray.strings = None
		fdArray.GlobalSubrs = topDict.GlobalSubrs
		topDict.GlobalSubrs.fdArray = fdArray
		charStrings = topDict.CharStrings
		if charStrings.charStringsAreIndexed:
			charStrings.charStringsIndex.fdArray = fdArray
		else:
			charStrings.fdArray = fdArray
		fontDict = FontDict()
		fontDict.setCFF2(True)
		fdArray.append(fontDict)
		fontDict.Private = privateDict
		privateOpOrder = buildOrder(privateDictOperators2)
		for entry in privateDictOperators:
			key = entry[1]
			if key not in privateOpOrder:
				if key in privateDict.rawDict:
					# print "Removing private dict", key
					del privateDict.rawDict[key]
				if hasattr(privateDict, key):
					delattr(privateDict, key)
					# print "Removing privateDict attr", key
	else:
		# clean up the PrivateDicts in the fdArray
		fdArray = topDict.FDArray
		privateOpOrder = buildOrder(privateDictOperators2)
		for fontDict in fdArray:
			fontDict.setCFF2(True)
			for key in list(fontDict.rawDict.keys()):
				if key not in fontDict.order:
					del fontDict.rawDict[key]
					if hasattr(fontDict, key):
						delattr(fontDict, key)

			privateDict = fontDict.Private
			for entry in privateDictOperators:
				key = entry[1]
				if key not in privateOpOrder:
					if key in privateDict.rawDict:
						# print "Removing private dict", key
						del privateDict.rawDict[key]
					if hasattr(privateDict, key):
						delattr(privateDict, key)
						# print "Removing privateDict attr", key
	# Now delete up the decrecated topDict operators from CFF 1.0
	for entry in topDictOperators:
		key = entry[1]
		if key not in opOrder:
			if key in topDict.rawDict:
				del topDict.rawDict[key]
			if hasattr(topDict, key):
				delattr(topDict, key)

	# At this point, the Subrs and Charstrings are all still T2Charstring class
	# easiest to fix this by compiling, then decompiling again
	cff.major = 2
	file = BytesIO()
	cff.compile(file, otFont, isCFF2=True)
	file.seek(0)
	cff.decompile(file, otFont, isCFF2=True)


def convertCFFtoCFF2(varFont):
	# Convert base font to a single master CFF2 font.
	cffTable = varFont['CFF ']
	lib_convertCFFToCFF2(cffTable.cff, varFont)
	newCFF2 = newTable("CFF2")
	newCFF2.cff = cffTable.cff
	varFont['CFF2'] = newCFF2
	del varFont['CFF ']


class MergeDictError(TypeError):
	def __init__(self, key, value, values):
		error_msg = ["For the Private Dict key '{}', ".format(key),
					 "the default font value list:",
					 "\t{}".format(value),
					 "had a different number of values than a region font:"]
		error_msg += ["\t{}".format(region_value) for region_value in values]
		error_msg = os.linesep.join(error_msg)


def conv_to_int(num):
	if isinstance(num, float) and num.is_integer():
		return int(num)
	return num


pd_blend_fields = ("BlueValues", "OtherBlues", "FamilyBlues",
				   "FamilyOtherBlues", "BlueScale", "BlueShift",
				   "BlueFuzz", "StdHW", "StdVW", "StemSnapH",
				   "StemSnapV")


def get_private(regionFDArrays, fd_index, ri, fd_map):
	region_fdArray = regionFDArrays[ri]
	region_fd_map = fd_map[fd_index]
	if ri in region_fd_map:
		region_fdIndex = region_fd_map[ri]
		private = region_fdArray[region_fdIndex].Private
	else:
		private = None
	return private


def merge_PrivateDicts(top_dicts, vsindex_dict, var_model, fd_map):
	"""
	I step through the FontDicts in the FDArray of the varfont TopDict.
	For each varfont FontDict:
		step through each key in FontDict.Private.
		For each key, step through each relevant source font Private dict, and
		build a list of values to blend.
	The 'relevant' source fonts are selected by first getting the right
	submodel using vsindex_dict[vsindex]. The indices of the
	subModel.locations are mapped to source font list indices by
	assuming the latter order is the same as the order of the
	var_model.locations. I can then get the index of each subModel
	location in the list of var_model.locations.
	"""

	topDict = top_dicts[0]
	region_top_dicts = top_dicts[1:]
	if hasattr(region_top_dicts[0], 'FDArray'):
		regionFDArrays = [fdTopDict.FDArray for fdTopDict in region_top_dicts]
	else:
		regionFDArrays = [[fdTopDict] for fdTopDict in region_top_dicts]
	for fd_index, font_dict in enumerate(topDict.FDArray):
		private_dict = font_dict.Private
		vsindex = getattr(private_dict, 'vsindex', 0)
		# At the moment, no PrivateDict has a vsindex key, but let's support
		# how it should work. See comment at end of
		# merge_charstrings() - still need to optimize use of vsindex.
		sub_model, _ = vsindex_dict[vsindex]
		master_indices = []
		for loc in sub_model.locations[1:]:
			i = var_model.locations.index(loc) - 1
			master_indices.append(i)
		pds = [private_dict]
		last_pd = private_dict
		for ri in master_indices:
			pd = get_private(regionFDArrays, fd_index, ri, fd_map)
			# If the region font doesn't have this FontDict, just reference
			# the last one used.
			if pd is None:
				pd = last_pd
			else:
				last_pd = pd
			pds.append(pd)
		num_masters = len(pds)
		for key, value in private_dict.rawDict.items():
			dataList = []
			if key not in pd_blend_fields:
				continue
			if isinstance(value, list):
				try:
					values = [pd.rawDict[key] for pd in pds]
				except KeyError:
					print(
						"Warning: {key} in default font Private dict is "
						"missing from another font, and was "
						"discarded.".format(key=key))
					continue
				try:
					values = zip(*values)
				except IndexError:
					raise MergeDictError(key, value, values)
				"""
				Row 0 contains the first  value from each master.
				Convert each row from absolute values to relative
				values from the previous row.
				e.g for three masters,	a list of values was:
				master 0 OtherBlues = [-217,-205]
				master 1 OtherBlues = [-234,-222]
				master 1 OtherBlues = [-188,-176]
				The call to zip() converts this to:
				[(-217, -234, -188), (-205, -222, -176)]
				and is converted finally to:
				OtherBlues = [[-217, 17.0, 46.0], [-205, 0.0, 0.0]]
				"""
				prev_val_list = [0] * num_masters
				any_points_differ = False
				for val_list in values:
					rel_list = [(val - prev_val_list[i]) for (
							i, val) in enumerate(val_list)]
					if (not any_points_differ) and not allEqual(rel_list):
						any_points_differ = True
					prev_val_list = val_list
					deltas = sub_model.getDeltas(rel_list)
					# For PrivateDict BlueValues, the default font
					# values are absolute, not relative to the prior value.
					deltas[0] = val_list[0]
					dataList.append(deltas)
				# If there are no blend values,then
				# we can collapse the blend lists.
				if not any_points_differ:
					dataList = [data[0] for data in dataList]
			else:
				values = [pd.rawDict[key] for pd in pds]
				if not allEqual(values):
					dataList = sub_model.getDeltas(values)
				else:
					dataList = values[0]

			# Convert numbers with no decimal part to an int
			if isinstance(dataList, list):
				for i, item in enumerate(dataList):
					if isinstance(item, list):
						for j, jtem in enumerate(item):
							dataList[i][j] = conv_to_int(jtem)
					else:
						dataList[i] = conv_to_int(item)
			else:
				dataList = conv_to_int(dataList)

			private_dict.rawDict[key] = dataList


def getfd_map(varFont, fonts_list):
	""" Since a subset source font may have fewer FontDicts in their
	FDArray than the default font, we have to match up the FontDicts in
	the different fonts . We do this with the FDSelect array, and by
	assuming that the same glyph will reference  matching FontDicts in
	each source font. We return a mapping from fdIndex in the default
	font to a dictionary which maps each master list index of each
	region font to the equivalent fdIndex in the region font."""
	fd_map = {}
	default_font = fonts_list[0]
	region_fonts = fonts_list[1:]
	num_regions = len(region_fonts)
	topDict = default_font['CFF '].cff.topDictIndex[0]
	if not hasattr(topDict, 'FDSelect'):
		# All glyphs reference only one FontDict.
		# Map the FD index for regions to index 0.
		fd_map[0] = {ri:0 for ri in range(num_regions)}
		return fd_map

	gname_mapping = {}
	default_fdSelect = topDict.FDSelect
	glyphOrder = default_font.getGlyphOrder()
	for gid, fdIndex in enumerate(default_fdSelect):
		gname_mapping[glyphOrder[gid]] = fdIndex
		if fdIndex not in fd_map:
			fd_map[fdIndex] = {}
	for ri, region_font in enumerate(region_fonts):
		region_glyphOrder = region_font.getGlyphOrder()
		region_topDict = region_font['CFF '].cff.topDictIndex[0]
		if not hasattr(region_topDict, 'FDSelect'):
			# All the glyphs share the same FontDict. Pick any glyph.
			default_fdIndex = gname_mapping[region_glyphOrder[0]]
			fd_map[default_fdIndex][ri] = 0
		else:
			region_fdSelect = region_topDict.FDSelect
			for gid, fdIndex in enumerate(region_fdSelect):
				default_fdIndex = gname_mapping[region_glyphOrder[gid]]
				region_map = fd_map[default_fdIndex]
				if ri not in region_map:
					region_map[ri] = fdIndex
	return fd_map


CVarData = namedtuple('CVarData', 'varDataList masterSupports vsindex_dict')
def merge_region_fonts(varFont, model, ordered_fonts_list, glyphOrder):
	topDict = varFont['CFF2'].cff.topDictIndex[0]
	top_dicts = [topDict] + [
					ttFont['CFF '].cff.topDictIndex[0]
					for ttFont in ordered_fonts_list[1:]
					]
	num_masters = len(model.mapping)
	cvData = merge_charstrings(glyphOrder, num_masters, top_dicts, model)
	fd_map = getfd_map(varFont, ordered_fonts_list)
	merge_PrivateDicts(top_dicts, cvData.vsindex_dict, model, fd_map)
	addCFFVarStore(varFont, model, cvData.varDataList,
		cvData.masterSupports)


def _get_cs(charstrings, glyphName):
	if glyphName not in charstrings:
		return None
	return charstrings[glyphName]

def _add_new_vsindex(model, key, masterSupports, vsindex_dict,
		vsindex_by_key, varDataList):
	varTupleIndexes = []
	for support in model.supports[1:]:
		if support not in masterSupports:
			masterSupports.append(support)
		varTupleIndexes.append(masterSupports.index(support))
	var_data = varLib.builder.buildVarData(varTupleIndexes, None, False)
	vsindex = len(vsindex_dict)
	vsindex_by_key[key] = vsindex
	vsindex_dict[vsindex] = (model, [key])
	varDataList.append(var_data)
	return vsindex

def merge_charstrings(glyphOrder, num_masters, top_dicts, masterModel):

	vsindex_dict = {}
	vsindex_by_key = {}
	varDataList = []
	masterSupports = []
	default_charstrings = top_dicts[0].CharStrings
	for gid, gname in enumerate(glyphOrder):
		all_cs = [
				_get_cs(td.CharStrings, gname)
				for td in top_dicts]
		if len([gs for gs in all_cs if gs is not None]) == 1:
			continue
		model, model_cs = masterModel.getSubModel(all_cs)
		# create the first pass CFF2 charstring, from
		# the default charstring.
		default_charstring = model_cs[0]
		var_pen = CFF2CharStringMergePen([], gname, num_masters, 0)
		# We need to override outlineExtractor because these
		# charstrings do have widths in the 'program'; we need to drop these
		# values rather than post assertion error for them.
		default_charstring.outlineExtractor = MergeOutlineExtractor
		default_charstring.draw(var_pen)

		# Add the coordinates from all the other regions to the
		# blend lists in the CFF2 charstring.
		region_cs = model_cs[1:]
		for region_idx, region_charstring in enumerate(region_cs, start=1):
			var_pen.restart(region_idx)
			region_charstring.outlineExtractor = MergeOutlineExtractor
			region_charstring.draw(var_pen)

		# Collapse each coordinate list to a blend operator and its args.
		new_cs = var_pen.getCharString(
			private=default_charstring.private,
			globalSubrs=default_charstring.globalSubrs,
			var_model=model, optimize=True)
		default_charstrings[gname] = new_cs

		if (not var_pen.seen_moveto) or ('blend' not in new_cs.program):
			# If this is not a marking glyph, or if there are no blend
			# arguments, then we can use vsindex 0. No need to
			# check if we need a new vsindex.
			continue

		# If the charstring required a new model, create
		# a VarData table to go with, and set vsindex.
		key = tuple(v is not None for v in all_cs)
		try:
			vsindex = vsindex_by_key[key]
		except KeyError:
			vsindex = _add_new_vsindex(model, key, masterSupports, vsindex_dict,
				vsindex_by_key, varDataList)
		# We do not need to check for an existing new_cs.private.vsindex,
		# as we know it doesn't exist yet.
		if vsindex != 0:
			new_cs.program[:0] = [vsindex, 'vsindex']

	# If there is no variation in any of the charstrings, then vsindex_dict
	# never gets built. This could still be needed if there is variation
	# in the PrivatDict, so we will build the default data for vsindex = 0.
	if not vsindex_dict:
		key = (True,) * num_masters
		_add_new_vsindex(model, key, masterSupports, vsindex_dict,
			vsindex_by_key, varDataList)
	cvData = CVarData(varDataList=varDataList, masterSupports=masterSupports,
						vsindex_dict=vsindex_dict)
	# XXX To do: optimize use of vsindex between the PrivateDicts and
	# charstrings
	return cvData


class MergeTypeError(TypeError):
	def __init__(self, point_type, pt_index, m_index, default_type, glyphName):
			self.error_msg = [
						"In glyph '{gname}' "
						"'{point_type}' at point index {pt_index} in master "
						"index {m_index} differs from the default font point "
						"type '{default_type}'"
						"".format(
								gname=glyphName,
								point_type=point_type, pt_index=pt_index,
								m_index=m_index, default_type=default_type)
							][0]
			super(MergeTypeError, self).__init__(self.error_msg)


def makeRoundNumberFunc(tolerance):
	if tolerance < 0:
		raise ValueError("Rounding tolerance must be positive")

	def roundNumber(val):
		return t2c_round(val, tolerance)

	return roundNumber


class CFFToCFF2OutlineExtractor(T2OutlineExtractor):
	""" This class is used to remove the initial width from the CFF
	charstring without trying to add the width to self.nominalWidthX,
	which is None. """
	def popallWidth(self, evenOdd=0):
		args = self.popall()
		if not self.gotWidth:
			if evenOdd ^ (len(args) % 2):
				args = args[1:]
			self.width = self.defaultWidthX
			self.gotWidth = 1
		return args


class MergeOutlineExtractor(CFFToCFF2OutlineExtractor):
	""" Used to extract the charstring commands - including hints - from a
	CFF charstring in order to merge it as another set of region data
	into a CFF2 variable font charstring."""

	def __init__(self, pen, localSubrs, globalSubrs,
			nominalWidthX, defaultWidthX, private=None):
		super(CFFToCFF2OutlineExtractor, self).__init__(pen, localSubrs,
			globalSubrs, nominalWidthX, defaultWidthX, private)

	def countHints(self):
		args = self.popallWidth()
		self.hintCount = self.hintCount + len(args) // 2
		return args

	def _hint_op(self, type, args):
		self.pen.add_hint(type, args)

	def op_hstem(self, index):
		args = self.countHints()
		self._hint_op('hstem', args)

	def op_vstem(self, index):
		args = self.countHints()
		self._hint_op('vstem', args)

	def op_hstemhm(self, index):
		args = self.countHints()
		self._hint_op('hstemhm', args)

	def op_vstemhm(self, index):
		args = self.countHints()
		self._hint_op('vstemhm', args)

	def _get_hintmask(self, index):
		if not self.hintMaskBytes:
			args = self.countHints()
			if args:
				self._hint_op('vstemhm', args)
			self.hintMaskBytes = (self.hintCount + 7) // 8
		hintMaskBytes, index = self.callingStack[-1].getBytes(index,
			self.hintMaskBytes)
		return index, hintMaskBytes

	def op_hintmask(self, index):
		index, hintMaskBytes = self._get_hintmask(index)
		self.pen.add_hintmask('hintmask', [hintMaskBytes])
		return hintMaskBytes, index

	def op_cntrmask(self, index):
		index, hintMaskBytes = self._get_hintmask(index)
		self.pen.add_hintmask('cntrmask', [hintMaskBytes])
		return hintMaskBytes, index


class CFF2CharStringMergePen(T2CharStringPen):
	"""Pen to merge Type 2 CharStrings.
	"""
	def __init__(
				self, default_commands, glyphName, num_masters, master_idx,
				roundTolerance=0.5):
		super(
			CFF2CharStringMergePen,
			self).__init__(
							width=None,
							glyphSet=None, CFF2=True,
							roundTolerance=roundTolerance)
		self.pt_index = 0
		self._commands = default_commands
		self.m_index = master_idx
		self.num_masters = num_masters
		self.prev_move_idx = 0
		self.seen_moveto = False
		self.glyphName = glyphName
		self.roundNumber = makeRoundNumberFunc(roundTolerance)

	def add_point(self, point_type, pt_coords):
		if self.m_index == 0:
			self._commands.append([point_type, [pt_coords]])
		else:
			cmd = self._commands[self.pt_index]
			if cmd[0] != point_type:
				raise MergeTypeError(
									point_type,
									self.pt_index, len(cmd[1]),
									cmd[0], self.glyphName)
			cmd[1].append(pt_coords)
		self.pt_index += 1

	def add_hint(self, hint_type, args):
		if self.m_index == 0:
			self._commands.append([hint_type, [args]])
		else:
			cmd = self._commands[self.pt_index]
			if cmd[0] != hint_type:
				raise MergeTypeError(hint_type, self.pt_index, len(cmd[1]),
					cmd[0], self.glyphName)
			cmd[1].append(args)
		self.pt_index += 1

	def add_hintmask(self, hint_type, abs_args):
		# For hintmask, fonttools.cffLib.specializer.py expects
		# each of these to be represented by two sequential commands:
		# first holding only the operator name, with an empty arg list,
		# second with an empty string as the op name, and  the mask arg list.
		if self.m_index == 0:
			self._commands.append([hint_type, []])
			self._commands.append(["", [abs_args]])
		else:
			cmd = self._commands[self.pt_index]
			if cmd[0] != hint_type:
				raise MergeTypeError(hint_type, self.pt_index, len(cmd[1]),
					cmd[0], self.glyphName)
			self.pt_index += 1
			cmd = self._commands[self.pt_index]
			cmd[1].append(abs_args)
		self.pt_index += 1

	def _moveTo(self, pt):
		if not self.seen_moveto:
			self.seen_moveto = True
		pt_coords = self._p(pt)
		self.add_point('rmoveto', pt_coords)
		# I set prev_move_idx here because add_point()
		# can change self.pt_index.
		self.prev_move_idx = self.pt_index - 1

	def _lineTo(self, pt):
		pt_coords = self._p(pt)
		self.add_point('rlineto', pt_coords)

	def _curveToOne(self, pt1, pt2, pt3):
		_p = self._p
		pt_coords = _p(pt1)+_p(pt2)+_p(pt3)
		self.add_point('rrcurveto', pt_coords)

	def _closePath(self):
		pass

	def _endPath(self):
		pass

	def restart(self, region_idx):
		self.pt_index = 0
		self.m_index = region_idx
		self._p0 = (0, 0)

	def getCommands(self):
		return self._commands

	def reorder_blend_args(self, commands, get_delta_func, round_func):
		"""
		We first re-order the master coordinate values.
		For a moveto to lineto, the args are now arranged as:
			[ [master_0 x,y], [master_1 x,y], [master_2 x,y] ]
		We re-arrange this to
		[	[master_0 x, master_1 x, master_2 x],
			[master_0 y, master_1 y, master_2 y]
		]
		If the master values are all the same, we collapse the list to
		as single value instead of a list.

		We then convert this to:
		[ [master_0 x] + [x delta tuple] + [numBlends=1]
		  [master_0 y] + [y delta tuple] + [numBlends=1]
		]
		"""
		for cmd in commands:
			# arg[i] is the set of arguments for this operator from master i.
			args = cmd[1]
			m_args = zip(*args)
			# m_args[n] is now all num_master args for the i'th argument
			# for this operation.
			cmd[1] = list(m_args)
		lastOp = None
		for cmd in commands:
			op = cmd[0]
			# masks are represented by two cmd's: first has only op names,
			# second has only args.
			if lastOp in ['hintmask', 'cntrmask']:
				coord = list(cmd[1])
				assert allEqual(coord), (
					"hintmask values cannot differ between source fonts.")
				cmd[1] = [coord[0][0]]
			else:
				coords = cmd[1]
				new_coords = []
				for coord in coords:
					if allEqual(coord):
						new_coords.append(coord[0])
					else:
						# convert to deltas
						deltas = get_delta_func(coord)[1:]
						if round_func:
							deltas = [round_func(delta) for delta in deltas]
						coord = [coord[0]] + deltas
						new_coords.append(coord)
				cmd[1] = new_coords
			lastOp = op
		return commands

	def getCharString(
					self, private=None, globalSubrs=None,
					var_model=None, optimize=True):
		commands = self._commands
		commands = self.reorder_blend_args(commands, var_model.getDeltas,
											self.roundNumber)
		if optimize:
			commands = specializeCommands(
						commands, generalizeFirst=False,
						maxstack=maxStackLimit)
		program = commandsToProgram(commands)
		charString = T2CharString(
						program=program, private=private,
						globalSubrs=globalSubrs)
		return charString
