"""
Functions to visualize the geometry elements and numbering and orientation of
their facets (edges and faces).

The standard geometry elements can be plotted by running::

  $ python sfepy/postprocess/plot_facets.py
"""
import numpy as nm
import matplotlib.pyplot as plt

from sfepy.linalg import (get_perpendiculars, normalize_vectors,
                          make_axis_rotation_matrix)
from sfepy.postprocess.plot_dofs import _get_axes, plot_mesh, plot_global_dofs

def plot_geometry(ax, gel, show=False):
    """
    Plot a geometry element as a wireframe.
    """
    ax = plot_mesh(ax, gel.coors, [gel.conn], gel.edges, show=False)
    ax = plot_global_dofs(ax, gel.coors, [gel.conn], show=show)

    return ax

def plot_edges(ax, gel, length, show=False):
    """
    Plot edges of a geometry element as numbered arrows.
    """
    dim = gel.dim
    ax = _get_axes(ax, dim)

    l2 = 0.5 * length
    for ii, edge in enumerate(gel.edges):
        cc = gel.coors[edge]
        centre = 0.5 * cc.sum(axis=0)

        vdir = (cc - centre)
        normalize_vectors(vdir)

        cc = l2 * vdir + centre
        draw_arrow(ax, cc, length=0.3*length, linewidth=3, color='b')

        if dim == 3:
            cx, cy, cz = centre
            ax.text(cx, cy, cz, ii,
                    color='b', fontsize=10, weight='light')

        else:
            cx, cy = centre
            ax.text(cx, cy, ii,
                    color='b', fontsize=10, weight='light')

    return ax

def plot_faces(ax, gel, radius, n_point, show=False):
    """
    Plot faces of a 3D geometry element as numbered oriented arcs. An arc
    centre corresponds to the first node of a face. It points from the first
    edge towards the last edge of the face.
    """
    dim = gel.dim
    ax = _get_axes(ax, dim)

    if dim < 3: return ax

    for ii, face in enumerate(gel.faces):
        cc = gel.coors[face]

        t1 = cc[1, :] - cc[0, :]
        t2 = cc[-1, :] - cc[0, :]
        n = nm.cross(t1, t2)

        nt1 = nm.linalg.norm(t1)
        nt2 = nm.linalg.norm(t2)
        angle = nm.arccos(nm.dot(t1, t2) / (nt1 * nt2))

        da = angle / (n_point - 1)

        mtx = 
make_axis_rotation_matrix(n, da)