# Copyright (c) 2012-2018 Manfred Moitzi
# License: MIT License
import pytest
from math import isclose
from ezdxf.math import open_uniform_bspline


DEFPOINTS = [
    (0.0, 0.0, 0.0),
    (10.0, 20.0, 20.0),
    (30.0, 10.0, 25.0),
    (40.0, 10.0, 25.0),
    (50.0, 0.0, 30.0),
]


def test_bsplineu_points():
    curve = open_uniform_bspline(DEFPOINTS, order=3)
    points = list(curve.approximate(40))

    for rpoint, epoint in zip(points, iter_points(DBSPLINEU, 0)):
        epx, epy, epz = epoint
        rpx, rpy, rpz = rpoint
        assert isclose(epx, rpx)
        assert isclose(epy, rpy)
        assert isclose(epz, rpz)


@pytest.fixture
def dbsplineu():
    curve = open_uniform_bspline(DEFPOINTS, order=3)
    return list(curve.derivatives(curve.params(40)))


def iter_points(values, n):
    return (data[n] for data in values)


def iter_data(result, n):
    return zip(iter_points(result, n), iter_points(DBSPLINEU, n))


def test_dbsplineu_points(dbsplineu):
    for rpoint, epoint in iter_data(dbsplineu, 0):
        epx, epy, epz = epoint
        rpx, rpy, rpz = rpoint
        assert isclose(epx, rpx)
        assert isclose(epy, rpy)
        assert isclose(epz, rpz)


def test_dbsplineu_derivative_1(dbsplineu):
    for rpoint, epoint in iter_data(dbsplineu, 1):
        epx, epy, epz = epoint
        rpx, rpy, rpz = rpoint
        assert isclose(epx, rpx)
        assert isclose(epy, rpy)
        assert isclose(epz, rpz)


def test_dbsplineu_derivative_2(dbsplineu):
    for rpoint, epoint in iter_data(dbsplineu, 2):
        epx, epy, epz = epoint
        rpx, rpy, rpz = rpoint
        assert isclose(epx, rpx)
        assert isclose(epy, rpy)
        assert isclose(epz, rpz)


DBSPLINEU = [
    [[5.0, 10.0, 10.0], [10.0, 20.0, 20.0], [10.0, -30.0, -15.0]],
    [
        [5.778125000000002, 11.415625000000002, 11.457812500000003],
        [10.750000000000002, 17.749999999999993, 18.874999999999996],
        [10.0, -30.0, -15.0],
    ],
    [
        [6.612499999999999, 12.6625, 12.831249999999999],
        [11.5, 15.500000000000004, 17.75],
        [10.0, -30.0, -15.0],
    ],
    [
        [7.503125000000001, 13.740625000000001, 14.1203125],
        [12.25, 13.249999999999996, 16.625],
        [10.0, -30.0, -15.0],
    ],
    [
        [8.449999999999998, 14.649999999999999, 15.324999999999998],
        [12.999999999999998, 11.000000000000005, 15.500000000000004],
        [10.0, -30.0, -15.0],
    ],
    [
        [9.453125, 15.390625, 16.4453125],
        [13.75, 8.75, 14.375],
        [10.0, -30.0, -15.0],
    ],
    [
        [10.512500000000003, 15.962500000000002, 17.481250000000003],
        [14.500000000000002, 6.499999999999995, 13.249999999999996],
        [10.0, -30.0, -15.0],
    ],
    [
        [11.628124999999999, 16.365625, 18.4328125],
        [15.249999999999998, 4.250000000000003, 12.125000000000002],
        [10.0, -30.0, -15.0],
    ],
    [
        [12.8, 16.6, 19.3],
        [16.0, 1.9999999999999973, 10.999999999999998],
        [10.0, -30.0, -15.0],
    ],
    [
        [14.028125, 16.665625000000002, 20.0828125],
        [16.749999999999996, -0.24999999999999467, 9.875000000000004],
        [10.0, -30.0, -15.0],
    ],
    [[15.3125, 16.5625, 20.78125], [17.5, -2.5, 8.75], [10.0, -30.0, -15.0]],
    [
        [16.653125000000003, 16.290625, 21.395312500000003],
        [18.250000000000004, -4.750000000000005, 7.6249999999999964],
        [10.0, -30.0, -15.0],
    ],
    [
        [18.049999999999997, 15.85, 21.924999999999997],
        [19.0, -6.9999999999999964, 6.5],
        [10.0, -30.0, -15.0],
    ],
    [
        [19.503125, 15.240625, 22.3703125],
        [19.75, -9.250000000000004, 5.375],
        [10.0, -30.0, -15.0],
    ],
    [
        [20.9875, 14.5125, 22.74375],
        [19.5, -9.500000000000002, 4.749999999999999],
        [-10.0, 10.0, -5.0],
    ],
    [
        [22.421875, 13.828125, 23.0859375],
        [18.75, -8.75, 4.375],
        [-10.0, 10.0, -5.0],
    ],
    [
        [23.800000000000004, 13.2, 23.4],
        [18.0, -7.999999999999998, 3.999999999999999],
        [-10.0, 10.0, -5.0],
    ],
    [
        [25.121875, 12.628124999999999, 23.6859375],
        [17.25, -7.250000000000001, 3.625],
        [-10.0, 10.0, -5.0],
    ],
    [
        [26.387499999999996, 12.112500000000002, 23.943749999999998],
        [16.500000000000004, -6.5000000000000036, 3.2500000000000018],
        [-10.0, 10.0, -5.0],
    ],
    [
        [27.596874999999997, 11.653125000000001, 24.1734375],
        [15.750000000000002, -5.750000000000002, 2.8750000000000018],
        [-10.0, 10.0, -5.0],
    ],
    [[28.75, 11.25, 24.375], [15.0, -5.0, 2.5], [-10.0, 10.0, -5.0]],
    [
        [29.846875000000004, 10.903125, 24.548437500000002],
        [14.249999999999998, -4.249999999999998, 2.1249999999999982],
        [-10.0, 10.0, -5.0],
    ],
    [
        [30.887500000000003, 10.6125, 24.69375],
        [13.5, -3.500000000000001, 1.75],
        [-10.0, 10.0, -5.0],
    ],
    [
        [31.871874999999996, 10.378125, 24.810937499999998],
        [12.750000000000004, -2.7500000000000036, 1.3750000000000036],
        [-10.0, 10.0, -5.0],
    ],
    [
        [32.8, 10.2, 24.900000000000002],
        [12.0, -2.0000000000000018, 1.0000000000000036],
        [-10.0, 10.0, -5.0],
    ],
    [
        [33.671875, 10.078125, 24.9609375],
        [11.25, -1.25, 0.625],
        [-10.0, 10.0, -5.0],
    ],
    [
        [34.4875, 10.0125, 24.99375],
        [10.5, -0.4999999999999982, 0.25],
        [-10.0, 10.0, -5.0],
    ],
    [
        [35.25000000000001, 9.996875, 25.0015625],
        [10.0, -0.25000000000000355, 0.125],
        [0.0, -10.0, 5.0],
    ],
    [
        [36.0, 9.950000000000001, 25.025],
        [10.0, -0.9999999999999964, 0.5],
        [0.0, -10.0, 5.0],
    ],
    [
        [36.75, 9.846875, 25.076562499999998],
        [9.999999999999998, -1.7499999999999982, 0.8749999999999982],
        [0.0, -10.0, 5.0],
    ],
    [[37.5, 9.6875, 25.15625], [10.0, -2.5, 1.25], [0.0, -10.0, 5.0]],
    [
        [38.24999999999999, 9.471875000000002, 25.264062499999998],
        [10.0, -3.249999999999993, 1.6249999999999964],
        [0.0, -10.0, 5.0],
    ],
    [
        [39.00000000000001, 9.2, 25.400000000000006],
        [10.0, -4.0000000000000036, 2.0000000000000018],
        [0.0, -10.0, 5.0],
    ],
    [
        [39.75, 8.871875000000003, 25.5640625],
        [10.0, -4.7499999999999964, 2.3749999999999982],
        [0.0, -10.0, 5.0],
    ],
    [
        [40.5, 8.4875, 25.756249999999998],
        [10.0, -5.499999999999998, 2.7499999999999982],
        [0.0, -10.0, 5.0],
    ],
    [[41.25, 8.046875, 25.9765625], [10.0, -6.25, 3.125], [0.0, -10.0, 5.0]],
    [
        [41.99999999999999, 7.550000000000005, 26.224999999999998],
        [10.0, -6.999999999999993, 3.4999999999999964],
        [0.0, -10.0, 5.0],
    ],
    [
        [42.75000000000001, 6.9968749999999975, 26.5015625],
        [9.999999999999996, -7.7500000000000036, 3.8750000000000036],
        [0.0, -10.0, 5.0],
    ],
    [
        [43.5, 6.387500000000004, 26.80625],
        [10.0, -8.499999999999996, 4.2499999999999964],
        [0.0, -10.0, 5.0],
    ],
    [
        [44.25, 5.721875000000002, 27.1390625],
        [10.0, -9.249999999999998, 4.6249999999999964],
        [0.0, -10.0, 5.0],
    ],
    [[45.0, 5.0, 27.5], [10.0, -10.0, 5.0], [0.0, -10.0, 5.0]],
]
