from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from . import DefaultTable
import array

hdmxHeaderFormat = """
	>   # big endian!
	version:	H
	numRecords:	H
	recordSize:	l
"""

try:
	from collections.abc import Mapping
except:
	from UserDict import DictMixin as Mapping

class _GlyphnamedList(Mapping):

	def __init__(self, reverseGlyphOrder, data):
		self._array = data
		self._map = dict(reverseGlyphOrder)

	def __getitem__(self, k):
		return self._array[self._map[k]]

	def __len__(self):
		return len(self._map)

	def __iter__(self):
		return iter(self._map)

	def keys(self):
		return self._map.keys()

class table__h_d_m_x(DefaultTable.DefaultTable):

	def decompile(self, data, ttFont):
		numGlyphs = ttFont['maxp'].numGlyphs
		glyphOrder = ttFont.getGlyphOrder()
		dummy, data = sstruct.unpack2(hdmxHeaderFormat, data, self)
		self.hdmx = {}
		for i in range(self.numRecords):
			ppem = byteord(data[0])
			maxSize = byteord(data[1])
			widths = _GlyphnamedList(ttFont.getReverseGlyphMap(), array.array("B", data[2:2+numGlyphs]))
			self.hdmx[ppem] = widths
			data = data[self.recordSize:]
		assert len(data) == 0, "too much hdmx data"

	def compile(self, ttFont):
		self.version = 0
		numGlyphs = ttFont['maxp'].numGlyphs
		glyphOrder = ttFont.getGlyphOrder()
		self.recordSize = 4 * ((2 + numGlyphs + 3) // 4)
		pad = (self.recordSize - 2 - numGlyphs) * b"\0"
		self.numRecords = len(self.hdmx)
		data = sstruct.pack(hdmxHeaderFormat, self)
		items = sorted(self.hdmx.items())
		for ppem, widths in items:
			data = data + bytechr(ppem) + bytechr(max(widths.values()))
			for glyphID in range(len(glyphOrder)):
				width = widths[glyphOrder[glyphID]]
				data = data + bytechr(width)
			data = data + pad
		return data

	def toXML(self, writer, ttFont):
		writer.begintag("hdmxData")
		writer.newline()
		ppems = sorted(self.hdmx.keys())
		records = []
		format = ""
		for ppem in ppems:
			widths = self.hdmx[ppem]
			records.append(widths)
			format = format + "%4d"
		glyphNames = ttFont.getGlyphOrder()[:]
		glyphNames.sort()
		maxNameLen = max(map(len, glyphNames))
		format = "%" + repr(maxNameLen) + 's:' + format + ' ;'
		writer.write(format % (("ppem",) + tuple(ppems)))
		writer.newline()
		writer.newline()
		for glyphName in glyphNames:
			row = []
			for ppem in ppems:
				widths = self.hdmx[ppem]
				row.append(widths[glyphName])
			if ";" in glyphName:
				glyphName = "\\x3b".join(glyphName.split(";"))
			writer.write(format % ((glyphName,) + tuple(row)))
			writer.newline()
		writer.endtag("hdmxData")
		writer.newline()

	def fromXML(self, name, attrs, content, ttFont):
		if name != "hdmxData":
			return
		content = strjoin(content)
		lines = content.split(";")
		topRow = lines[0].split()
		assert topRow[0] == "ppem:", "illegal hdmx format"
		ppems = list(map(int, topRow[1:]))
		self.hdmx = hdmx = {}
		for ppem in ppems:
			hdmx[ppem] = {}
		lines = (line.split() for line in lines[1:])
		for line in lines:
			if not line:
				continue
			assert line[0][-1] == ":", "illegal hdmx format"
			glyphName = line[0][:-1]
			if "\\" in glyphName:
				from fontTools.misc.textTools import safeEval
				glyphName = safeEval('"""' + glyphName + '"""')
			line = list(map(int, line[1:]))
			assert len(line) == len(ppems), "illegal hdmx format"
			for i in range(len(ppems)):
				hdmx[ppems[i]][glyphName] = line[i]
