"""Module for reading and writing AFM files."""

# XXX reads AFM's generated by Fog, not tested with much else.
# It does not implement the full spec (Adobe Technote 5004, Adobe Font Metrics
# File Format Specification). Still, it should read most "common" AFM files.

from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
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):
		self._attrs = {}
		self._chars = {}
		self._kerning = {}
		self._index = {}
		self._comments = []
		self._composites = {}
		if path is not None:
			self.read(path)

	def read(self, path):
		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'):
		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):
		return pair in self._kerning

	def kernpairs(self):
		return list(self._kerning.keys())

	def has_char(self, char):
		return char in self._chars

	def chars(self):
		return list(self._chars.keys())

	def comments(self):
		return self._comments

	def addComment(self, comment):
		self._comments.append(comment)

	def addComposite(self, glyphName, components):
		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")
