import numpy as np
from menpo.shape import TriMesh


def utils_mesh():
    trilist = np.array([[0, 1, 2], [0, 2, 3]])
    points = np.array([[0, 0], [1, 0], [1, 1], [0, 1]])
    return TriMesh(points, trilist=trilist)


gt_edge_indices = np.array([[0, 1], [1, 2], [2, 0], [0, 2], [2, 3], [3, 0]])

gt_edge_vectors = np.array([[1, 0], [0, 1], [1, 1], [1, 1], [-1, 0], [0, 1]])

gt_unique_edge_vectors = np.array([[1, 0], [1, 1], [0, 1], [0, 1], [-1, 0]])

gt_edge_lengths = np.array([1.0, 1.0, 1.41421356, 1.41421356, 1.0, 1.0])

gt_unique_edge_lengths = np.array([1.0, 1.41421356, 1.0, 1.0, 1.0])

gt_tri_areas = np.array([0.5, 0.5])


def test_edge_indices():
    np.testing.assert_allclose(utils_mesh().edge_indices(), gt_edge_indices)


def test_edge_vectors():
    np.testing.assert_allclose(utils_mesh().edge_vectors(), gt_edge_vectors)


def test_unique_edge_vectors():
    np.testing.assert_allclose(
        utils_mesh().unique_edge_vectors(), gt_unique_edge_vectors
    )


def test_edge_lengths():
    assert np.allclose(utils_mesh().edge_lengths(), gt_edge_lengths)


def test_unique_edge_lengths():
    np.testing.assert_allclose(
        utils_mesh().unique_edge_lengths(), gt_unique_edge_lengths
    )


def test_tri_areas():
    np.testing.assert_allclose(utils_mesh().tri_areas(), gt_tri_areas)


def test_2d_trimesh_2d_positive_areas():
    t = TriMesh(
        np.array([[0, 0], [0, 1], [1, 1], [1, 0]], dtype=np.float),
        trilist=np.array([[0, 2, 3], [0, 2, 1]]),
    )
    assert np.all(t.tri_areas() > 0)


def test_mean_tri_area():
    assert np.isclose(utils_mesh().mean_tri_area(), 0.5)


def test_mean_edge_length():
    np.testing.assert_allclose(
        utils_mesh().mean_edge_length(), np.mean(gt_unique_edge_lengths)
    )


def test_mean_edge_length_not_unique():
    np.testing.assert_allclose(
        utils_mesh().mean_edge_length(unique=False), np.mean(gt_edge_lengths)
    )
