from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.misc import sstruct
from fontTools.misc.textTools import safeEval
from itertools import *
from functools import partial
from . import DefaultTable
from . import grUtils
import struct, operator, warnings
try:
    import lz4
except: 
    lz4 = None


Glat_format_0 = """
    >        # big endian
    version: 16.16F
"""

Glat_format_3 = """
    >
    version: 16.16F
    compression:L    # compression scheme or reserved 
"""

Glat_format_1_entry = """
    >
    attNum:     B    # Attribute number of first attribute
    num:        B    # Number of attributes in this run
"""
Glat_format_23_entry = """
    >
    attNum:     H    # Attribute number of first attribute
    num:        H    # Number of attributes in this run
"""

Glat_format_3_octabox_metrics = """
    >
    subboxBitmap:   H    # Which subboxes exist on 4x4 grid
    diagNegMin:     B    # Defines minimum negatively-sloped diagonal (si)
    diagNegMax:     B    # Defines maximum negatively-sloped diagonal (sa)
    diagPosMin:     B    # Defines minimum positively-sloped diagonal (di)
    diagPosMax:     B    # Defines maximum positively-sloped diagonal (da)
"""

Glat_format_3_subbox_entry = """
    >
    left:           B    # xi
    right:          B    # xa
    bottom:         B    # yi
    top:            B    # ya
    diagNegMin:     B    # Defines minimum negatively-sloped diagonal (si)
    diagNegMax:     B    # Defines maximum negatively-sloped diagonal (sa)
    diagPosMin:     B    # Defines minimum positively-sloped diagonal (di)
    diagPosMax:     B    # Defines maximum positively-sloped diagonal (da)
"""

class _Object() :
    pass

class _Dict(dict) :
    pass

class table_G__l_a_t(DefaultTable.DefaultTable):
    '''
    Support Graphite Glat tables
    '''

    def __init__(self, tag=None):
        DefaultTable.DefaultTable.__init__(self, tag)
        self.scheme = 0

    def decompile(self, data, ttFont):
        sstruct.unpack2(Glat_format_0, data, self)
        if self.version <= 1.9:
            decoder = partial(self.decompileAttributes12,fmt=Glat_format_1_entry)
        elif self.version <= 2.9:   
            decoder = partial(self.decompileAttributes12,fmt=Glat_format_23_entry)
        elif self.version >= 3.0:
            (data, self.scheme) = grUtils.decompress(data)
            sstruct.unpack2(Glat_format_3, data, self)
            self.hasOctaboxes = (self.compression & 1) == 1
            decoder = self.decompileAttributes3
        
        gloc = ttFont['Gloc']
        self.attributes = {}
        count = 0
        for s,e in zip(gloc,gloc[1:]):
            self.attributes[ttFont.getGlyphName(count)] = decoder(data[s:e])
            count += 1
    
    def decompileAttributes12(self, data, fmt):
        attributes = _Dict()
        while len(data) > 3:
            e, data = sstruct.unpack2(fmt, data, _Object())
            keys = range(e.attNum, e.attNum+e.num)
            if len(data) >= 2 * e.num :
                vals = struct.unpack_from(('>%dh' % e.num), data)
                attributes.update(zip(keys,vals))
                data = data[2*e.num:]
        return attributes

    def decompileAttributes3(self, data):
        if self.hasOctaboxes:
            o, data = sstruct.unpack2(Glat_format_3_octabox_metrics, data, _Object())
            numsub = bin(o.subboxBitmap).count("1")
            o.subboxes = []
            for b in range(numsub):
                if len(data) >= 8 :
                    subbox, data = sstruct.unpack2(Glat_format_3_subbox_entry,
                                                    data, _Object())
                    o.subboxes.append(subbox)
        attrs = self.decompileAttributes12(data, Glat_format_23_entry)
        if self.hasOctaboxes:
            attrs.octabox = o
        return attrs

    def compile(self, ttFont):
        data = sstruct.pack(Glat_format_0, self)
        if self.version <= 1.9:
            encoder = partial(self.compileAttributes12, fmt=Glat_format_1_entry)
        elif self.version <= 2.9:
            encoder = partial(self.compileAttributes12, fmt=Glat_format_1_entry)
        elif self.version >= 3.0:
            self.compression = (self.scheme << 27) + (1 if self.hasOctaboxes else 0)
            data = sstruct.pack(Glat_format_3, self)
            encoder = self.compileAttributes3

        glocs = []
        for n in range(len(self.attributes)):
            glocs.append(len(data))
            data += encoder(self.attributes[ttFont.getGlyphName(n)])
        glocs.append(len(data))
        ttFont['Gloc'].set(glocs)

        if self.version >= 3.0:
            data = grUtils.compress(self.scheme, data)
        return data

    def compileAttributes12(self, attrs, fmt):
        data = []
        for e in grUtils.entries(attrs):
            data.extend(sstruct.pack(fmt, {'attNum' : e[0], 'num' : e[1]}))
            data.extend(struct.pack(('>%dh' % len(e[2])), *e[2]))
        return "".join(data)
    
    def compileAttributes3(self, attrs):
        if self.hasOctaboxes:
            o = attrs.octabox
            data = sstruct.pack(Glat_format_3_octabox_metrics, o)
            numsub = bin(o.subboxBitmap).count("1")
            for b in range(numsub) :
                data += sstruct.pack(Glat_format_3_subbox_entry, o.subboxes[b])
        else:
            data = ""
        return data + self.compileAttributes12(attrs, Glat_format_23_entry)

    def toXML(self, writer, ttFont):
        writer.simpletag('version', version=self.version, compressionScheme=self.scheme)
        writer.newline()
        for n, a in sorted(self.attributes.items(), key=lambda x:ttFont.getGlyphID(x[0])):
            writer.begintag('glyph', name=n)
            writer.newline()
            if hasattr(a, 'octabox'):
                o = a.octabox
                formatstring, names, fixes = sstruct.getformat(Glat_format_3_octabox_metrics)
                vals = {}
                for k in names:
                    if k == 'subboxBitmap': continue
                    vals[k] = "{:.3f}%".format(getattr(o, k) * 100. / 256)
                vals['bitmap'] = "{:0X}".format(o.subboxBitmap)
                writer.begintag('octaboxes', **vals)
                writer.newline()
                formatstring, names, fixes = sstruct.getformat(Glat_format_3_subbox_entry)
                for s in o.subboxes:
                    vals = {}
                    for k in names:
                        vals[k] = "{:.3f}%".format(getattr(s, k) * 100. / 256)
                    writer.simpletag('octabox', **vals)
                    writer.newline()
                writer.endtag('octaboxes')
                writer.newline()
            for k, v in sorted(a.items()):
                writer.simpletag('attribute', index=k, value=v)
                writer.newline()
            writer.endtag('glyph')
            writer.newline()

    def fromXML(self, name, attrs, content, ttFont):
        if name == 'version' :
            self.version = float(safeEval(attrs['version']))
        if name != 'glyph' : return
        if not hasattr(self, 'attributes'):
            self.attributes = {}
        gname = attrs['name']
        attributes = _Dict()
        for element in content:
            if not isinstance(element, tuple): continue
            tag, attrs, subcontent = element
            if tag == 'attribute' :
                k = int(safeEval(attrs['index']))
                v = int(safeEval(attrs['value']))
                attributes[k]=v
            elif tag == 'octaboxes':
                self.hasOctaboxes = True
                o = _Object()
                o.subboxBitmap = int(attrs['bitmap'], 16)
                o.subboxes = []
                del attrs['bitmap']
                for k, v in attrs.items():
                    setattr(o, k, int(float(v[:-1]) * 256. / 100. + 0.5))
                for element in subcontent:
                    if not isinstance(element, tuple): continue
                    (tag, attrs, subcontent) = element
                    so = _Object()
                    for k, v in attrs.items():
                        setattr(so, k, int(float(v[:-1]) * 256. / 100. + 0.5))
                    o.subboxes.append(so)
                attributes.octabox = o
        self.attributes[gname] = attributes
