import DefaultTable
import sstruct
from fontTools.misc.textTools import safeEval

maxpFormat_0_5 = """
		>	# big endian
		tableVersion:           i
		numGlyphs:              H
"""

maxpFormat_1_0_add = """
		>	# big endian
		maxPoints:              H
		maxContours:            H
		maxCompositePoints:     H
		maxCompositeContours:   H
		maxZones:               H
		maxTwilightPoints:      H
		maxStorage:             H
		maxFunctionDefs:        H
		maxInstructionDefs:     H
		maxStackElements:       H
		maxSizeOfInstructions:  H
		maxComponentElements:   H
		maxComponentDepth:      H
"""


class table__m_a_x_p(DefaultTable.DefaultTable):
	
	dependencies = ['glyf']
	
	def decompile(self, data, ttFont):
		dummy, data = sstruct.unpack2(maxpFormat_0_5, data, self)
		self.numGlyphs = int(self.numGlyphs)
		if self.tableVersion != 0x00005000:
			dummy, data = sstruct.unpack2(maxpFormat_1_0_add, data, self)
		assert len(data) == 0
	
	def compile(self, ttFont):
		if ttFont.has_key('glyf'):
			if ttFont.isLoaded('glyf') and ttFont.recalcBBoxes:
				self.recalc(ttFont)
		else:
			pass  # CFF
		self.numGlyphs = len(ttFont.getGlyphOrder())
		if self.tableVersion != 0x00005000:
			self.tableVersion = 0x00010000
		data = sstruct.pack(maxpFormat_0_5, self)
		if self.tableVersion == 0x00010000:
			data = data + sstruct.pack(maxpFormat_1_0_add, self)
		return data
	
	def recalc(self, ttFont):
		"""Recalculate the font bounding box, and most other maxp values except
		for the TT instructions values. Also recalculate the value of bit 1
		of the flags field and the font bounding box of the 'head' table.
		"""
		glyfTable = ttFont['glyf']
		hmtxTable = ttFont['hmtx']
		headTable = ttFont['head']
		self.numGlyphs = len(glyfTable)
		xMin = 100000
		yMin = 100000
		xMax = -100000
		yMax = -100000
		maxPoints = 0
		maxContours = 0
		maxCompositePoints = 0
		maxCompositeContours = 0
		maxComponentElements = 0
		maxComponentDepth = 0
		allXMaxIsLsb = 1
		for glyphName in ttFont.getGlyphOrder():
			g = glyfTable[glyphName]
			if g.numberOfContours:
				if hmtxTable[glyphName][1] <> g.xMin:
					allXMaxIsLsb = 0
				xMin = min(xMin, g.xMin)
				yMin = min(yMin, g.yMin)
				xMax = max(xMax, g.xMax)
				yMax = max(yMax, g.yMax)
				if g.numberOfContours > 0:
					nPoints, nContours = g.getMaxpValues()
					maxPoints = max(maxPoints, nPoints)
					maxContours = max(maxContours, nContours)
				else:
					nPoints, nContours, componentDepth = g.getCompositeMaxpValues(glyfTable)
					maxCompositePoints = max(maxCompositePoints, nPoints)
					maxCompositeContours = max(maxCompositeContours, nContours)
					maxComponentElements = max(maxComponentElements, len(g.components))
					maxComponentDepth = max(maxComponentDepth, componentDepth)
		headTable.xMin = xMin
		headTable.yMin = yMin
		headTable.xMax = xMax
		headTable.yMax = yMax
		self.maxPoints = maxPoints
		self.maxContours = maxContours
		self.maxCompositePoints = maxCompositePoints
		self.maxCompositeContours = maxCompositeContours
		self.maxComponentDepth = maxComponentDepth
		if allXMaxIsLsb:
			headTable.flags = headTable.flags | 0x2
		else:
			headTable.flags = headTable.flags & ~0x2
	
	def testrepr(self):
		items = self.__dict__.items()
		items.sort()
		print ". . . . . . . . ."
		for combo in items:
			print "  %s: %s" % combo
		print ". . . . . . . . ."
	
	def toXML(self, writer, ttFont):
		if self.tableVersion != 0x00005000:
			writer.comment("Most of this table will be recalculated by the compiler")
			writer.newline()
		formatstring, names, fixes = sstruct.getformat(maxpFormat_0_5)
		if self.tableVersion != 0x00005000:
			formatstring, names_1_0, fixes = sstruct.getformat(maxpFormat_1_0_add)
			names = names + names_1_0
		for name in names:
			value = getattr(self, name)
			if type(value) == type(0L):
				value=int(value)
			if name == "tableVersion":
				value = hex(value)
			writer.simpletag(name, value=value)
			writer.newline()
	
	def fromXML(self, (name, attrs, content), ttFont):
		setattr(self, name, safeEval(attrs["value"]))
		

