/*
---------------------------------------------------------------------------
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 Implementation of the DeterminePTypeHelperProcess and
 *  SortByPTypeProcess post-process steps.
*/



// internal headers
#include "ProcessHelper.h"
#include "SortByPTypeProcess.h"
#include "Exceptional.h"

using namespace Assimp;

// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
SortByPTypeProcess::SortByPTypeProcess()
{
    configRemoveMeshes = 0;
}

// ------------------------------------------------------------------------------------------------
// Destructor, private as well
SortByPTypeProcess::~SortByPTypeProcess()
{
    // nothing to do here
}

// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool SortByPTypeProcess::IsActive( unsigned int pFlags) const
{
    return  (pFlags & aiProcess_SortByPType) != 0;
}

// ------------------------------------------------------------------------------------------------
void SortByPTypeProcess::SetupProperties(const Importer* pImp)
{
    configRemoveMeshes = pImp->GetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE,0);
}

// ------------------------------------------------------------------------------------------------
// Update changed meshes in all nodes
void UpdateNodes(const std::vector<unsigned int>& replaceMeshIndex, aiNode* node)
{
//  std::vector<unsigned int>::const_iterator it;

    if (node->mNumMeshes)
    {
        unsigned int newSize = 0;
        for (unsigned int m = 0; m< node->mNumMeshes; ++m)
        {
            unsigned int add = node->mMeshes[m]<<2;
            for (unsigned int i = 0; i < 4;++i)
            {
                if (UINT_MAX != replaceMeshIndex[add+i])++newSize;
            }
        }
        if (!newSize)
        {
            delete[] node->mMeshes;
            node->mNumMeshes = 0;
            node->mMeshes    = NULL;
        }
        else
        {
            // Try to reuse the old array if possible
            unsigned int* newMeshes = (newSize > node->mNumMeshes
                ? new unsigned int[newSize] : node->mMeshes);

            for (unsigned int m = 0; m< node->mNumMeshes; ++m)
            {
                unsigned int add = node->mMeshes[m]<<2;
                for (unsigned int i = 0; i < 4;++i)
                {
                    if (UINT_MAX != replaceMeshIndex[add+i])
                        *newMeshes++ = replaceMeshIndex[add+i];
                }
            }
            if (newSize > node->mNumMeshes)
                delete[] node->mMeshes;

            node->mMeshes = newMeshes-(node->mNumMeshes = newSize);
        }
    }

    // call all subnodes recursively
    for (unsigned int m = 0; m < node->mNumChildren; ++m)
        UpdateNodes(replaceMeshIndex,node->mChildren[m]);
}

// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void SortByPTypeProcess::Execute( aiScene* pScene)
{
    if (!pScene->mNumMeshes)
    {
        DefaultLogger::get()->debug("SortByPTypeProcess skipped, there are no meshes");
        return;
    }

    DefaultLogger::get()->debug("SortByPTypeProcess begin");

    unsigned int aiNumMeshesPerPType[4] = {0,0,0,0};

    std::vector<aiMesh*> outMeshes;
    outMeshes.reserve(pScene->mNumMeshes<<1u);

    bool bAnyChanges = false;

    std::vector<unsigned int> replaceMeshIndex(pScene->mNumMeshes*4,UINT_MAX);
    std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
    for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
    {
        aiMesh* const mesh = pScene->mMeshes[i];
        ai_assert(0 != mesh->mPrimitiveTypes);

        // if there's just one primitive type in the mesh there's nothing to do for us
        unsigned int num = 0;
        if (mesh->mPrimitiveTypes & aiPrimitiveType_POINT)
        {
            ++aiNumMeshesPerPType[0];
            ++num;
        }
        if (mesh->mPrimitiveTypes & aiPrimitiveType_LINE)
        {
            ++aiNumMeshesPerPType[1];
            ++num;
        }
        if (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE)
        {
            ++aiNumMeshesPerPType[2];
            ++num;
        }
        if (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)
        {
            ++aiNumMeshesPerPType[3];
            ++num;
        }

        if (1 == num)
        {
            if (!(configRemoveMeshes & mesh->mPrimitiveTypes))
            {
                *meshIdx = (unsigned int) outMeshes.size();
                outMeshes.push_back(mesh);
            }
            else bAnyChanges = true;

            meshIdx += 4;
            continue;
        }
        bAnyChanges = true;

        // reuse our current mesh arrays for the submesh
        // with the largest numer of primitives
        unsigned int aiNumPerPType[4] = {0,0,0,0};
        aiFace* pFirstFace = mesh->mFaces;
        aiFace* const pLastFace = pFirstFace + mesh->mNumFaces;

        unsigned int numPolyVerts = 0;
        for (;pFirstFace != pLastFace; ++pFirstFace)
        {
            if (pFirstFace->mNumIndices <= 3)
                ++aiNumPerPType[pFirstFace->mNumIndices-1];
            else
            {
                ++aiNumPerPType[3];
                numPolyVerts += pFirstFace-> mNumIndices;
            }
        }

        VertexWeightTable* avw = ComputeVertexBoneWeightTable(mesh);
        for (unsigned int real = 0; real < 4; ++real,++meshIdx)
        {
            if ( !aiNumPerPType[real] || configRemoveMeshes & (1u << real))
            {
                continue;
            }

            *meshIdx = (unsigned int) outMeshes.size();
            outMeshes.push_back(new aiMesh());
            aiMesh* out = outMeshes.back();

            // the name carries the adjacency information between the meshes
            out->mName = mesh->mName;

            // copy data members
            out->mPrimitiveTypes = 1u << real;
            out->mMaterialIndex = mesh->mMaterialIndex;

            // allocate output storage
            out->mNumFaces = aiNumPerPType[real];
            aiFace* outFaces = out->mFaces = new aiFace[out->mNumFaces];

            out->mNumVertices = (3 == real ? numPolyVerts : out->mNumFaces * (real+1));

            aiVector3D *vert(NULL), *nor(NULL), *tan(NULL), *bit(NULL);
            aiVector3D *uv   [AI_MAX_NUMBER_OF_TEXTURECOORDS];
            aiColor4D  *cols [AI_MAX_NUMBER_OF_COLOR_SETS];

            if (mesh->mVertices)
                vert = out->mVertices = new aiVector3D[out->mNumVertices];

            if (mesh->mNormals)
                nor  = out->mNormals  = new aiVector3D[out->mNumVertices];

            if (mesh->mTangents)
            {
                tan = out->mTangents   = new aiVector3D[out->mNumVertices];
                bit = out->mBitangents = new aiVector3D[out->mNumVertices];
            }

            for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
            {
                if (mesh->mTextureCoords[i])
                    uv[i] = out->mTextureCoords[i] = new aiVector3D[out->mNumVertices];
                else uv[i] = NULL;

                out->mNumUVComponents[i] = mesh->mNumUVComponents[i];
            }

            for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
            {
                if (mesh->mColors[i])
                    cols[i] = out->mColors[i] = new aiColor4D[out->mNumVertices];
                else cols[i] = NULL;
            }

            typedef std::vector< aiVertexWeight > TempBoneInfo;
            std::vector< TempBoneInfo > tempBones(mesh->mNumBones);

            // try to guess how much storage we'll need
            for (unsigned int q = 0; q < mesh->mNumBones;++q)
            {
                tempBones[q].reserve(mesh->mBones[q]->mNumWeights / (num-1));
            }

            unsigned int outIdx = 0;
            for (unsigned int m = 0; m < mesh->mNumFaces; ++m)
            {
                aiFace& in = mesh->mFaces[m];
                if ((real == 3  && in.mNumIndices <= 3) || (real != 3 && in.mNumIndices != real+1))
                {
                    continue;
                }

                outFaces->mNumIndices = in.mNumIndices;
                outFaces->mIndices    = in.mIndices;

                for (unsigned int q = 0; q < in.mNumIndices; ++q)
                {
                    unsigned int idx = in.mIndices[q];

                    // process all bones of this index
                    if (avw)
                    {
                        VertexWeightTable& tbl = avw[idx];
                        for (VertexWeightTable::const_iterator it = tbl.begin(), end = tbl.end();
                             it != end; ++it)
                        {
                            tempBones[ (*it).first ].push_back( aiVertexWeight(outIdx, (*it).second) );
                        }
                    }

                    if (vert)
                    {
                        *vert++ = mesh->mVertices[idx];
                        //mesh->mVertices[idx].x = get_qnan();
                    }
                    if (nor )*nor++  = mesh->mNormals[idx];
                    if (tan )
                    {
                        *tan++  = mesh->mTangents[idx];
                        *bit++  = mesh->mBitangents[idx];
                    }

                    for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp)
                    {
                        if (!uv[pp])break;
                        *uv[pp]++ = mesh->mTextureCoords[pp][idx];
                    }

                    for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp)
                    {
                        if (!cols[pp])break;
                        *cols[pp]++ = mesh->mColors[pp][idx];
                    }

                    in.mIndices[q] = outIdx++;
                }

                in.mIndices = NULL;
                ++outFaces;
            }
            ai_assert(outFaces == out->mFaces + out->mNumFaces);

            // now generate output bones
            for (unsigned int q = 0; q < mesh->mNumBones;++q)
                if (!tempBones[q].empty())++out->mNumBones;

            if (out->mNumBones)
            {
                out->mBones = new aiBone*[out->mNumBones];
                for (unsigned int q = 0, real = 0; q < mesh->mNumBones;++q)
                {
                    TempBoneInfo& in = tempBones[q];
                    if (in.empty())continue;

                    aiBone* srcBone = mesh->mBones[q];
                    aiBone* bone = out->mBones[real] = new aiBone();

                    bone->mName = srcBone->mName;
                    bone->mOffsetMatrix = srcBone->mOffsetMatrix;

                    bone->mNumWeights = (unsigned int)in.size();
                    bone->mWeights = new aiVertexWeight[bone->mNumWeights];

                    ::memcpy(bone->mWeights,&in[0],bone->mNumWeights*sizeof(aiVertexWeight));

                    ++real;
                }
            }
        }

        // delete the per-vertex bone weights table
        delete[] avw;

        // delete the input mesh
        delete mesh;

        // avoid invalid pointer
        pScene->mMeshes[i] = NULL;
    }

    if (outMeshes.empty())
    {
        // This should not occur
        throw DeadlyImportError("No meshes remaining");
    }

    // If we added at least one mesh process all nodes in the node
    // graph and update their respective mesh indices.
    if (bAnyChanges)
    {
        UpdateNodes(replaceMeshIndex,pScene->mRootNode);
    }

    if (outMeshes.size() != pScene->mNumMeshes)
    {
        delete[] pScene->mMeshes;
        pScene->mNumMeshes = (unsigned int)outMeshes.size();
        pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
    }
    ::memcpy(pScene->mMeshes,&outMeshes[0],pScene->mNumMeshes*sizeof(void*));

    if (!DefaultLogger::isNullLogger())
    {
        char buffer[1024];
        ::ai_snprintf(buffer,1024,"Points: %u%s, Lines: %u%s, Triangles: %u%s, Polygons: %u%s (Meshes, X = removed)",
            aiNumMeshesPerPType[0], ((configRemoveMeshes & aiPrimitiveType_POINT)     ? "X" : ""),
            aiNumMeshesPerPType[1], ((configRemoveMeshes & aiPrimitiveType_LINE)      ? "X" : ""),
            aiNumMeshesPerPType[2], ((configRemoveMeshes & aiPrimitiveType_TRIANGLE)  ? "X" : ""),
            aiNumMeshesPerPType[3], ((configRemoveMeshes & aiPrimitiveType_POLYGON)   ? "X" : ""));
        DefaultLogger::get()->info(buffer);
        DefaultLogger::get()->debug("SortByPTypeProcess finished");
    }
}

