import numpy as np

from ..constants import log


def load_assimp(file_obj, file_type=None):
    '''
    Use the assimp library to load a mesh, from a file object and type,
    or filename (if file_obj is a string)

    Assimp supports a huge number of mesh formats.

    Performance notes: in tests on binary STL pyassimp was ~10x
    slower than the native loader included in this package.
    This is probably due to their recursive prettifying of the data structure.

    Also, you need a very recent version of PyAssimp for this function to work
    (the commit was merged into the assimp github master on roughly 9/5/2014)
    '''

    def LPMesh_to_Trimesh(lp):
        colors = (np.reshape(lp.colors, (-1, 4))[:, 0:3] * 255).astype(np.int)
        return {'vertices': lp.vertices,
                'vertex_normals': lp.normals,
                'faces': lp.faces,
                'vertex_colors': colors}

    if not hasattr(file_obj, 'read'):
        # if there is no read attribute, we assume we've been passed a file
        # name
        file_type = (str(file_obj).split('.')[-1]).lower()
        file_obj = open(file_obj, 'rb')

    scene = pyassimp.load(file_obj, file_type=file_type)
    meshes = list(map(LPMesh_to_Trimesh, scene.meshes))
    pyassimp.release(scene)

    if len(meshes) == 1:
        return meshes[0]
    return meshes

_assimp_loaders = {}
try:
    import pyassimp
    if hasattr(pyassimp, 'available_formats'):
        _assimp_formats = [i.lower() for i in pyassimp.available_formats()]
    else:
        log.warning(
            'Older version of assimp detected, using hardcoded format list')
        _assimp_formats = ['dae', 'blend', '3ds', 'ase', 'obj',
                           'ifc', 'xgl', 'zgl', 'ply', 'lwo',
                           'lxo', 'x', 'ac', 'ms3d', 'cob', 'scn']
    _assimp_loaders.update(zip(_assimp_formats,
                               [load_assimp] * len(_assimp_formats)))
except:
    log.warning('pyassimp unavailable, using only native loaders')
