from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from fontTools.misc.fixedTools import fixedToFloat as fi2fl, floatToFixed as fl2fi
from fontTools.misc.textTools import safeEval
from fontTools.ttLib import TTLibError
from . import DefaultTable
import struct
try:
	from collections.abc import MutableMapping
except ImportError:
	from UserDict import DictMixin as MutableMapping


# Apple's documentation of 'trak':
# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html

TRAK_HEADER_FORMAT = """
	> # big endian
	version:     16.16F
	format:      H
	horizOffset: H
	vertOffset:  H
	reserved:    H
"""

TRAK_HEADER_FORMAT_SIZE = sstruct.calcsize(TRAK_HEADER_FORMAT)


TRACK_DATA_FORMAT = """
	> # big endian
	nTracks:         H
	nSizes:          H
	sizeTableOffset: L
"""

TRACK_DATA_FORMAT_SIZE = sstruct.calcsize(TRACK_DATA_FORMAT)


TRACK_TABLE_ENTRY_FORMAT = """
	> # big endian
	track:      16.16F
	nameIndex:       H
	offset:          H
"""

TRACK_TABLE_ENTRY_FORMAT_SIZE = sstruct.calcsize(TRACK_TABLE_ENTRY_FORMAT)


# size values are actually '16.16F' fixed-point values, but here I do the
# fixedToFloat conversion manually instead of relying on sstruct
SIZE_VALUE_FORMAT = ">l"
SIZE_VALUE_FORMAT_SIZE = struct.calcsize(SIZE_VALUE_FORMAT)

# per-Size values are in 'FUnits', i.e. 16-bit signed integers
PER_SIZE_VALUE_FORMAT = ">h"
PER_SIZE_VALUE_FORMAT_SIZE = struct.calcsize(PER_SIZE_VALUE_FORMAT)


class table__t_r_a_k(DefaultTable.DefaultTable):
	dependencies = ['name']

	def compile(self, ttFont):
		dataList = []
		offset = TRAK_HEADER_FORMAT_SIZE
		for direction in ('horiz', 'vert'):
			trackData = getattr(self, direction + 'Data', TrackData())
			offsetName = direction + 'Offset'
			# set offset to 0 if None or empty
			if not trackData:
				setattr(self, offsetName, 0)
				continue
			# TrackData table format must be longword aligned
			alignedOffset = (offset + 3) & ~3
			padding, offset = b"\x00"*(alignedOffset - offset), alignedOffset
			setattr(self, offsetName, offset)

			data = trackData.compile(offset)
			offset += len(data)
			dataList.append(padding + data)

		self.reserved = 0
		tableData = bytesjoin([sstruct.pack(TRAK_HEADER_FORMAT, self)] + dataList)
		return tableData

	def decompile(self, data, ttFont):
		sstruct.unpack(TRAK_HEADER_FORMAT, data[:TRAK_HEADER_FORMAT_SIZE], self)
		for direction in ('horiz', 'vert'):
			trackData = TrackData()
			offset = getattr(self, direction + 'Offset')
			if offset != 0:
				trackData.decompile(data, offset)
			setattr(self, direction + 'Data', trackData)

	def toXML(self, writer, ttFont, progress=None):
		writer.simpletag('version', value=self.version)
		writer.newline()
		writer.simpletag('format', value=self.format)
		writer.newline()
		for direction in ('horiz', 'vert'):
			dataName = direction + 'Data'
			writer.begintag(dataName)
			writer.newline()
			trackData = getattr(self, dataName, TrackData())
			trackData.toXML(writer, ttFont)
			writer.endtag(dataName)
			writer.newline()

	def fromXML(self, name, attrs, content, ttFont):
		if name == 'version':
			self.version = safeEval(attrs['value'])
		elif name == 'format':
			self.format = safeEval(attrs['value'])
		elif name in ('horizData', 'vertData'):
			trackData = TrackData()
			setattr(self, name, trackData)
			for element in content:
				if not isinstance(element, tuple):
					continue
				name, attrs, content_ = element
				trackData.fromXML(name, attrs, content_, ttFont)


class TrackData(MutableMapping):

	def __init__(self, initialdata={}):
		self._map = dict(initialdata)

	def compile(self, offset):
		nTracks = len(self)
		sizes = self.sizes()
		nSizes = len(sizes)

		# offset to the start of the size subtable
		offset += TRACK_DATA_FORMAT_SIZE + TRACK_TABLE_ENTRY_FORMAT_SIZE*nTracks
		trackDataHeader = sstruct.pack(
			TRACK_DATA_FORMAT,
			{'nTracks': nTracks, 'nSizes': nSizes, 'sizeTableOffset': offset})

		entryDataList = []
		perSizeDataList = []
		# offset to per-size tracking values
		offset += SIZE_VALUE_FORMAT_SIZE*nSizes
		# sort track table entries by track value
		for track, entry in sorted(self.items()):
			assert entry.nameIndex is not None
			entry.track = track
			entry.offset = offset
			entryDataList += [sstruct.pack(TRACK_TABLE_ENTRY_FORMAT, entry)]
			# sort per-size values by size
			for size, value in sorted(entry.items()):
				perSizeDataList += [struct.pack(PER_SIZE_VALUE_FORMAT, value)]
			offset += PER_SIZE_VALUE_FORMAT_SIZE*nSizes
		# sort size values
		sizeDataList = [struct.pack(SIZE_VALUE_FORMAT, fl2fi(sv, 16)) for sv in sorted(sizes)]

		data = bytesjoin([trackDataHeader] + entryDataList + sizeDataList + perSizeDataList)
		return data

	def decompile(self, data, offset):
		# initial offset is from the start of trak table to the current TrackData
		trackDataHeader = data[offset:offset+TRACK_DATA_FORMAT_SIZE]
		if len(trackDataHeader) != TRACK_DATA_FORMAT_SIZE:
			raise TTLibError('not enough data to decompile TrackData header')
		sstruct.unpack(TRACK_DATA_FORMAT, trackDataHeader, self)
		offset += TRACK_DATA_FORMAT_SIZE

		nSizes = self.nSizes
		sizeTableOffset = self.sizeTableOffset
		sizeTable = []
		for i in range(nSizes):
			sizeValueData = data[sizeTableOffset:sizeTableOffset+SIZE_VALUE_FORMAT_SIZE]
			if len(sizeValueData) < SIZE_VALUE_FORMAT_SIZE:
				raise TTLibError('not enough data to decompile TrackData size subtable')
			sizeValue, = struct.unpack(SIZE_VALUE_FORMAT, sizeValueData)
			sizeTable.append(fi2fl(sizeValue, 16))
			sizeTableOffset += SIZE_VALUE_FORMAT_SIZE

		for i in range(self.nTracks):
			entry = TrackTableEntry()
			entryData = data[offset:offset+TRACK_TABLE_ENTRY_FORMAT_SIZE]
			if len(entryData) < TRACK_TABLE_ENTRY_FORMAT_SIZE:
				raise TTLibError('not enough data to decompile TrackTableEntry record')
			sstruct.unpack(TRACK_TABLE_ENTRY_FORMAT, entryData, entry)
			perSizeOffset = entry.offset
			for j in range(nSizes):
				size = sizeTable[j]
				perSizeValueData = data[perSizeOffset:perSizeOffset+PER_SIZE_VALUE_FORMAT_SIZE]
				if len(perSizeValueData) < PER_SIZE_VALUE_FORMAT_SIZE:
					raise TTLibError('not enough data to decompile per-size track values')
				perSizeValue, = struct.unpack(PER_SIZE_VALUE_FORMAT, perSizeValueData)
				entry[size] = perSizeValue
				perSizeOffset += PER_SIZE_VALUE_FORMAT_SIZE
			self[entry.track] = entry
			offset += TRACK_TABLE_ENTRY_FORMAT_SIZE

	def toXML(self, writer, ttFont, progress=None):
		nTracks = len(self)
		nSizes = len(self.sizes())
		writer.comment("nTracks=%d, nSizes=%d" % (nTracks, nSizes))
		writer.newline()
		for track, entry in sorted(self.items()):
			assert entry.nameIndex is not None
			entry.track = track
			entry.toXML(writer, ttFont)

	def fromXML(self, name, attrs, content, ttFont):
		if name != 'trackEntry':
			return
		entry = TrackTableEntry()
		entry.fromXML(name, attrs, content, ttFont)
		self[entry.track] = entry

	def sizes(self):
		if not self:
			return frozenset()
		tracks = list(self.tracks())
		sizes = self[tracks.pop(0)].sizes()
		for track in tracks:
			entrySizes = self[track].sizes()
			if sizes != entrySizes:
				raise TTLibError(
					"'trak' table entries must specify the same sizes: "
					"%s != %s" % (sorted(sizes), sorted(entrySizes)))
		return frozenset(sizes)

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

	def __delitem__(self, track):
		del self._map[track]

	def __setitem__(self, track, entry):
		self._map[track] = entry

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

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

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

	tracks = keys

	def __repr__(self):
		return "TrackData({})".format(self._map if self else "")


class TrackTableEntry(MutableMapping):

	def __init__(self, values={}, nameIndex=None):
		self.nameIndex = nameIndex
		self._map = dict(values)

	def toXML(self, writer, ttFont, progress=None):
		name = ttFont["name"].getDebugName(self.nameIndex)
		writer.begintag(
			"trackEntry",
			(('value', self.track), ('nameIndex', self.nameIndex)))
		writer.newline()
		if name:
			writer.comment(name)
			writer.newline()
		for size, perSizeValue in sorted(self.items()):
			writer.simpletag("track", size=size, value=perSizeValue)
			writer.newline()
		writer.endtag("trackEntry")
		writer.newline()

	def fromXML(self, name, attrs, content, ttFont):
		self.track = safeEval(attrs['value'])
		self.nameIndex = safeEval(attrs['nameIndex'])
		for element in content:
			if not isinstance(element, tuple):
				continue
			name, attrs, _ = element
			if name != 'track':
				continue
			size = safeEval(attrs['size'])
			self[size] = safeEval(attrs['value'])

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

	def __delitem__(self, size):
		del self._map[size]

	def __setitem__(self, size, value):
		self._map[size] = value

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

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

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

	sizes = keys

	def __repr__(self):
		return "TrackTableEntry({}, nameIndex={})".format(self._map, self.nameIndex)

	def __eq__(self, other):
		if not isinstance(other, self.__class__):
			return NotImplemented
		return self.nameIndex == other.nameIndex and dict(self) == dict(other)

	def __ne__(self, other):
		result = self.__eq__(other)
		return result if result is NotImplemented else not result
