/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------

Copyright (c) 2006-2017, assimp team

All rights reserved.

Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:

* Redistributions of source code must retain the above
  copyright notice, this list of conditions and the
  following disclaimer.

* Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the
  following disclaimer in the documentation and/or other
  materials provided with the distribution.

* Neither the name of the assimp team, nor the names of its
  contributors may be used to endorse or promote products
  derived from this software without specific prior
  written permission of the assimp team.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

----------------------------------------------------------------------
*/

/// @file ProcessHelper.cpp
/** Implement shared utility functions for postprocessing steps */


#include "ProcessHelper.h"


#include <limits>

namespace Assimp {

// -------------------------------------------------------------------------------
void ConvertListToStrings(const std::string& in, std::list<std::string>& out)
{
    const char* s = in.c_str();
    while (*s) {
        SkipSpacesAndLineEnd(&s);
        if (*s == '\'') {
            const char* base = ++s;
            while (*s != '\'') {
                ++s;
                if (*s == '\0') {
                    DefaultLogger::get()->error("ConvertListToString: String list is ill-formatted");
                    return;
                }
            }
            out.push_back(std::string(base,(size_t)(s-base)));
            ++s;
        }
        else {
            out.push_back(GetNextToken(s));
        }
    }
}

// -------------------------------------------------------------------------------
void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max,
    const aiMatrix4x4& m)
{
    min = aiVector3D ( ai_real( 10e10 ), ai_real( 10e10 ), ai_real( 10e10 ) );
    max = aiVector3D ( ai_real( -10e10 ), ai_real( -10e10 ), ai_real( -10e10 ) );
    for (unsigned int i = 0;i < mesh->mNumVertices;++i)
    {
        const aiVector3D v = m * mesh->mVertices[i];
        min = std::min(v,min);
        max = std::max(v,max);
    }
}

// -------------------------------------------------------------------------------
void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max)
{
    ArrayBounds(mesh->mVertices,mesh->mNumVertices, min,max);
    out = min + (max-min)*(ai_real)0.5;
}

// -------------------------------------------------------------------------------
void FindSceneCenter (aiScene* scene, aiVector3D& out, aiVector3D& min, aiVector3D& max) {
    if ( NULL == scene ) {
        return;
    }

    if ( 0 == scene->mNumMeshes ) {
        return;
    }
    FindMeshCenter(scene->mMeshes[0], out, min, max);
    for (unsigned int i = 1; i < scene->mNumMeshes; ++i) {
        aiVector3D tout, tmin, tmax;
        FindMeshCenter(scene->mMeshes[i], tout, tmin, tmax);
        if (min[0] > tmin[0]) min[0] = tmin[0];
        if (min[1] > tmin[1]) min[1] = tmin[1];
        if (min[2] > tmin[2]) min[2] = tmin[2];
        if (max[0] < tmax[0]) max[0] = tmax[0];
        if (max[1] < tmax[1]) max[1] = tmax[1];
        if (max[2] < tmax[2]) max[2] = tmax[2];
    }
    out = min + (max-min)*(ai_real)0.5;
}


// -------------------------------------------------------------------------------
void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min,
    aiVector3D& max, const aiMatrix4x4& m)
{
    FindAABBTransformed(mesh,min,max,m);
    out = min + (max-min)*(ai_real)0.5;
}

// -------------------------------------------------------------------------------
void FindMeshCenter (aiMesh* mesh, aiVector3D& out)
{
    aiVector3D min,max;
    FindMeshCenter(mesh,out,min,max);
}

// -------------------------------------------------------------------------------
void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out,
    const aiMatrix4x4& m)
{
    aiVector3D min,max;
    FindMeshCenterTransformed(mesh,out,min,max,m);
}

// -------------------------------------------------------------------------------
ai_real ComputePositionEpsilon(const aiMesh* pMesh)
{
    const ai_real epsilon = ai_real( 1e-4 );

    // calculate the position bounds so we have a reliable epsilon to check position differences against
    aiVector3D minVec, maxVec;
    ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,minVec,maxVec);
    return (maxVec - minVec).Length() * epsilon;
}

// -------------------------------------------------------------------------------
ai_real ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num)
{
    ai_assert( NULL != pMeshes );

    const ai_real epsilon = ai_real( 1e-4 );

    // calculate the position bounds so we have a reliable epsilon to check position differences against
    aiVector3D minVec, maxVec, mi, ma;
    MinMaxChooser<aiVector3D>()(minVec,maxVec);

    for (size_t a = 0; a < num; ++a) {
        const aiMesh* pMesh = pMeshes[a];
        ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,mi,ma);

        minVec = std::min(minVec,mi);
        maxVec = std::max(maxVec,ma);
    }
    return (maxVec - minVec).Length() * epsilon;
}


// -------------------------------------------------------------------------------
unsigned int GetMeshVFormatUnique(const aiMesh* pcMesh)
{
    ai_assert(NULL != pcMesh);

    // FIX: the hash may never be 0. Otherwise a comparison against
    // nullptr could be successful
    unsigned int iRet = 1;

    // normals
    if (pcMesh->HasNormals())iRet |= 0x2;
    // tangents and bitangents
    if (pcMesh->HasTangentsAndBitangents())iRet |= 0x4;

#ifdef BOOST_STATIC_ASSERT
    BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_COLOR_SETS);
    BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS);
#endif

    // texture coordinates
    unsigned int p = 0;
    while (pcMesh->HasTextureCoords(p))
    {
        iRet |= (0x100 << p);
        if (3 == pcMesh->mNumUVComponents[p])
            iRet |= (0x10000 << p);

        ++p;
    }
    // vertex colors
    p = 0;
    while (pcMesh->HasVertexColors(p))iRet |= (0x1000000 << p++);
    return iRet;
}

// -------------------------------------------------------------------------------
VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh)
{
    if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) {
        return NULL;
    }

    VertexWeightTable* avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
    for (unsigned int i = 0; i < pMesh->mNumBones;++i)  {

        aiBone* bone = pMesh->mBones[i];
        for (unsigned int a = 0; a < bone->mNumWeights;++a) {
            const aiVertexWeight& weight = bone->mWeights[a];
            avPerVertexWeights[weight.mVertexId].push_back( std::pair<unsigned int,float>(i,weight.mWeight) );
        }
    }
    return avPerVertexWeights;
}


// -------------------------------------------------------------------------------
const char* TextureTypeToString(aiTextureType in)
{
    switch (in)
    {
    case aiTextureType_NONE:
        return "n/a";
    case aiTextureType_DIFFUSE:
        return "Diffuse";
    case aiTextureType_SPECULAR:
        return "Specular";
    case aiTextureType_AMBIENT:
        return "Ambient";
    case aiTextureType_EMISSIVE:
        return "Emissive";
    case aiTextureType_OPACITY:
        return "Opacity";
    case aiTextureType_NORMALS:
        return "Normals";
    case aiTextureType_HEIGHT:
        return "Height";
    case aiTextureType_SHININESS:
        return "Shininess";
    case aiTextureType_DISPLACEMENT:
        return "Displacement";
    case aiTextureType_LIGHTMAP:
        return "Lightmap";
    case aiTextureType_REFLECTION:
        return "Reflection";
    case aiTextureType_UNKNOWN:
        return "Unknown";
    default:
        break;
    }

    ai_assert(false);
    return  "BUG";
}

// -------------------------------------------------------------------------------
const char* MappingTypeToString(aiTextureMapping in)
{
    switch (in)
    {
    case aiTextureMapping_UV:
        return "UV";
    case aiTextureMapping_BOX:
        return "Box";
    case aiTextureMapping_SPHERE:
        return "Sphere";
    case aiTextureMapping_CYLINDER:
        return "Cylinder";
    case aiTextureMapping_PLANE:
        return "Plane";
    case aiTextureMapping_OTHER:
        return "Other";
    default:
        break;
    }

    ai_assert(false);
    return  "BUG";
}


// -------------------------------------------------------------------------------
aiMesh* MakeSubmesh(const aiMesh *pMesh, const std::vector<unsigned int> &subMeshFaces, unsigned int subFlags)
{
    aiMesh *oMesh = new aiMesh();
    std::vector<unsigned int> vMap(pMesh->mNumVertices,UINT_MAX);

    size_t numSubVerts = 0;
    size_t numSubFaces = subMeshFaces.size();

    for(unsigned int i=0;i<numSubFaces;i++) {
        const aiFace &f = pMesh->mFaces[subMeshFaces[i]];

        for(unsigned int j=0;j<f.mNumIndices;j++)   {
            if(vMap[f.mIndices[j]]==UINT_MAX)   {
                vMap[f.mIndices[j]] = static_cast<unsigned int>(numSubVerts++);
            }
        }
    }

    oMesh->mName = pMesh->mName;

    oMesh->mMaterialIndex = pMesh->mMaterialIndex;
    oMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes;

    // create all the arrays for this mesh if the old mesh contained them

    oMesh->mNumFaces = static_cast<unsigned int>(subMeshFaces.size());
    oMesh->mNumVertices = static_cast<unsigned int>(numSubVerts);
    oMesh->mVertices = new aiVector3D[numSubVerts];
    if( pMesh->HasNormals() ) {
        oMesh->mNormals = new aiVector3D[numSubVerts];
    }

    if( pMesh->HasTangentsAndBitangents() ) {
        oMesh->mTangents = new aiVector3D[numSubVerts];
        oMesh->mBitangents = new aiVector3D[numSubVerts];
    }

    for( size_t a = 0;  pMesh->HasTextureCoords(static_cast<unsigned int>(a)) ; ++a ) {
        oMesh->mTextureCoords[a] = new aiVector3D[numSubVerts];
        oMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
    }

    for( size_t a = 0; pMesh->HasVertexColors( static_cast<unsigned int>(a)); ++a )    {
        oMesh->mColors[a] = new aiColor4D[numSubVerts];
    }

    // and copy over the data, generating faces with linear indices along the way
    oMesh->mFaces = new aiFace[numSubFaces];

    for(unsigned int a = 0; a < numSubFaces; ++a )  {

        const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
        aiFace& dstFace = oMesh->mFaces[a];
        dstFace.mNumIndices = srcFace.mNumIndices;
        dstFace.mIndices = new unsigned int[dstFace.mNumIndices];

        // accumulate linearly all the vertices of the source face
        for( size_t b = 0; b < dstFace.mNumIndices; ++b )   {
            dstFace.mIndices[b] = vMap[srcFace.mIndices[b]];
        }
    }

    for(unsigned int srcIndex = 0; srcIndex < pMesh->mNumVertices; ++srcIndex ) {
        unsigned int nvi = vMap[srcIndex];
        if(nvi==UINT_MAX) {
            continue;
        }

        oMesh->mVertices[nvi] = pMesh->mVertices[srcIndex];
        if( pMesh->HasNormals() ) {
            oMesh->mNormals[nvi] = pMesh->mNormals[srcIndex];
        }

        if( pMesh->HasTangentsAndBitangents() ) {
            oMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
            oMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
        }
        for( size_t c = 0, cc = pMesh->GetNumUVChannels(); c < cc; ++c )    {
                oMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
        }
        for( size_t c = 0, cc = pMesh->GetNumColorChannels(); c < cc; ++c ) {
            oMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
        }
    }

    if(~subFlags&AI_SUBMESH_FLAGS_SANS_BONES)   {
        std::vector<unsigned int> subBones(pMesh->mNumBones,0);

        for(unsigned int a=0;a<pMesh->mNumBones;++a)    {
            const aiBone* bone = pMesh->mBones[a];

            for(unsigned int b=0;b<bone->mNumWeights;b++)   {
                unsigned int v = vMap[bone->mWeights[b].mVertexId];

                if(v!=UINT_MAX) {
                    subBones[a]++;
                }
            }
        }

        for(unsigned int a=0;a<pMesh->mNumBones;++a)    {
            if(subBones[a]>0) {
                oMesh->mNumBones++;
            }
        }

        if(oMesh->mNumBones) {
            oMesh->mBones = new aiBone*[oMesh->mNumBones]();
            unsigned int nbParanoia = oMesh->mNumBones;

            oMesh->mNumBones = 0; //rewind

            for(unsigned int a=0;a<pMesh->mNumBones;++a)    {
                if(subBones[a]==0) {
                    continue;
                }
                aiBone *newBone = new aiBone;
                oMesh->mBones[oMesh->mNumBones++] = newBone;

                const aiBone* bone = pMesh->mBones[a];

                newBone->mName = bone->mName;
                newBone->mOffsetMatrix = bone->mOffsetMatrix;
                newBone->mWeights = new aiVertexWeight[subBones[a]];

                for(unsigned int b=0;b<bone->mNumWeights;b++)   {
                    const unsigned int v = vMap[bone->mWeights[b].mVertexId];

                    if(v!=UINT_MAX) {
                        aiVertexWeight w(v,bone->mWeights[b].mWeight);
                        newBone->mWeights[newBone->mNumWeights++] = w;
                    }
                }
            }

            ai_assert(nbParanoia==oMesh->mNumBones);
            (void)nbParanoia; // remove compiler warning on release build
        }
    }

    return oMesh;
}

} // namespace Assimp
