from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from array import array
from fontTools.pens.basePen import LoggingPen
from fontTools.pens.transformPen import TransformPen
from fontTools.ttLib.tables import ttProgram
from fontTools.ttLib.tables._g_l_y_f import Glyph
from fontTools.ttLib.tables._g_l_y_f import GlyphComponent
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates


__all__ = ["TTGlyphPen"]


# the max value that can still fit in an F2Dot14:
# 1.99993896484375
MAX_F2DOT14 = 0x7FFF / (1 << 14)


class TTGlyphPen(LoggingPen):
    """Pen used for drawing to a TrueType glyph.

    If `handleOverflowingTransforms` is True, the components' transform values
    are checked that they don't overflow the limits of a F2Dot14 number:
    -2.0 <= v < +2.0. If any transform value exceeds these, the composite
    glyph is decomposed.
    An exception to this rule is done for values that are very close to +2.0
    (both for consistency with the -2.0 case, and for the relative frequency
    these occur in real fonts). When almost +2.0 values occur (and all other
    values are within the range -2.0 <= x <= +2.0), they are clamped to the
    maximum positive value that can still be encoded as an F2Dot14: i.e.
    1.99993896484375.
    If False, no check is done and all components are translated unmodified
    into the glyf table, followed by an inevitable `struct.error` once an
    attempt is made to compile them.
    """

    def __init__(self, glyphSet, handleOverflowingTransforms=True):
        self.glyphSet = glyphSet
        self.handleOverflowingTransforms = handleOverflowingTransforms
        self.init()

    def init(self):
        self.points = []
        self.endPts = []
        self.types = []
        self.components = []

    def _addPoint(self, pt, onCurve):
        self.points.append(pt)
        self.types.append(onCurve)

    def _popPoint(self):
        self.points.pop()
        self.types.pop()

    def _isClosed(self):
        return (
            (not self.points) or
            (self.endPts and self.endPts[-1] == len(self.points) - 1))

    def lineTo(self, pt):
        self._addPoint(pt, 1)

    def moveTo(self, pt):
        assert self._isClosed(), '"move"-type point must begin a new contour.'
        self._addPoint(pt, 1)

    def qCurveTo(self, *points):
        assert len(points) >= 1
        for pt in points[:-1]:
            self._addPoint(pt, 0)

        # last point is None if there are no on-curve points
        if points[-1] is not None:
            self._addPoint(points[-1], 1)

    def closePath(self):
        endPt = len(self.points) - 1

        # ignore anchors (one-point paths)
        if endPt == 0 or (self.endPts and endPt == self.endPts[-1] + 1):
            self._popPoint()
            return

        # if first and last point on this path are the same, remove last
        startPt = 0
        if self.endPts:
            startPt = self.endPts[-1] + 1
        if self.points[startPt] == self.points[endPt]:
            self._popPoint()
            endPt -= 1

        self.endPts.append(endPt)

    def endPath(self):
        # TrueType contours are always "closed"
        self.closePath()

    def addComponent(self, glyphName, transformation):
        self.components.append((glyphName, transformation))

    def _buildComponents(self, componentFlags):
        if self.handleOverflowingTransforms:
            # we can't encode transform values > 2 or < -2 in F2Dot14,
            # so we must decompose the glyph if any transform exceeds these
            overflowing = any(s > 2 or s < -2
                              for (glyphName, transformation) in self.components
                              for s in transformation[:4])
        components = []
        for glyphName, transformation in self.components:
            if glyphName not in self.glyphSet:
                self.log.warning(
                    "skipped non-existing component '%s'", glyphName
                )
                continue
            if (self.points or
                    (self.handleOverflowingTransforms and overflowing)):
                # can't have both coordinates and components, so decompose
                tpen = TransformPen(self, transformation)
                self.glyphSet[glyphName].draw(tpen)
                continue

            component = GlyphComponent()
            component.glyphName = glyphName
            component.x, component.y = transformation[4:]
            transformation = transformation[:4]
            if transformation != (1, 0, 0, 1):
                if (self.handleOverflowingTransforms and
                        any(MAX_F2DOT14 < s <= 2 for s in transformation)):
                    # clamp values ~= +2.0 so we can keep the component
                    transformation = tuple(MAX_F2DOT14 if MAX_F2DOT14 < s <= 2
                                           else s for s in transformation)
                component.transform = (transformation[:2], transformation[2:])
            component.flags = componentFlags
            components.append(component)
        return components

    def glyph(self, componentFlags=0x4):
        assert self._isClosed(), "Didn't close last contour."

        components = self._buildComponents(componentFlags)

        glyph = Glyph()
        glyph.coordinates = GlyphCoordinates(self.points)
        glyph.endPtsOfContours = self.endPts
        glyph.flags = array("B", self.types)
        self.init()

        if components:
            glyph.components = components
            glyph.numberOfContours = -1
        else:
            glyph.numberOfContours = len(glyph.endPtsOfContours)
            glyph.program = ttProgram.Program()
            glyph.program.fromBytecode(b"")

        return glyph
