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 .otBase import BaseTTXConverter
from . import DefaultTable
from . import grUtils
import struct

Feat_hdr_format='''
    >
    version:    16.16F
'''

class table_F__e_a_t(DefaultTable.DefaultTable):

    def __init__(self, tag=None):
        DefaultTable.DefaultTable.__init__(self, tag)
        self.features = {}

    def decompile(self, data, ttFont):
        (_, data) = sstruct.unpack2(Feat_hdr_format, data, self)
        numFeats, = struct.unpack('>H', data[:2])
        data = data[8:]
        allfeats = []
        maxsetting = 0
        for i in range(numFeats):
            if self.version >= 2.0:
                (fid, nums, _, offset, flags, lid) = struct.unpack(">LHHLHH",
                                                            data[16*i:16*(i+1)])
                offset = int((offset - 12 - 16 * numFeats) / 4)
            else:
                (fid, nums, offset, flags, lid) = struct.unpack(">HHLHH",
                                                            data[12*i:12*(i+1)])
                offset = int((offset - 12 - 12 * numFeats) / 4)
            allfeats.append((fid, nums, offset, flags, lid))
            maxsetting = max(maxsetting, offset + nums)
        data = data[16*numFeats:]
        allsettings = []
        for i in range(maxsetting):
            if len(data) >= 4 * (i + 1):
                (val, lid) = struct.unpack(">HH", data[4*i:4*(i+1)])
                allsettings.append((val, lid))
        for i,f in enumerate(allfeats):
            (fid, nums, offset, flags, lid) = f
            fobj = Feature()
            fobj.flags = flags
            fobj.label = lid
            self.features[grUtils.num2tag(fid)] = fobj
            fobj.settings = {}
            fobj.default = None
            fobj.index = i
            for i in range(offset, offset + nums):
                if i >= len(allsettings): continue
                (vid, vlid) = allsettings[i]
                fobj.settings[vid] = vlid
                if fobj.default is None:
                    fobj.default = vid

    def compile(self, ttFont):
        fdat = b""
        vdat = b""
        offset = 0
        for f, v in sorted(self.features.items(), key=lambda x:x[1].index):
            fnum = grUtils.tag2num(f)
            if self.version >= 2.0:
                fdat += struct.pack(">LHHLHH", grUtils.tag2num(f), len(v.settings),
                    0, offset * 4 + 12 + 16 * len(self.features), v.flags, v.label)
            elif fnum > 65535:      # self healing for alphabetic ids
                self.version = 2.0
                return self.compile(ttFont)
            else:
                fdat += struct.pack(">HHLHH", grUtils.tag2num(f), len(v.settings),
                    offset * 4 + 12 + 12 * len(self.features), v.flags, v.label)
            for s, l in sorted(v.settings.items(), key=lambda x:(-1, x[1]) if x[0] == v.default else x):
                vdat += struct.pack(">HH", s, l)
            offset += len(v.settings)
        hdr = sstruct.pack(Feat_hdr_format, self)
        return hdr + struct.pack('>HHL', len(self.features), 0, 0) + fdat + vdat

    def toXML(self, writer, ttFont):
        writer.simpletag('version', version=self.version)
        writer.newline()
        for f, v in sorted(self.features.items(), key=lambda x:x[1].index):
            writer.begintag('feature', fid=f, label=v.label, flags=v.flags,
                            default=(v.default if v.default else 0))
            writer.newline()
            for s, l in sorted(v.settings.items()):
                writer.simpletag('setting', value=s, label=l)
                writer.newline()
            writer.endtag('feature')
            writer.newline()

    def fromXML(self, name, attrs, content, ttFont):
        if name == 'version':
            self.version = float(safeEval(attrs['version']))
        elif name == 'feature':
            fid = attrs['fid']
            fobj = Feature()
            fobj.flags = int(safeEval(attrs['flags']))
            fobj.label = int(safeEval(attrs['label']))
            fobj.default = int(safeEval(attrs.get('default','0')))
            fobj.index = len(self.features)
            self.features[fid] = fobj
            fobj.settings = {}
            for element in content:
                if not isinstance(element, tuple): continue
                tag, a, c = element
                if tag == 'setting':
                    fobj.settings[int(safeEval(a['value']))] = int(safeEval(a['label']))

class Feature(object):
    pass

