/*
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 A helper class that processes texture transformations */



#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>

#include "TextureTransform.h"
#include "StringUtils.h"

using namespace Assimp;

// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
TextureTransformStep::TextureTransformStep() :
    configFlags()
{
    // nothing to do here
}

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

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

// ------------------------------------------------------------------------------------------------
// Setup properties
void TextureTransformStep::SetupProperties(const Importer* pImp)
{
    configFlags = pImp->GetPropertyInteger(AI_CONFIG_PP_TUV_EVALUATE,AI_UVTRAFO_ALL);
}

// ------------------------------------------------------------------------------------------------
void TextureTransformStep::PreProcessUVTransform(STransformVecInfo& info)
{
    /*  This function tries to simplify the input UV transformation.
     *  That's very important as it allows us to reduce the number
     *  of output UV channels. The oder in which the transformations
     *  are applied is - as always - scaling, rotation, translation.
     */

    char szTemp[512];
    int rounded = 0;


    /* Optimize the rotation angle. That's slightly difficult as
     * we have an inprecise floating-point number (when comparing
     * UV transformations we'll take that into account by using
     * an epsilon of 5 degrees). If there is a rotation value, we can't
     * perform any further optimizations.
     */
    if (info.mRotation)
    {
        float out = info.mRotation;
        if ((rounded = (int)(info.mRotation / (float)AI_MATH_TWO_PI)))
        {
            out -= rounded*(float)AI_MATH_PI;

            ai_snprintf(szTemp, 512, "Texture coordinate rotation %f can be simplified to %f",info.mRotation,out);
            DefaultLogger::get()->info(szTemp);
        }

        // Next step - convert negative rotation angles to positives
        if (out < 0.f)
            out = (float)AI_MATH_TWO_PI * 2 + out;

        info.mRotation = out;
        return;
    }


    /* Optimize UV translation in the U direction. To determine whether
     * or not we can optimize we need to look at the requested mapping
     * type (e.g. if mirroring is active there IS a difference between
     * offset 2 and 3)
     */
    if ((rounded  = (int)info.mTranslation.x))  {
        float out = 0.0f;
        szTemp[0] = 0;
        if (aiTextureMapMode_Wrap == info.mapU) {
            // Wrap - simple take the fraction of the field
            out = info.mTranslation.x-(float)rounded;
			ai_snprintf(szTemp, 512, "[w] UV U offset %f can be simplified to %f", info.mTranslation.x, out);
        }
        else if (aiTextureMapMode_Mirror == info.mapU && 1 != rounded)  {
            // Mirror
            if (rounded % 2)
                rounded--;
            out = info.mTranslation.x-(float)rounded;

            ai_snprintf(szTemp,512,"[m/d] UV U offset %f can be simplified to %f",info.mTranslation.x,out);
        }
        else if (aiTextureMapMode_Clamp == info.mapU || aiTextureMapMode_Decal == info.mapU)    {
            // Clamp - translations beyond 1,1 are senseless
            ai_snprintf(szTemp,512,"[c] UV U offset %f can be clamped to 1.0f",info.mTranslation.x);

            out = 1.f;
        }
        if (szTemp[0])      {
            DefaultLogger::get()->info(szTemp);
            info.mTranslation.x = out;
        }
    }

    /* Optimize UV translation in the V direction. To determine whether
     * or not we can optimize we need to look at the requested mapping
     * type (e.g. if mirroring is active there IS a difference between
     * offset 2 and 3)
     */
    if ((rounded  = (int)info.mTranslation.y))  {
        float out = 0.0f;
        szTemp[0] = 0;
        if (aiTextureMapMode_Wrap == info.mapV) {
            // Wrap - simple take the fraction of the field
            out = info.mTranslation.y-(float)rounded;
            ::ai_snprintf(szTemp,512,"[w] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
        }
        else if (aiTextureMapMode_Mirror == info.mapV  && 1 != rounded) {
            // Mirror
            if (rounded % 2)
                rounded--;
            out = info.mTranslation.x-(float)rounded;

            ::ai_snprintf(szTemp,512,"[m/d] UV V offset %f can be simplified to %f",info.mTranslation.y,out);
        }
        else if (aiTextureMapMode_Clamp == info.mapV || aiTextureMapMode_Decal == info.mapV)    {
            // Clamp - translations beyond 1,1 are senseless
            ::ai_snprintf(szTemp,512,"[c] UV V offset %f canbe clamped to 1.0f",info.mTranslation.y);

            out = 1.f;
        }
        if (szTemp[0])  {
            DefaultLogger::get()->info(szTemp);
            info.mTranslation.y = out;
        }
    }
    return;
}

// ------------------------------------------------------------------------------------------------
void UpdateUVIndex(const std::list<TTUpdateInfo>& l, unsigned int n)
{
    // Don't set if == 0 && wasn't set before
    for (std::list<TTUpdateInfo>::const_iterator it = l.begin();it != l.end(); ++it) {
        const TTUpdateInfo& info = *it;

        if (info.directShortcut)
            *info.directShortcut = n;
        else if (!n)
        {
            info.mat->AddProperty<int>((int*)&n,1,AI_MATKEY_UVWSRC(info.semantic,info.index));
        }
    }
}

// ------------------------------------------------------------------------------------------------
inline const char* MappingModeToChar(aiTextureMapMode map)
{
    if (aiTextureMapMode_Wrap == map)
        return "-w";

    if (aiTextureMapMode_Mirror == map)
        return "-m";

    return "-c";
}

// ------------------------------------------------------------------------------------------------
void TextureTransformStep::Execute( aiScene* pScene)
{
    DefaultLogger::get()->debug("TransformUVCoordsProcess begin");


    /*  We build a per-mesh list of texture transformations we'll need
     *  to apply. To achieve this, we iterate through all materials,
     *  find all textures and get their transformations and UV indices.
     *  Then we search for all meshes using this material.
     */
    typedef std::list<STransformVecInfo> MeshTrafoList;
    std::vector<MeshTrafoList> meshLists(pScene->mNumMeshes);

    for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {

        aiMaterial* mat = pScene->mMaterials[i];
        for (unsigned int a = 0; a < mat->mNumProperties;++a)   {

            aiMaterialProperty* prop = mat->mProperties[a];
            if (!::strcmp( prop->mKey.data, "$tex.file"))   {
                STransformVecInfo info;

                // Setup a shortcut structure to allow for a fast updating
                // of the UV index later
                TTUpdateInfo update;
                update.mat = (aiMaterial*) mat;
                update.semantic = prop->mSemantic;
                update.index = prop->mIndex;

                // Get textured properties and transform
                for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)  {
                    aiMaterialProperty* prop2 = mat->mProperties[a2];
                    if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex) {
                        continue;
                    }

                    if ( !::strcmp( prop2->mKey.data, "$tex.uvwsrc")) {
                        info.uvIndex = *((int*)prop2->mData);

                        // Store a direct pointer for later use
                        update.directShortcut = (unsigned int*) prop2->mData;
                    }

                    else if ( !::strcmp( prop2->mKey.data, "$tex.mapmodeu")) {
                        info.mapU = *((aiTextureMapMode*)prop2->mData);
                    }
                    else if ( !::strcmp( prop2->mKey.data, "$tex.mapmodev")) {
                        info.mapV = *((aiTextureMapMode*)prop2->mData);
                    }
                    else if ( !::strcmp( prop2->mKey.data, "$tex.uvtrafo"))  {
                        // ValidateDS should check this
                        ai_assert(prop2->mDataLength >= 20);
                        ::memcpy(&info.mTranslation.x,prop2->mData,sizeof(float)*5);

                        // Directly remove this property from the list
                        mat->mNumProperties--;
                        for (unsigned int a3 = a2; a3 < mat->mNumProperties;++a3) {
                            mat->mProperties[a3] = mat->mProperties[a3+1];
                        }

                        delete prop2;

                        // Warn: could be an underflow, but this does not invoke undefined behaviour
                        --a2;
                    }
                }

                // Find out which transformations are to be evaluated
                if (!(configFlags & AI_UVTRAFO_ROTATION)) {
                    info.mRotation = 0.f;
                }
                if (!(configFlags & AI_UVTRAFO_SCALING)) {
                    info.mScaling = aiVector2D(1.f,1.f);
                }
                if (!(configFlags & AI_UVTRAFO_TRANSLATION)) {
                    info.mTranslation = aiVector2D(0.f,0.f);
                }

                // Do some preprocessing
                PreProcessUVTransform(info);
                info.uvIndex = std::min(info.uvIndex,AI_MAX_NUMBER_OF_TEXTURECOORDS -1u);

                // Find out whether this material is used by more than
                // one mesh. This will make our task much, much more difficult!
                unsigned int cnt = 0;
                for (unsigned int n = 0; n < pScene->mNumMeshes;++n)    {
                    if (pScene->mMeshes[n]->mMaterialIndex == i)
                        ++cnt;
                }

                if (!cnt)
                    continue;
                else if (1 != cnt)  {
                    // This material is referenced by more than one mesh!
                    // So we need to make sure the UV index for the texture
                    // is identical for each of it ...
                    info.lockedPos = AI_TT_UV_IDX_LOCK_TBD;
                }

                // Get all corresponding meshes
                for (unsigned int n = 0; n < pScene->mNumMeshes;++n)    {
                    aiMesh* mesh = pScene->mMeshes[n];
                    if (mesh->mMaterialIndex != i || !mesh->mTextureCoords[0])
                        continue;

                    unsigned int uv = info.uvIndex;
                    if (!mesh->mTextureCoords[uv])  {
                        // If the requested UV index is not available, take the first one instead.
                        uv = 0;
                    }

                    if (mesh->mNumUVComponents[info.uvIndex] >= 3){
                        DefaultLogger::get()->warn("UV transformations on 3D mapping channels are not supported");
                        continue;
                    }

                    MeshTrafoList::iterator it;

                    // Check whether we have this transform setup already
                    for (it = meshLists[n].begin();it != meshLists[n].end(); ++it)  {

                        if ((*it) == info && (*it).uvIndex == uv)   {
                            (*it).updateList.push_back(update);
                            break;
                        }
                    }

                    if (it == meshLists[n].end())   {
                        meshLists[n].push_back(info);
                        meshLists[n].back().uvIndex = uv;
                        meshLists[n].back().updateList.push_back(update);
                    }
                }
            }
        }
    }

    char buffer[1024]; // should be sufficiently large
    unsigned int outChannels = 0, inChannels = 0, transformedChannels = 0;

    // Now process all meshes. Important: we don't remove unreferenced UV channels.
    // This is a job for the RemoveUnreferencedData-Step.
    for (unsigned int q = 0; q < pScene->mNumMeshes;++q)    {

        aiMesh* mesh = pScene->mMeshes[q];
        MeshTrafoList& trafo =  meshLists[q];

        inChannels += mesh->GetNumUVChannels();

        if (!mesh->mTextureCoords[0] || trafo.empty() ||  (trafo.size() == 1 && trafo.begin()->IsUntransformed())) {
            outChannels += mesh->GetNumUVChannels();
            continue;
        }

        // Move untransformed UV channels to the first position in the list ....
        // except if we need a new locked index which should be as small as possible
        bool veto = false, need = false;
        unsigned int cnt = 0;
        unsigned int untransformed = 0;

        MeshTrafoList::iterator it,it2;
        for (it = trafo.begin();it != trafo.end(); ++it,++cnt)  {

            if (!(*it).IsUntransformed()) {
                need = true;
            }

            if ((*it).lockedPos == AI_TT_UV_IDX_LOCK_TBD)   {
                // Lock this index and make sure it won't be changed
                (*it).lockedPos = cnt;
                veto = true;
                continue;
            }

            if (!veto && it != trafo.begin() && (*it).IsUntransformed())    {
                for (it2 = trafo.begin();it2 != it; ++it2) {
                    if (!(*it2).IsUntransformed())
                        break;
                }
                trafo.insert(it2,*it);
                trafo.erase(it);
                break;
            }
        }
        if (!need)
            continue;

        // Find all that are not at their 'locked' position and move them to it.
        // Conflicts are possible but quite unlikely.
        cnt = 0;
        for (it = trafo.begin();it != trafo.end(); ++it,++cnt) {
            if ((*it).lockedPos != AI_TT_UV_IDX_LOCK_NONE && (*it).lockedPos != cnt) {
                it2 = trafo.begin();unsigned int t = 0;
                while (t != (*it).lockedPos)
                    ++it2;

                if ((*it2).lockedPos != AI_TT_UV_IDX_LOCK_NONE) {
                    DefaultLogger::get()->error("Channel mismatch, can't compute all transformations properly [design bug]");
                    continue;
                }

                std::swap(*it2,*it);
                if ((*it).lockedPos == untransformed)
                    untransformed = cnt;
            }
        }

        // ... and add dummies for all unreferenced channels
        // at the end of the list
        bool ref[AI_MAX_NUMBER_OF_TEXTURECOORDS];
        for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
            ref[n] = (!mesh->mTextureCoords[n] ? true : false);

        for (it = trafo.begin();it != trafo.end(); ++it)
            ref[(*it).uvIndex] = true;

        for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
            if (ref[n])
                continue;
            trafo.push_back(STransformVecInfo());
            trafo.back().uvIndex = n;
        }

        // Then check whether this list breaks the channel limit.
        // The unimportant ones are at the end of the list, so
        // it shouldn't be too worse if we remove them.
        unsigned int size = (unsigned int)trafo.size();
        if (size > AI_MAX_NUMBER_OF_TEXTURECOORDS) {

            if (!DefaultLogger::isNullLogger()) {
                ::ai_snprintf(buffer,1024,"%u UV channels required but just %u available",
                    static_cast<unsigned int>(trafo.size()),AI_MAX_NUMBER_OF_TEXTURECOORDS);

                DefaultLogger::get()->error(buffer);
            }
            size = AI_MAX_NUMBER_OF_TEXTURECOORDS;
        }


        aiVector3D* old[AI_MAX_NUMBER_OF_TEXTURECOORDS];
        for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n)
            old[n] = mesh->mTextureCoords[n];

        // Now continue and generate the output channels. Channels
        // that we're not going to need later can be overridden.
        it = trafo.begin();
        for (unsigned int n = 0; n < trafo.size();++n,++it) {

            if (n >= size)  {
                // Try to use an untransformed channel for all channels we threw over board
                UpdateUVIndex((*it).updateList,untransformed);
                continue;
            }

            outChannels++;

            // Write to the log
            if (!DefaultLogger::isNullLogger()) {
                ::ai_snprintf(buffer,1024,"Mesh %u, channel %u: t(%.3f,%.3f), s(%.3f,%.3f), r(%.3f), %s%s",
                    q,n,
                    (*it).mTranslation.x,
                    (*it).mTranslation.y,
                    (*it).mScaling.x,
                    (*it).mScaling.y,
                    AI_RAD_TO_DEG( (*it).mRotation),
                    MappingModeToChar ((*it).mapU),
                    MappingModeToChar ((*it).mapV));

                DefaultLogger::get()->info(buffer);
            }

            // Check whether we need a new buffer here
            if (mesh->mTextureCoords[n])    {

                it2 = it;++it2;
                for (unsigned int m = n+1; m < size;++m, ++it2) {

                    if ((*it2).uvIndex == n){
                        it2 = trafo.begin();
                        break;
                    }
                }
                if (it2 == trafo.begin()){
                    mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];
                }
            }
            else mesh->mTextureCoords[n] = new aiVector3D[mesh->mNumVertices];

            aiVector3D* src = old[(*it).uvIndex];
            aiVector3D* dest, *end;
            dest = mesh->mTextureCoords[n];

            ai_assert(NULL != src);

            // Copy the data to the destination array
            if (dest != src)
                ::memcpy(dest,src,sizeof(aiVector3D)*mesh->mNumVertices);

            end = dest + mesh->mNumVertices;

            // Build a transformation matrix and transform all UV coords with it
            if (!(*it).IsUntransformed()) {
                const aiVector2D& trl = (*it).mTranslation;
                const aiVector2D& scl = (*it).mScaling;

                // fixme: simplify ..
                ++transformedChannels;
                aiMatrix3x3 matrix;

                aiMatrix3x3 m2,m3,m4,m5;

                m4.a1 = scl.x;
                m4.b2 = scl.y;

                m2.a3 = m2.b3 = 0.5f;
                m3.a3 = m3.b3 = -0.5f;

                if ((*it).mRotation > AI_TT_ROTATION_EPSILON )
                    aiMatrix3x3::RotationZ((*it).mRotation,matrix);

                m5.a3 += trl.x; m5.b3 += trl.y;
                matrix = m2 * m4 * matrix * m3 * m5;

                for (src = dest; src != end; ++src) { /* manual homogenious divide */
                    src->z = 1.f;
                    *src = matrix * *src;
                    src->x /= src->z;
                    src->y /= src->z;
                    src->z = 0.f;
                }
            }

            // Update all UV indices
            UpdateUVIndex((*it).updateList,n);
        }
    }

    // Print some detailed statistics into the log
    if (!DefaultLogger::isNullLogger()) {

        if (transformedChannels)    {
            ::ai_snprintf(buffer,1024,"TransformUVCoordsProcess end: %u output channels (in: %u, modified: %u)",
                outChannels,inChannels,transformedChannels);

            DefaultLogger::get()->info(buffer);
        }
        else DefaultLogger::get()->debug("TransformUVCoordsProcess finished");
    }
}


