/*
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  LWOAnimation.cpp
 *  @brief LWOAnimationResolver utility class
 *
 *  It's a very generic implementation of LightWave's system of
 *  componentwise-animated stuff. The one and only fully free
 *  implementation of LightWave envelopes of which I know.
*/


#if (!defined ASSIMP_BUILD_NO_LWO_IMPORTER) && (!defined ASSIMP_BUILD_NO_LWS_IMPORTER)

#include <functional>

// internal headers
#include "LWOFileData.h"
#include <assimp/anim.h>

using namespace Assimp;
using namespace Assimp::LWO;

// ------------------------------------------------------------------------------------------------
// Construct an animation resolver from a given list of envelopes
AnimResolver::AnimResolver(std::list<Envelope>& _envelopes,double tick)
    : envelopes   (_envelopes)
    , sample_rate (0.)
    , envl_x(), envl_y(), envl_z()
    , end_x(), end_y(), end_z()
    , flags()
    , sample_delta()
{
    trans_x = trans_y = trans_z = NULL;
    rotat_x = rotat_y = rotat_z = NULL;
    scale_x = scale_y = scale_z = NULL;

    first = last = 150392.;

    // find transformation envelopes
    for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {

        (*it).old_first = 0;
        (*it).old_last  = (*it).keys.size()-1;

        if ((*it).keys.empty()) continue;
        switch ((*it).type) {

            // translation
            case LWO::EnvelopeType_Position_X:
                trans_x = &*it;break;
            case LWO::EnvelopeType_Position_Y:
                trans_y = &*it;break;
            case LWO::EnvelopeType_Position_Z:
                trans_z = &*it;break;

                // rotation
            case LWO::EnvelopeType_Rotation_Heading:
                rotat_x = &*it;break;
            case LWO::EnvelopeType_Rotation_Pitch:
                rotat_y = &*it;break;
            case LWO::EnvelopeType_Rotation_Bank:
                rotat_z = &*it;break;

                // scaling
            case LWO::EnvelopeType_Scaling_X:
                scale_x = &*it;break;
            case LWO::EnvelopeType_Scaling_Y:
                scale_y = &*it;break;
            case LWO::EnvelopeType_Scaling_Z:
                scale_z = &*it;break;
            default:
                continue;
        };

        // convert from seconds to ticks
        for (std::vector<LWO::Key>::iterator d = (*it).keys.begin(); d != (*it).keys.end(); ++d)
            (*d).time *= tick;

        // set default animation range (minimum and maximum time value for which we have a keyframe)
        first = std::min(first, (*it).keys.front().time );
        last  = std::max(last,  (*it).keys.back().time );
    }

    // deferred setup of animation range to increase performance.
    // typically the application will want to specify its own.
    need_to_setup = true;
}

// ------------------------------------------------------------------------------------------------
// Reset all envelopes to their original contents
void AnimResolver::ClearAnimRangeSetup()
{
    for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {

        (*it).keys.erase((*it).keys.begin(),(*it).keys.begin()+(*it).old_first);
        (*it).keys.erase((*it).keys.begin()+(*it).old_last+1,(*it).keys.end());
    }
}

// ------------------------------------------------------------------------------------------------
// Insert additional keys to match LWO's pre& post behaviours.
void AnimResolver::UpdateAnimRangeSetup()
{
    // XXX doesn't work yet (hangs if more than one envelope channels needs to be interpolated)

    for (std::list<LWO::Envelope>::iterator it = envelopes.begin(); it != envelopes.end(); ++it) {
        if ((*it).keys.empty()) continue;

        const double my_first = (*it).keys.front().time;
        const double my_last  = (*it).keys.back().time;

        const double delta = my_last-my_first;
        const size_t old_size = (*it).keys.size();

        const float value_delta = (*it).keys.back().value - (*it).keys.front().value;

        // NOTE: We won't handle reset, linear and constant here.
        // See DoInterpolation() for their implementation.

        // process pre behaviour
        switch ((*it).pre) {
            case LWO::PrePostBehaviour_OffsetRepeat:
            case LWO::PrePostBehaviour_Repeat:
            case LWO::PrePostBehaviour_Oscillate:
                {
                const double start_time = delta - std::fmod(my_first-first,delta);
                std::vector<LWO::Key>::iterator n = std::find_if((*it).keys.begin(),(*it).keys.end(),
                    [start_time](double t) { return start_time > t; }),m;

                size_t ofs = 0;
                if (n != (*it).keys.end()) {
                    // copy from here - don't use iterators, insert() would invalidate them
                    ofs = (*it).keys.end()-n;
                    (*it).keys.insert((*it).keys.begin(),ofs,LWO::Key());

                    std::copy((*it).keys.end()-ofs,(*it).keys.end(),(*it).keys.begin());
                }

                // do full copies. again, no iterators
                const unsigned int num = (unsigned int)((my_first-first) / delta);
                (*it).keys.resize((*it).keys.size() + num*old_size);

                n = (*it).keys.begin()+ofs;
                bool reverse = false;
                for (unsigned int i = 0; i < num; ++i) {
                    m = n+old_size*(i+1);
                    std::copy(n,n+old_size,m);

                    if ((*it).pre == LWO::PrePostBehaviour_Oscillate && (reverse = !reverse))
                        std::reverse(m,m+old_size-1);
                }

                // update time values
                n = (*it).keys.end() - (old_size+1);
                double cur_minus = delta;
                unsigned int tt = 1;
                for (const double tmp =  delta*(num+1);cur_minus <= tmp;cur_minus += delta,++tt) {
                    m = (delta == tmp ? (*it).keys.begin() :  n - (old_size+1));
                    for (;m != n; --n) {
                        (*n).time -= cur_minus;

                        // offset repeat? add delta offset to key value
                        if ((*it).pre == LWO::PrePostBehaviour_OffsetRepeat) {
                            (*n).value += tt * value_delta;
                        }
                    }
                }
                break;
                }
            default:
                // silence compiler warning
                break;
        }

        // process post behaviour
        switch ((*it).post) {

            case LWO::PrePostBehaviour_OffsetRepeat:
            case LWO::PrePostBehaviour_Repeat:
            case LWO::PrePostBehaviour_Oscillate:

                break;

            default:
                // silence compiler warning
                break;
        }
    }
}

// ------------------------------------------------------------------------------------------------
// Extract bind pose matrix
void AnimResolver::ExtractBindPose(aiMatrix4x4& out)
{
    // If we have no envelopes, return identity
    if (envelopes.empty()) {
        out = aiMatrix4x4();
        return;
    }
    aiVector3D angles, scaling(1.f,1.f,1.f), translation;

    if (trans_x) translation.x = trans_x->keys[0].value;
    if (trans_y) translation.y = trans_y->keys[0].value;
    if (trans_z) translation.z = trans_z->keys[0].value;

    if (rotat_x) angles.x = rotat_x->keys[0].value;
    if (rotat_y) angles.y = rotat_y->keys[0].value;
    if (rotat_z) angles.z = rotat_z->keys[0].value;

    if (scale_x) scaling.x = scale_x->keys[0].value;
    if (scale_y) scaling.y = scale_y->keys[0].value;
    if (scale_z) scaling.z = scale_z->keys[0].value;

    // build the final matrix
    aiMatrix4x4 s,rx,ry,rz,t;
    aiMatrix4x4::RotationZ(angles.z, rz);
    aiMatrix4x4::RotationX(angles.y, rx);
    aiMatrix4x4::RotationY(angles.x, ry);
    aiMatrix4x4::Translation(translation,t);
    aiMatrix4x4::Scaling(scaling,s);
    out = t*ry*rx*rz*s;
}

// ------------------------------------------------------------------------------------------------
// Do a single interpolation on a channel
void AnimResolver::DoInterpolation(std::vector<LWO::Key>::const_iterator cur,
    LWO::Envelope* envl,double time, float& fill)
{
    if (envl->keys.size() == 1) {
        fill = envl->keys[0].value;
        return;
    }

    // check whether we're at the beginning of the animation track
    if (cur == envl->keys.begin()) {

        // ok ... this depends on pre behaviour now
        // we don't need to handle repeat&offset repeat&oszillate here, see UpdateAnimRangeSetup()
        switch (envl->pre)
        {
        case LWO::PrePostBehaviour_Linear:
            DoInterpolation2(cur,cur+1,time,fill);
            return;

        case LWO::PrePostBehaviour_Reset:
            fill = 0.f;
            return;

        default : //case LWO::PrePostBehaviour_Constant:
            fill = (*cur).value;
            return;
        }
    }
    // check whether we're at the end of the animation track
    else if (cur == envl->keys.end()-1 && time > envl->keys.rbegin()->time) {
        // ok ... this depends on post behaviour now
        switch (envl->post)
        {
        case LWO::PrePostBehaviour_Linear:
            DoInterpolation2(cur,cur-1,time,fill);
            return;

        case LWO::PrePostBehaviour_Reset:
            fill = 0.f;
            return;

        default : //case LWO::PrePostBehaviour_Constant:
            fill = (*cur).value;
            return;
        }
    }

    // Otherwise do a simple interpolation
    DoInterpolation2(cur-1,cur,time,fill);
}

// ------------------------------------------------------------------------------------------------
// Almost the same, except we won't handle pre/post conditions here
void AnimResolver::DoInterpolation2(std::vector<LWO::Key>::const_iterator beg,
    std::vector<LWO::Key>::const_iterator end,double time, float& fill)
{
    switch ((*end).inter) {

        case LWO::IT_STEP:
            // no interpolation at all - take the value of the last key
            fill = (*beg).value;
            return;
        default:

            // silence compiler warning
            break;
    }
    // linear interpolation - default
    double duration = (*end).time - (*beg).time;
    if (duration > 0.0) {
        fill = (*beg).value + ((*end).value - (*beg).value)*(float)(((time - (*beg).time) / duration));
    } else {
        fill = (*beg).value;
    }
}

// ------------------------------------------------------------------------------------------------
// Subsample animation track by given key values
void AnimResolver::SubsampleAnimTrack(std::vector<aiVectorKey>& /*out*/,
    double /*time*/ ,double /*sample_delta*/ )
{
    //ai_assert(out.empty() && sample_delta);

    //const double time_start = out.back().mTime;
//  for ()
}

// ------------------------------------------------------------------------------------------------
// Track interpolation
void AnimResolver::InterpolateTrack(std::vector<aiVectorKey>& out,aiVectorKey& fill,double time)
{
    // subsample animation track?
    if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
        SubsampleAnimTrack(out,time, sample_delta);
    }

    fill.mTime = time;

    // get x
    if ((*cur_x).time == time) {
        fill.mValue.x = (*cur_x).value;

        if (cur_x != envl_x->keys.end()-1) /* increment x */
            ++cur_x;
        else end_x = true;
    }
    else DoInterpolation(cur_x,envl_x,time,(float&)fill.mValue.x);

    // get y
    if ((*cur_y).time == time) {
        fill.mValue.y = (*cur_y).value;

        if (cur_y != envl_y->keys.end()-1) /* increment y */
            ++cur_y;
        else end_y = true;
    }
    else DoInterpolation(cur_y,envl_y,time,(float&)fill.mValue.y);

    // get z
    if ((*cur_z).time == time) {
        fill.mValue.z = (*cur_z).value;

        if (cur_z != envl_z->keys.end()-1) /* increment z */
            ++cur_z;
        else end_x = true;
    }
    else DoInterpolation(cur_z,envl_z,time,(float&)fill.mValue.z);
}

// ------------------------------------------------------------------------------------------------
// Build linearly subsampled keys from three single envelopes, one for each component (x,y,z)
void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
    LWO::Envelope* _envl_x,
    LWO::Envelope* _envl_y,
    LWO::Envelope* _envl_z,
    unsigned int _flags)
{
    envl_x = _envl_x;
    envl_y = _envl_y;
    envl_z = _envl_z;
    flags  = _flags;

    // generate default channels if none are given
    LWO::Envelope def_x, def_y, def_z;
    LWO::Key key_dummy;
    key_dummy.time = 0.f;
    if ((envl_x && envl_x->type == LWO::EnvelopeType_Scaling_X) ||
        (envl_y && envl_y->type == LWO::EnvelopeType_Scaling_Y) ||
        (envl_z && envl_z->type == LWO::EnvelopeType_Scaling_Z)) {
        key_dummy.value = 1.f;
    }
    else key_dummy.value = 0.f;

    if (!envl_x) {
        envl_x = &def_x;
        envl_x->keys.push_back(key_dummy);
    }
    if (!envl_y) {
        envl_y = &def_y;
        envl_y->keys.push_back(key_dummy);
    }
    if (!envl_z) {
        envl_z = &def_z;
        envl_z->keys.push_back(key_dummy);
    }

    // guess how many keys we'll get
    size_t reserve;
    double sr = 1.;
    if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
        if (!sample_rate)
            sr = 100.f;
        else sr = sample_rate;
        sample_delta = 1.f / sr;

        reserve = (size_t)(
            std::max( envl_x->keys.rbegin()->time,
            std::max( envl_y->keys.rbegin()->time, envl_z->keys.rbegin()->time )) * sr);
    }
    else reserve = std::max(envl_x->keys.size(),std::max(envl_x->keys.size(),envl_z->keys.size()));
    out.reserve(reserve+(reserve>>1));

    // Iterate through all three arrays at once - it's tricky, but
    // rather interesting to implement.
    cur_x = envl_x->keys.begin();
    cur_y = envl_y->keys.begin();
    cur_z = envl_z->keys.begin();

    end_x = end_y = end_z = false;
    while (1) {

        aiVectorKey fill;

        if ((*cur_x).time == (*cur_y).time && (*cur_x).time == (*cur_z).time ) {

            // we have a keyframe for all of them defined .. this means
            // we don't need to interpolate here.
            fill.mTime = (*cur_x).time;

            fill.mValue.x = (*cur_x).value;
            fill.mValue.y = (*cur_y).value;
            fill.mValue.z = (*cur_z).value;

            // subsample animation track
            if (flags & AI_LWO_ANIM_FLAG_SAMPLE_ANIMS) {
                //SubsampleAnimTrack(out,cur_x, cur_y, cur_z, d, sample_delta);
            }
        }

        // Find key with lowest time value
        else if ((*cur_x).time <= (*cur_y).time && !end_x) {

            if ((*cur_z).time <= (*cur_x).time && !end_z) {
                InterpolateTrack(out,fill,(*cur_z).time);
            }
            else {
                InterpolateTrack(out,fill,(*cur_x).time);
            }
        }
        else if ((*cur_z).time <= (*cur_y).time && !end_y)  {
            InterpolateTrack(out,fill,(*cur_y).time);
        }
        else if (!end_y) {
            // welcome on the server, y
            InterpolateTrack(out,fill,(*cur_y).time);
        }
        else {
            // we have reached the end of at least 2 channels,
            // only one is remaining. Extrapolate the 2.
            if (end_y) {
                InterpolateTrack(out,fill,(end_x ? (*cur_z) : (*cur_x)).time);
            }
            else if (end_x) {
                InterpolateTrack(out,fill,(end_z ? (*cur_y) : (*cur_z)).time);
            }
            else { // if (end_z)
                InterpolateTrack(out,fill,(end_y ? (*cur_x) : (*cur_y)).time);
            }
        }
        double lasttime = fill.mTime;
        out.push_back(fill);

        if (lasttime >= (*cur_x).time) {
            if (cur_x != envl_x->keys.end()-1)
                ++cur_x;
            else end_x = true;
        }
        if (lasttime >= (*cur_y).time) {
            if (cur_y != envl_y->keys.end()-1)
                ++cur_y;
            else end_y = true;
        }
        if (lasttime >= (*cur_z).time) {
            if (cur_z != envl_z->keys.end()-1)
                ++cur_z;
            else end_z = true;
        }

        if( end_x && end_y && end_z ) /* finished? */
            break;
    }

    if (flags & AI_LWO_ANIM_FLAG_START_AT_ZERO) {
        for (std::vector<aiVectorKey>::iterator it = out.begin(); it != out.end(); ++it)
            (*it).mTime -= first;
    }
}

// ------------------------------------------------------------------------------------------------
// Extract animation channel
void AnimResolver::ExtractAnimChannel(aiNodeAnim** out, unsigned int flags /*= 0*/)
{
    *out = NULL;


    //FIXME: crashes if more than one component is animated at different timings, to be resolved.

    // If we have no envelopes, return NULL
    if (envelopes.empty()) {
        return;
    }

    // We won't spawn an animation channel if we don't have at least one envelope with more than one keyframe defined.
    const bool trans = ((trans_x && trans_x->keys.size() > 1) || (trans_y && trans_y->keys.size() > 1) || (trans_z && trans_z->keys.size() > 1));
    const bool rotat = ((rotat_x && rotat_x->keys.size() > 1) || (rotat_y && rotat_y->keys.size() > 1) || (rotat_z && rotat_z->keys.size() > 1));
    const bool scale = ((scale_x && scale_x->keys.size() > 1) || (scale_y && scale_y->keys.size() > 1) || (scale_z && scale_z->keys.size() > 1));
    if (!trans && !rotat && !scale)
        return;

    // Allocate the output animation
    aiNodeAnim* anim = *out = new aiNodeAnim();

    // Setup default animation setup if necessary
    if (need_to_setup) {
        UpdateAnimRangeSetup();
        need_to_setup = false;
    }

    // copy translation keys
    if (trans) {
        std::vector<aiVectorKey> keys;
        GetKeys(keys,trans_x,trans_y,trans_z,flags);

        anim->mPositionKeys = new aiVectorKey[ anim->mNumPositionKeys = static_cast<unsigned int>(keys.size()) ];
        std::copy(keys.begin(),keys.end(),anim->mPositionKeys);
    }

    // copy rotation keys
    if (rotat) {
        std::vector<aiVectorKey> keys;
        GetKeys(keys,rotat_x,rotat_y,rotat_z,flags);

        anim->mRotationKeys = new aiQuatKey[ anim->mNumRotationKeys = static_cast<unsigned int>(keys.size()) ];

        // convert heading, pitch, bank to quaternion
        // mValue.x=Heading=Rot(Y), mValue.y=Pitch=Rot(X), mValue.z=Bank=Rot(Z)
        // Lightwave's rotation order is ZXY
        aiVector3D X(1.0,0.0,0.0);
        aiVector3D Y(0.0,1.0,0.0);
        aiVector3D Z(0.0,0.0,1.0);
        for (unsigned int i = 0; i < anim->mNumRotationKeys; ++i) {
            aiQuatKey& qk = anim->mRotationKeys[i];
            qk.mTime  = keys[i].mTime;
            qk.mValue = aiQuaternion(Y,keys[i].mValue.x)*aiQuaternion(X,keys[i].mValue.y)*aiQuaternion(Z,keys[i].mValue.z);
        }
    }

    // copy scaling keys
    if (scale) {
        std::vector<aiVectorKey> keys;
        GetKeys(keys,scale_x,scale_y,scale_z,flags);

        anim->mScalingKeys = new aiVectorKey[ anim->mNumScalingKeys = static_cast<unsigned int>(keys.size()) ];
        std::copy(keys.begin(),keys.end(),anim->mScalingKeys);
    }
}


#endif // no lwo or no lws
