# Copyright 2016 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import collections
import math
import unittest
import os
import json

from fontTools.cu2qu import curve_to_quadratic, curves_to_quadratic


DATADIR = os.path.join(os.path.dirname(__file__), "data")

MAX_ERR = 5


class CurveToQuadraticTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        """Do the curve conversion ahead of time, and run tests on results."""
        with open(os.path.join(DATADIR, "curves.json"), "r") as fp:
            curves = json.load(fp)

        cls.single_splines = [curve_to_quadratic(c, MAX_ERR) for c in curves]
        cls.single_errors = [
            cls.curve_spline_dist(c, s) for c, s in zip(curves, cls.single_splines)
        ]

        curve_groups = [curves[i : i + 3] for i in range(0, 300, 3)]
        cls.compat_splines = [
            curves_to_quadratic(c, [MAX_ERR] * 3) for c in curve_groups
        ]
        cls.compat_errors = [
            [cls.curve_spline_dist(c, s) for c, s in zip(curve_group, splines)]
            for curve_group, splines in zip(curve_groups, cls.compat_splines)
        ]

        cls.results = []

    @classmethod
    def tearDownClass(cls):
        """Print stats from conversion, as determined during tests."""

        for tag, results in cls.results:
            print(
                "\n%s\n%s"
                % (
                    tag,
                    "\n".join(
                        "%s: %s (%d)" % (k, "#" * (v // 10 + 1), v)
                        for k, v in sorted(results.items())
                    ),
                )
            )

    def test_results_unchanged(self):
        """Tests that the results of conversion haven't changed since the time
        of this test's writing. Useful as a quick check whenever one modifies
        the conversion algorithm.
        """

        expected = {2: 6, 3: 26, 4: 82, 5: 232, 6: 360, 7: 266, 8: 28}

        results = collections.defaultdict(int)
        for spline in self.single_splines:
            n = len(spline) - 2
            results[n] += 1
        self.assertEqual(results, expected)
        self.results.append(("single spline lengths", results))

    def test_results_unchanged_multiple(self):
        """Test that conversion results are unchanged for multiple curves."""

        expected = {5: 11, 6: 35, 7: 49, 8: 5}

        results = collections.defaultdict(int)
        for splines in self.compat_splines:
            n = len(splines[0]) - 2
            for spline in splines[1:]:
                self.assertEqual(
                    len(spline) - 2, n, "Got incompatible conversion results"
                )
            results[n] += 1
        self.assertEqual(results, expected)
        self.results.append(("compatible spline lengths", results))

    def test_does_not_exceed_tolerance(self):
        """Test that conversion results do not exceed given error tolerance."""

        results = collections.defaultdict(int)
        for error in self.single_errors:
            results[round(error, 1)] += 1
            self.assertLessEqual(error, MAX_ERR)
        self.results.append(("single errors", results))

    def test_does_not_exceed_tolerance_multiple(self):
        """Test that error tolerance isn't exceeded for multiple curves."""

        results = collections.defaultdict(int)
        for errors in self.compat_errors:
            for error in errors:
                results[round(error, 1)] += 1
                self.assertLessEqual(error, MAX_ERR)
        self.results.append(("compatible errors", results))

    @classmethod
    def curve_spline_dist(cls, bezier, spline, total_steps=20):
        """Max distance between a bezier and quadratic spline at sampled points."""

        error = 0
        n = len(spline) - 2
        steps = total_steps // n
        for i in range(0, n - 1):
            p1 = spline[0] if i == 0 else p3
            p2 = spline[i + 1]
            if i < n - 1:
                p3 = cls.lerp(spline[i + 1], spline[i + 2], 0.5)
            else:
                p3 = spline[n + 2]
            segment = p1, p2, p3
            for j in range(steps):
                error = max(
                    error,
                    cls.dist(
                        cls.cubic_bezier_at(bezier, (j / steps + i) / n),
                        cls.quadratic_bezier_at(segment, j / steps),
                    ),
                )
        return error

    @classmethod
    def lerp(cls, p1, p2, t):
        (x1, y1), (x2, y2) = p1, p2
        return x1 + (x2 - x1) * t, y1 + (y2 - y1) * t

    @classmethod
    def dist(cls, p1, p2):
        (x1, y1), (x2, y2) = p1, p2
        return math.hypot(x1 - x2, y1 - y2)

    @classmethod
    def quadratic_bezier_at(cls, b, t):
        (x1, y1), (x2, y2), (x3, y3) = b
        _t = 1 - t
        t2 = t * t
        _t2 = _t * _t
        _2_t_t = 2 * t * _t
        return (_t2 * x1 + _2_t_t * x2 + t2 * x3, _t2 * y1 + _2_t_t * y2 + t2 * y3)

    @classmethod
    def cubic_bezier_at(cls, b, t):
        (x1, y1), (x2, y2), (x3, y3), (x4, y4) = b
        _t = 1 - t
        t2 = t * t
        _t2 = _t * _t
        t3 = t * t2
        _t3 = _t * _t2
        _3_t2_t = 3 * t2 * _t
        _3_t_t2 = 3 * t * _t2
        return (
            _t3 * x1 + _3_t_t2 * x2 + _3_t2_t * x3 + t3 * x4,
            _t3 * y1 + _3_t_t2 * y2 + _3_t2_t * y3 + t3 * y4,
        )


class AllQuadraticFalseTest(unittest.TestCase):
    def test_cubic(self):
        cubic = [(0, 0), (0, 1), (2, 1), (2, 0)]
        result = curve_to_quadratic(cubic, 0.1, all_quadratic=False)
        assert result == cubic

    def test_quadratic(self):
        cubic = [(0, 0), (2, 2), (4, 2), (6, 0)]
        result = curve_to_quadratic(cubic, 0.1, all_quadratic=False)
        quadratic = [(0, 0), (3, 3), (6, 0)]
        assert result == quadratic


if __name__ == "__main__":
    unittest.main()
