from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from . import DefaultTable
try:
    import xml.etree.cElementTree as ET
except ImportError:
    import xml.etree.ElementTree as ET
import struct
import re

__doc__="""
Compiles/decompiles version 0 and 1 SVG tables from/to XML.

Version 1 is the first SVG definition, implemented in Mozilla before Aug 2013, now deprecated.
This module will decompile this correctly, but will compile a version 1 table
only if you add the secret element "<version1/>" to the SVG element in the TTF file.

Version 0 is the joint Adobe-Mozilla proposal, which supports color palettes.

The XML format is:
  <SVG>
    <svgDoc endGlyphID="1" startGlyphID="1">
      <![CDATA[ <complete SVG doc> ]]
    </svgDoc>
...
	<svgDoc endGlyphID="n" startGlyphID="m">
      <![CDATA[ <complete SVG doc> ]]
    </svgDoc>

    <colorPalettes>
    	<colorParamUINameID>n</colorParamUINameID>
    	...
    	<colorParamUINameID>m</colorParamUINameID>
    	<colorPalette uiNameID="n">
    		<colorRecord red="<int>" green="<int>" blue="<int>" alpha="<int>" />
    		...
    		<colorRecord red="<int>" green="<int>" blue="<int>" alpha="<int>" />
    	</colorPalette>
    	...
    	<colorPalette uiNameID="m">
    		<colorRecord red="<int> green="<int>" blue="<int>" alpha="<int>" />
    		...
    		<colorRecord red=<int>" green="<int>" blue="<int>" alpha="<int>" />
    	</colorPalette>
    </colorPalettes>
</SVG>

Color values must be less than 256. 

The number of color records in each </colorPalette> must be the same as
the number of <colorParamUINameID> elements.

"""

XML = ET.XML
XMLElement = ET.Element
xmlToString = ET.tostring

SVG_format_0 = """
	>   # big endian
	version:                  H
	offsetToSVGDocIndex:      L
	offsetToColorPalettes:    L
"""

SVG_format_0Size = sstruct.calcsize(SVG_format_0)

SVG_format_1 = """
	>   # big endian
	version:                  H
	numIndicies:              H
"""

SVG_format_1Size = sstruct.calcsize(SVG_format_1)

doc_index_entry_format_0 = """
	>   # big endian
	startGlyphID:             H
	endGlyphID:               H
	svgDocOffset:             L
	svgDocLength:             L
"""

doc_index_entry_format_0Size = sstruct.calcsize(doc_index_entry_format_0)

colorRecord_format_0 = """
	red:                      B
	green:                    B
	blue:                     B
	alpha:                    B
"""


class table_S_V_G_(DefaultTable.DefaultTable):
	
	def decompile(self, data, ttFont):
		self.docList = None
		self.colorPalettes = None
		pos = 0
		self.version = struct.unpack(">H", data[pos:pos+2])[0]
		
		if self.version == 1:
			self.decompile_format_1(data, ttFont)
		else:
			if self.version != 0:
				print("Unknown SVG table version '%s'. Decompiling as version 0." % (self.version))
			self.decompile_format_0(data, ttFont)


	def decompile_format_0(self, data, ttFont):
		dummy, data2 = sstruct.unpack2(SVG_format_0, data, self)
		# read in SVG Documents Index
		self.decompileEntryList(data)

		# read in colorPalettes table.
		self.colorPalettes = colorPalettes = ColorPalettes()
		pos = self.offsetToColorPalettes
		if pos > 0:
			colorPalettes.numColorParams = numColorParams = struct.unpack(">H", data[pos:pos+2])[0]
			if numColorParams > 0:
				colorPalettes.colorParamUINameIDs = colorParamUINameIDs = []
				pos = pos + 2
				i = 0
				while i < numColorParams:
					nameID = struct.unpack(">H", data[pos:pos+2])[0]
					colorParamUINameIDs.append(nameID)
					pos = pos + 2
					i += 1

				colorPalettes.numColorPalettes = numColorPalettes = struct.unpack(">H", data[pos:pos+2])[0]
				pos = pos + 2
				if numColorPalettes > 0:
					colorPalettes.colorPaletteList = colorPaletteList = []
					i = 0
					while i < numColorPalettes:
						colorPalette = ColorPalette()
						colorPaletteList.append(colorPalette)
						colorPalette.uiNameID = struct.unpack(">H", data[pos:pos+2])[0]
						pos = pos + 2
						colorPalette.paletteColors = paletteColors = []
						j = 0
						while j < numColorParams:
							colorRecord, colorPaletteData = sstruct.unpack2(colorRecord_format_0, data[pos:], ColorRecord())
							paletteColors.append(colorRecord)
							j += 1
							pos += 4
						i += 1

	def decompile_format_1(self, data, ttFont):
		pos = 2
		self.numEntries = struct.unpack(">H", data[pos:pos+2])[0]
		pos += 2
		self.decompileEntryList(data, pos)

	def decompileEntryList(self, data):
		# data starts with the first entry of the entry list.
		pos = subTableStart = self.offsetToSVGDocIndex
		self.numEntries = numEntries = struct.unpack(">H", data[pos:pos+2])[0]
		pos += 2
		if self.numEntries > 0:
			data2 = data[pos:]
			self.docList = []
			self.entries = entries = []
			i = 0
			while i < self.numEntries:
				docIndexEntry, data2 = sstruct.unpack2(doc_index_entry_format_0, data2, DocumentIndexEntry())
				entries.append(docIndexEntry)
				i += 1

			for entry in entries:
				start = entry.svgDocOffset + subTableStart
				end = start + entry.svgDocLength
				doc = tostr(data[start:end], "utf-8")
				self.docList.append( [doc, entry.startGlyphID, entry.endGlyphID] )

	def compile(self, ttFont):
		if hasattr(self, "version1"):
			data = self.compileFormat1(ttFont)
		else:
			data = self.compileFormat0(ttFont)
		return data

	def compileFormat0(self, ttFont):
		version = 0
		offsetToSVGDocIndex = SVG_format_0Size # I start the SVGDocIndex right after the header.
		# get SGVDoc info.
		docList = []
		entryList = []
		numEntries = len(self.docList)
		datum = struct.pack(">H",numEntries)
		entryList.append(datum)
		curOffset = len(datum) + doc_index_entry_format_0Size*numEntries
		for doc, startGlyphID, endGlyphID in self.docList:
			docOffset = curOffset
			docLength = len(doc)
			curOffset += docLength
			entry = struct.pack(">HHLL", startGlyphID, endGlyphID, docOffset, docLength)
			entryList.append(entry)
			docList.append(tobytes(doc, encoding="utf-8"))
		entryList.extend(docList)
		svgDocData = bytesjoin(entryList)

		# get colorpalette info.
		if self.colorPalettes is None:
			offsetToColorPalettes = 0
			palettesData = ""
		else:
			offsetToColorPalettes = SVG_format_0Size + len(svgDocData)
			dataList = []
			numColorParams = len(self.colorPalettes.colorParamUINameIDs)
			datum = struct.pack(">H", numColorParams)
			dataList.append(datum)
			for uiNameId in self.colorPalettes.colorParamUINameIDs:
				datum = struct.pack(">H", uiNameId)
				dataList.append(datum)
			numColorPalettes = len(self.colorPalettes.colorPaletteList)
			datum = struct.pack(">H", numColorPalettes)
			dataList.append(datum)
			for colorPalette in self.colorPalettes.colorPaletteList:
				datum = struct.pack(">H", colorPalette.uiNameID)
				dataList.append(datum)
				for colorRecord in colorPalette.paletteColors:
					data = struct.pack(">BBBB", colorRecord.red, colorRecord.green, colorRecord.blue, colorRecord.alpha)
					dataList.append(data)
			palettesData = bytesjoin(dataList)

		header = struct.pack(">HLL", version, offsetToSVGDocIndex, offsetToColorPalettes)
		data = [header, svgDocData, palettesData]
		data = bytesjoin(data)
		return data

	def compileFormat1(self, ttFont):
		version = 1
		numEntries = len(self.docList)
		header = struct.pack(">HH", version, numEntries)
		dataList = [header]
		docList = []
		curOffset = SVG_format_1Size + doc_index_entry_format_0Size*numEntries
		for doc, startGlyphID, endGlyphID in self.docList:
			docOffset = curOffset
			docLength = len(doc)
			curOffset += docLength
			entry = struct.pack(">HHLL", startGlyphID, endGlyphID, docOffset, docLength)
			dataList.append(entry)
			docList.append(tobytes(doc, encoding="utf-8"))
		dataList.extend(docList)
		data = bytesjoin(dataList)
		return data

	def toXML(self, writer, ttFont):
		writer.newline()
		for doc, startGID, endGID in self.docList:
			writer.begintag("svgDoc", startGlyphID=startGID, endGlyphID=endGID)
			writer.newline()
			writer.writecdata(doc)
			writer.newline()
			writer.endtag("svgDoc")
			writer.newline()

		if (self.colorPalettes is not None) and (self.colorPalettes.numColorParams is not None):
			writer.begintag("colorPalettes")
			writer.newline()
			for uiNameID in self.colorPalettes.colorParamUINameIDs:
				writer.begintag("colorParamUINameID")
				writer.writeraw(str(uiNameID))
				writer.endtag("colorParamUINameID")
				writer.newline()
			for colorPalette in self.colorPalettes.colorPaletteList:
				writer.begintag("colorPalette", [("uiNameID", str(colorPalette.uiNameID))])
				writer.newline()
				for colorRecord in colorPalette.paletteColors:
					colorAttributes = [
							("red", hex(colorRecord.red)),
							("green", hex(colorRecord.green)),
							("blue", hex(colorRecord.blue)),
							("alpha", hex(colorRecord.alpha)),
						]
					writer.begintag("colorRecord", colorAttributes)
					writer.endtag("colorRecord")
					writer.newline()
				writer.endtag("colorPalette")
				writer.newline()

			writer.endtag("colorPalettes")
			writer.newline()
		else:
			writer.begintag("colorPalettes")
			writer.endtag("colorPalettes")
			writer.newline()

	def fromXML(self, name, attrs, content, ttFont):
		import re
		if name == "svgDoc":
			if not hasattr(self, "docList"):
				self.docList = []
			doc = strjoin(content)
			doc = doc.strip()
			startGID = int(attrs["startGlyphID"])
			endGID = int(attrs["endGlyphID"])
			self.docList.append( [doc, startGID, endGID] )
		elif  name == "colorPalettes":
			self.colorPalettes = ColorPalettes()
			self.colorPalettes.fromXML(name, attrs, content, ttFont)
			if self.colorPalettes.numColorParams == 0:
				self.colorPalettes = None
		else:
			print("Unknown", name, content)

class DocumentIndexEntry(object):
	def __init__(self):
		self.startGlyphID = None # USHORT
		self.endGlyphID = None # USHORT
		self.svgDocOffset = None # ULONG
		self.svgDocLength = None # ULONG

	def __repr__(self):
		return "startGlyphID: %s, endGlyphID: %s, svgDocOffset: %s, svgDocLength: %s" % (self.startGlyphID, self.endGlyphID, self.svgDocOffset, self.svgDocLength)

class ColorPalettes(object):
	def __init__(self):
		self.numColorParams = None # USHORT
		self.colorParamUINameIDs = [] # list of name table name ID values that provide UI description of each color palette.
		self.numColorPalettes = None # USHORT
		self.colorPaletteList = [] # list of ColorPalette records

	def fromXML(self, name, attrs, content, ttFont):
		for element in content:
			if isinstance(element, type("")):
				continue
			name, attrib, content = element
			if name == "colorParamUINameID":
				uiNameID = int(content[0])
				self.colorParamUINameIDs.append(uiNameID)
			elif name == "colorPalette":
				colorPalette = ColorPalette()
				self.colorPaletteList.append(colorPalette)
				colorPalette.fromXML((name, attrib, content), ttFont)

		self.numColorParams = len(self.colorParamUINameIDs)
		self.numColorPalettes = len(self.colorPaletteList)
		for colorPalette in self.colorPaletteList:
			if len(colorPalette.paletteColors) != self.numColorParams:
				raise ValueError("Number of color records in a colorPalette ('%s') does not match the number of colorParamUINameIDs elements ('%s')." % (len(colorPalette.paletteColors), self.numColorParams))

class ColorPalette(object):
	def __init__(self):
		self.uiNameID = None # USHORT. name table ID that describes user interface strings associated with this color palette. 
		self.paletteColors = [] # list of ColorRecords

	def fromXML(self, name, attrs, content, ttFont):
		self.uiNameID = int(attrs["uiNameID"])
		for element in content:
			if isinstance(element, type("")):
				continue
			name, attrib, content = element
			if name == "colorRecord":
				colorRecord = ColorRecord()
				self.paletteColors.append(colorRecord)
				colorRecord.red = eval(attrib["red"])
				colorRecord.green = eval(attrib["green"])
				colorRecord.blue = eval(attrib["blue"])
				colorRecord.alpha = eval(attrib["alpha"])

class ColorRecord(object):
	def __init__(self):
		self.red = 255 # all are one byte values.
		self.green = 255
		self.blue = 255
		self.alpha = 255
