from __future__ import print_function, division, absolute_import
from fontTools.misc.py23 import *
from fontTools.pens.pointInsidePen import PointInsidePen
import unittest


class PointInsidePenTest(unittest.TestCase):
    def test_line(self):
        def draw_triangles(pen):
            pen.moveTo((0,0)); pen.lineTo((10,5)); pen.lineTo((10,0))
            pen.moveTo((9,1)); pen.lineTo((4,1)); pen.lineTo((9,4))
            pen.closePath()

        self.assertEqual(
            " *********"
            "   **    *"
            "     **  *"
            "       * *"
            "         *",
            self.render(draw_triangles, even_odd=True))

        self.assertEqual(
            " *********"
            "   *******"
            "     *****"
            "       ***"
            "         *",
            self.render(draw_triangles, even_odd=False))

    def test_curve(self):
        def draw_curves(pen):
            pen.moveTo((0,0)); pen.curveTo((9,1), (9,4), (0,5))
            pen.moveTo((10,5)); pen.curveTo((1,4), (1,1), (10,0))
            pen.closePath()

        self.assertEqual(
            "***    ***"
            "****  ****"
            "***    ***"
            "****  ****"
            "***    ***",
            self.render(draw_curves, even_odd=True))

        self.assertEqual(
            "***    ***"
            "**********"
            "**********"
            "**********"
            "***    ***",
            self.render(draw_curves, even_odd=False))

    def test_qCurve(self):
        def draw_qCurves(pen):
            pen.moveTo((0,0)); pen.qCurveTo((15,2), (0,5))
            pen.moveTo((10,5)); pen.qCurveTo((-5,3), (10,0))
            pen.closePath()

        self.assertEqual(
            "***     **"
            "****   ***"
            "***    ***"
            "***   ****"
            "**     ***",
            self.render(draw_qCurves, even_odd=True))

        self.assertEqual(
            "***     **"
            "**********"
            "**********"
            "**********"
            "**     ***",
            self.render(draw_qCurves, even_odd=False))

    @staticmethod
    def render(draw_function, even_odd):
        result = BytesIO()
        for y in range(5):
            for x in range(10):
                pen = PointInsidePen(None, (x + 0.5, y + 0.5), even_odd)
                draw_function(pen)
                if pen.getResult():
                    result.write(b"*")
                else:
                    result.write(b" ")
        return tounicode(result.getvalue())


    def test_contour_no_solutions(self):
        def draw_contour(pen):
            pen.moveTo( (969, 230) )
            pen.curveTo( (825, 348) , (715, 184) , (614, 202) )
            pen.lineTo( (614, 160) )
            pen.lineTo( (969, 160) )
            pen.closePath()

        piPen = PointInsidePen(None, (750, 295)) # this point is outside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 0)
        self.assertEqual(piPen.getResult(), False)

        piPen = PointInsidePen(None, (835, 190)) # this point is inside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 1)
        self.assertEqual(piPen.getResult(), True)

    def test_contour_square_closed(self):
        def draw_contour(pen):
            pen.moveTo( (100, 100) )
            pen.lineTo( (-100, 100) )
            pen.lineTo( (-100, -100) )
            pen.lineTo( (100, -100) )
            pen.closePath()

        piPen = PointInsidePen(None, (0, 0)) # this point is inside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 1)
        self.assertEqual(piPen.getResult(), True)

    def test_contour_square_opened(self):
        def draw_contour(pen):
            pen.moveTo( (100, 100) )
            pen.lineTo( (-100, 100) )
            pen.lineTo( (-100, -100) )
            pen.lineTo( (100, -100) )
            # contour not explicitly closed

        piPen = PointInsidePen(None, (0, 0)) # this point is inside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 1)
        self.assertEqual(piPen.getResult(), True)

    def test_contour_circle(self):
        def draw_contour(pen):
            pen.moveTo( (0, 100) )
            pen.curveTo( (-55, 100) , (-100, 55) , (-100, 0) )
            pen.curveTo( (-100, -55) , (-55, -100) , (0, -100) )
            pen.curveTo( (55, -100) , (100, -55) , (100, 0) )
            pen.curveTo( (100, 55) , (55, 100) , (0, 100) )

        piPen = PointInsidePen(None, (50, 50)) # this point is inside
        draw_contour(piPen)
        self.assertEqual(piPen.getResult(), True)

        piPen = PointInsidePen(None, (50, -50)) # this point is inside
        draw_contour(piPen)
        self.assertEqual(piPen.getResult(), True)

    def test_contour_diamond(self):
        def draw_contour(pen):
            pen.moveTo( (0, 100) )
            pen.lineTo( (100, 0) )
            pen.lineTo( (0, -100) )
            pen.lineTo( (-100, 0) )
            pen.closePath()

        piPen = PointInsidePen(None, (-200, 0)) # this point is outside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 0)

        piPen = PointInsidePen(None, (-200, 100)) # this point is outside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 0)

        piPen = PointInsidePen(None, (-200, -100)) # this point is outside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 0)

        piPen = PointInsidePen(None, (-200, 50)) # this point is outside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 0)

    def test_contour_integers(self):
        def draw_contour(pen):
            pen.moveTo( (728, 697) )
            pen.lineTo( (504, 699) )
            pen.curveTo( (487, 719) , (508, 783) , (556, 783) )
            pen.lineTo( (718, 783) )
            pen.curveTo( (739, 783) , (749, 712) , (728, 697) )
            pen.closePath()

        piPen = PointInsidePen(None, (416, 783)) # this point is outside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 0)

    def test_contour_decimals(self):
        def draw_contour(pen):
            pen.moveTo( (727.546875, 697.0) )
            pen.lineTo( (504.375, 698.515625) )
            pen.curveTo( (487.328125, 719.359375), (507.84375, 783.140625), (555.796875, 783.140625) )
            pen.lineTo( (717.96875, 783.140625) )
            pen.curveTo( (738.890625, 783.140625), (748.796875, 711.5), (727.546875, 697.0) )
            pen.closePath()

        piPen = PointInsidePen(None, (416.625, 783.140625)) # this point is outside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 0)

    def test_contour2_integers(self):
        def draw_contour(pen):
            pen.moveTo( (51, 22) )
            pen.lineTo( (51, 74) )
            pen.lineTo( (83, 50) )
            pen.curveTo( (83, 49) , (82, 48) , (82, 47) )
            pen.closePath()

        piPen = PointInsidePen(None, (21, 50)) # this point is outside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 0)

    def test_contour2_decimals(self):
        def draw_contour(pen):
            pen.moveTo( (51.25, 21.859375) )
            pen.lineTo( (51.25, 73.828125) )
            pen.lineTo( (82.5, 50.0) )
            pen.curveTo( (82.5, 49.09375) , (82.265625, 48.265625) , (82.234375, 47.375) )
            pen.closePath()

        piPen = PointInsidePen(None, (21.25, 50.0)) # this point is outside
        draw_contour(piPen)
        self.assertEqual(piPen.getWinding(), 0)

if __name__ == "__main__":
    import sys
    sys.exit(unittest.main())

