"""Module for reading and writing AFM (Adobe Font Metrics) files.

Note that this has been designed to read in AFM files generated by Fontographer
and has not been tested on many other files. In particular, it does not
implement the whole Adobe AFM specification [#f1]_ but, it should read most
"common" AFM files.

Here is an example of using `afmLib` to read, modify and write an AFM file:

	>>> from fontTools.afmLib import AFM
	>>> f = AFM("Tests/afmLib/data/TestAFM.afm")
	>>>
	>>> # Accessing a pair gets you the kern value
	>>> f[("V","A")]
	-60
	>>>
	>>> # Accessing a glyph name gets you metrics
	>>> f["A"]
	(65, 668, (8, -25, 660, 666))
	>>> # (charnum, width, bounding box)
	>>>
	>>> # Accessing an attribute gets you metadata
	>>> f.FontName
	'TestFont-Regular'
	>>> f.FamilyName
	'TestFont'
	>>> f.Weight
	'Regular'
	>>> f.XHeight
	500
	>>> f.Ascender
	750
	>>>
	>>> # Attributes and items can also be set
	>>> f[("A","V")] = -150 # Tighten kerning
	>>> f.FontName = "TestFont Squished"
	>>>
	>>> # And the font written out again (remove the # in front)
	>>> #f.write("testfont-squished.afm")

.. rubric:: Footnotes

.. [#f1] `Adobe Technote 5004 <https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5004.AFM_Spec.pdf>`_,
   Adobe Font Metrics File Format Specification.

"""


import re

# every single line starts with a "word"
identifierRE = re.compile(r"^([A-Za-z]+).*")

# regular expression to parse char lines
charRE = re.compile(
		r"(-?\d+)"			# charnum
		r"\s*;\s*WX\s+"			# ; WX
		r"(-?\d+)"			# width
		r"\s*;\s*N\s+"			# ; N
		r"([.A-Za-z0-9_]+)"		# charname
		r"\s*;\s*B\s+"			# ; B
		r"(-?\d+)"			# left
		r"\s+"
		r"(-?\d+)"			# bottom
		r"\s+"
		r"(-?\d+)"			# right
		r"\s+"
		r"(-?\d+)"			# top
		r"\s*;\s*"			# ;
		)

# regular expression to parse kerning lines
kernRE = re.compile(
		r"([.A-Za-z0-9_]+)"		# leftchar
		r"\s+"
		r"([.A-Za-z0-9_]+)"		# rightchar
		r"\s+"
		r"(-?\d+)"			# value
		r"\s*"
		)

# regular expressions to parse composite info lines of the form:
# Aacute 2 ; PCC A 0 0 ; PCC acute 182 211 ;
compositeRE = re.compile(
		r"([.A-Za-z0-9_]+)"		# char name
		r"\s+"
		r"(\d+)"				# number of parts
		r"\s*;\s*"
		)
componentRE = re.compile(
		r"PCC\s+"			# PPC
		r"([.A-Za-z0-9_]+)"		# base char name
		r"\s+"
		r"(-?\d+)"			# x offset
		r"\s+"
		r"(-?\d+)"			# y offset
		r"\s*;\s*"
		)

preferredAttributeOrder = [
		"FontName",
		"FullName",
		"FamilyName",
		"Weight",
		"ItalicAngle",
		"IsFixedPitch",
		"FontBBox",
		"UnderlinePosition",
		"UnderlineThickness",
		"Version",
		"Notice",
		"EncodingScheme",
		"CapHeight",
		"XHeight",
		"Ascender",
		"Descender",
]


class error(Exception):
	pass


class AFM(object):

	_attrs = None

	_keywords = ['StartFontMetrics',
			'EndFontMetrics',
			'StartCharMetrics',
			'EndCharMetrics',
			'StartKernData',
			'StartKernPairs',
			'EndKernPairs',
			'EndKernData',
			'StartComposites',
			'EndComposites',
			]

	def __init__(self, path=None):
		"""AFM file reader.

		Instantiating an object with a path name will cause the file to be opened,
		read, and parsed. Alternatively the path can be left unspecified, and a
		file can be parsed later with the :meth:`read` method."""
		self._attrs = {}
		self._chars = {}
		self._kerning = {}
		self._index = {}
		self._comments = []
		self._composites = {}
		if path is not None:
			self.read(path)

	def read(self, path):
		"""Opens, reads and parses a file."""
		lines = readlines(path)
		for line in lines:
			if not line.strip():
				continue
			m = identifierRE.match(line)
			if m is None:
				raise error("syntax error in AFM file: " + repr(line))

			pos = m.regs[1][1]
			word = line[:pos]
			rest = line[pos:].strip()
			if word in self._keywords:
				continue
			if word == "C":
				self.parsechar(rest)
			elif word == "KPX":
				self.parsekernpair(rest)
			elif word == "CC":
				self.parsecomposite(rest)
			else:
				self.parseattr(word, rest)

	def parsechar(self, rest):
		m = charRE.match(rest)
		if m is None:
			raise error("syntax error in AFM file: " + repr(rest))
		things = []
		for fr, to in m.regs[1:]:
			things.append(rest[fr:to])
		charname = things[2]
		del things[2]
		charnum, width, l, b, r, t = (int(thing) for thing in things)
		self._chars[charname] = charnum, width, (l, b, r, t)

	def parsekernpair(self, rest):
		m = kernRE.match(rest)
		if m is None:
			raise error("syntax error in AFM file: " + repr(rest))
		things = []
		for fr, to in m.regs[1:]:
			things.append(rest[fr:to])
		leftchar, rightchar, value = things
		value = int(value)
		self._kerning[(leftchar, rightchar)] = value

	def parseattr(self, word, rest):
		if word == "FontBBox":
			l, b, r, t = [int(thing) for thing in rest.split()]
			self._attrs[word] = l, b, r, t
		elif word == "Comment":
			self._comments.append(rest)
		else:
			try:
				value = int(rest)
			except (ValueError, OverflowError):
				self._attrs[word] = rest
			else:
				self._attrs[word] = value

	def parsecomposite(self, rest):
		m = compositeRE.match(rest)
		if m is None:
			raise error("syntax error in AFM file: " + repr(rest))
		charname = m.group(1)
		ncomponents = int(m.group(2))
		rest = rest[m.regs[0][1]:]
		components = []
		while True:
			m = componentRE.match(rest)
			if m is None:
				raise error("syntax error in AFM file: " + repr(rest))
			basechar = m.group(1)
			xoffset = int(m.group(2))
			yoffset = int(m.group(3))
			components.append((basechar, xoffset, yoffset))
			rest = rest[m.regs[0][1]:]
			if not rest:
				break
		assert len(components) == ncomponents
		self._composites[charname] = components

	def write(self, path, sep='\r'):
		"""Writes out an AFM font to the given path."""
		import time
		lines = [	"StartFontMetrics 2.0",
				"Comment Generated by afmLib; at %s" % (
						time.strftime("%m/%d/%Y %H:%M:%S",
						time.localtime(time.time())))]

		# write comments, assuming (possibly wrongly!) they should
		# all appear at the top
		for comment in self._comments:
			lines.append("Comment " + comment)

		# write attributes, first the ones we know about, in
		# a preferred order
		attrs = self._attrs
		for attr in preferredAttributeOrder:
			if attr in attrs:
				value = attrs[attr]
				if attr == "FontBBox":
					value = "%s %s %s %s" % value
				lines.append(attr + " " + str(value))
		# then write the attributes we don't know about,
		# in alphabetical order
		items = sorted(attrs.items())
		for attr, value in items:
			if attr in preferredAttributeOrder:
				continue
			lines.append(attr + " " + str(value))

		# write char metrics
		lines.append("StartCharMetrics " + repr(len(self._chars)))
		items = [(charnum, (charname, width, box)) for charname, (charnum, width, box) in self._chars.items()]

		def myKey(a):
			"""Custom key function to make sure unencoded chars (-1)
			end up at the end of the list after sorting."""
			if a[0] == -1:
				a = (0xffff,) + a[1:]  # 0xffff is an arbitrary large number
			return a
		items.sort(key=myKey)

		for charnum, (charname, width, (l, b, r, t)) in items:
			lines.append("C %d ; WX %d ; N %s ; B %d %d %d %d ;" %
					(charnum, width, charname, l, b, r, t))
		lines.append("EndCharMetrics")

		# write kerning info
		lines.append("StartKernData")
		lines.append("StartKernPairs " + repr(len(self._kerning)))
		items = sorted(self._kerning.items())
		for (leftchar, rightchar), value in items:
			lines.append("KPX %s %s %d" % (leftchar, rightchar, value))
		lines.append("EndKernPairs")
		lines.append("EndKernData")

		if self._composites:
			composites = sorted(self._composites.items())
			lines.append("StartComposites %s" % len(self._composites))
			for charname, components in composites:
				line = "CC %s %s ;" % (charname, len(components))
				for basechar, xoffset, yoffset in components:
					line = line + " PCC %s %s %s ;" % (basechar, xoffset, yoffset)
				lines.append(line)
			lines.append("EndComposites")

		lines.append("EndFontMetrics")

		writelines(path, lines, sep)

	def has_kernpair(self, pair):
		"""Returns `True` if the given glyph pair (specified as a tuple) exists
		in the kerning dictionary."""
		return pair in self._kerning

	def kernpairs(self):
		"""Returns a list of all kern pairs in the kerning dictionary."""
		return list(self._kerning.keys())

	def has_char(self, char):
		"""Returns `True` if the given glyph exists in the font."""
		return char in self._chars

	def chars(self):
		"""Returns a list of all glyph names in the font."""
		return list(self._chars.keys())

	def comments(self):
		"""Returns all comments from the file."""
		return self._comments

	def addComment(self, comment):
		"""Adds a new comment to the file."""
		self._comments.append(comment)

	def addComposite(self, glyphName, components):
		"""Specifies that the glyph `glyphName` is made up of the given components.
		The components list should be of the following form::

			[
				(glyphname, xOffset, yOffset),
				...
			]
		
		"""
		self._composites[glyphName] = components

	def __getattr__(self, attr):
		if attr in self._attrs:
			return self._attrs[attr]
		else:
			raise AttributeError(attr)

	def __setattr__(self, attr, value):
		# all attrs *not* starting with "_" are consider to be AFM keywords
		if attr[:1] == "_":
			self.__dict__[attr] = value
		else:
			self._attrs[attr] = value

	def __delattr__(self, attr):
		# all attrs *not* starting with "_" are consider to be AFM keywords
		if attr[:1] == "_":
			try:
				del self.__dict__[attr]
			except KeyError:
				raise AttributeError(attr)
		else:
			try:
				del self._attrs[attr]
			except KeyError:
				raise AttributeError(attr)

	def __getitem__(self, key):
		if isinstance(key, tuple):
			# key is a tuple, return the kernpair
			return self._kerning[key]
		else:
			# return the metrics instead
			return self._chars[key]

	def __setitem__(self, key, value):
		if isinstance(key, tuple):
			# key is a tuple, set kernpair
			self._kerning[key] = value
		else:
			# set char metrics
			self._chars[key] = value

	def __delitem__(self, key):
		if isinstance(key, tuple):
			# key is a tuple, del kernpair
			del self._kerning[key]
		else:
			# del char metrics
			del self._chars[key]

	def __repr__(self):
		if hasattr(self, "FullName"):
			return '<AFM object for %s>' % self.FullName
		else:
			return '<AFM object at %x>' % id(self)


def readlines(path):
	with open(path, "r", encoding="ascii") as f:
		data = f.read()
	return data.splitlines()

def writelines(path, lines, sep='\r'):
	with open(path, "w", encoding="ascii", newline=sep) as f:
		f.write("\n".join(lines) + "\n")


if __name__ == "__main__":
	import EasyDialogs
	path = EasyDialogs.AskFileForOpen()
	if path:
		afm = AFM(path)
		char = 'A'
		if afm.has_char(char):
			print(afm[char])	# print charnum, width and boundingbox
		pair = ('A', 'V')
		if afm.has_kernpair(pair):
			print(afm[pair])	# print kerning value for pair
		print(afm.Version)	# various other afm entries have become attributes
		print(afm.Weight)
		# afm.comments() returns a list of all Comment lines found in the AFM
		print(afm.comments())
		#print afm.chars()
		#print afm.kernpairs()
		print(afm)
		afm.write(path + ".muck")
