#include "rive/constraints/ik_constraint.hpp"
#include "rive/bones/bone.hpp"
#include "rive/artboard.hpp"
#include "rive/math/math_types.hpp"
#include <algorithm>

using namespace rive;

void IKConstraint::buildDependencies() {
    Super::buildDependencies();

    // IK Constraint needs to depend on the target so that world transform
    // changes can propagate to the bones (and they can be reset before IK
    // runs).
    if (m_Target != nullptr) {
        m_Target->addDependent(this);
    }
}

StatusCode IKConstraint::onAddedClean(CoreContext* context) {
    if (!parent()->is<Bone>()) {
        return StatusCode::InvalidObject;
    }

    auto boneCount = parentBoneCount();
    auto bone = parent()->as<Bone>();
    std::vector<Bone*> bones;
    bones.push_back(bone);
    // Get the reverse FK chain of bones (from tip up).
    while (bone->parent()->is<Bone>() && boneCount > 0) {
        boneCount--;
        bone = bone->parent()->as<Bone>();
        bone->addPeerConstraint(this);
        bones.push_back(bone);
    }
    int numBones = (int)bones.size();
    m_FkChain.resize(numBones);
    // Now put them in FK order (top to bottom).
    int idx = 0;
    for (auto boneItr = bones.rbegin(); boneItr != bones.rend(); ++boneItr) {
        BoneChainLink& link = m_FkChain[idx];
        link.index = idx++;
        link.bone = *boneItr;
        link.angle = 0.0f;
    }

    // Make sure all of the first level children of each bone depend on the
    // tip (constrainedComponent).
    auto tip = parent()->as<Bone>();

    auto artboard = static_cast<Artboard*>(context);

    // Find all children of this bone (we don't directly build up
    // hierarchy at runtime, so we have to traverse everything and check
    // parents).
    for (auto core : artboard->objects()) {
        if (core == nullptr || !core->is<TransformComponent>()) {
            continue;
        }
        auto transformComponent = core->as<TransformComponent>();

        for (int i = 1; i < numBones; i++) {
            auto bone = bones[i];
            if (transformComponent->parent() == bone &&
                std::find(bones.begin(), bones.end(), transformComponent) == bones.end())
            {
                tip->addDependent(transformComponent);
            }
        }
    }
    return Super::onAddedClean(context);
}

void IKConstraint::markConstraintDirty() {
    Super::markConstraintDirty();
    // We automatically propagate dirt to the parent constrained bone, but we
    // also need to make sure the other bones we influence above it rebuild
    // their transforms.
    for (int i = 0, length = (int)m_FkChain.size() - 1; i < length; i++) {
        m_FkChain[i].bone->markTransformDirty();
    }
}

void IKConstraint::solve1(BoneChainLink* fk1, const Vec2D& worldTargetTranslation) {
    Mat2D iworld = fk1->parentWorldInverse;
    Vec2D pA;
    fk1->bone->worldTranslation(pA);
    Vec2D pBT(worldTargetTranslation);

    // To target in worldspace
    const Vec2D toTarget = pBT - pA;

    // Note this is directional, hence not transformMat2d
    Vec2D toTargetLocal = Vec2D::transformDir(toTarget, iworld);
    float r = std::atan2(toTargetLocal[1], toTargetLocal[0]);

    constrainRotation(*fk1, r);
    fk1->angle = r;
}

void IKConstraint::solve2(BoneChainLink* fk1,
                          BoneChainLink* fk2,
                          const Vec2D& worldTargetTranslation) {
    Bone* b1 = fk1->bone;
    Bone* b2 = fk2->bone;
    BoneChainLink* firstChild = &(m_FkChain[fk1->index + 1]);

    const Mat2D& iworld = fk1->parentWorldInverse;

    Vec2D pA, pC, pB;
    b1->worldTranslation(pA);
    firstChild->bone->worldTranslation(pC);
    b2->tipWorldTranslation(pB);
    Vec2D pBT(worldTargetTranslation);

    pA = iworld * pA;
    pC = iworld * pC;
    pB = iworld * pB;
    pBT = iworld * pBT;

    // http://mathworld.wolfram.com/LawofCosines.html
    Vec2D av = pB - pC, bv = pC - pA, cv = pBT - pA;
    float a = av.length(), b = bv.length(), c = cv.length();

    float A = std::acos(std::max(-1.0f, std::min(1.0f, (-a * a + b * b + c * c) / (2.0f * b * c))));
    float C = std::acos(std::max(-1.0f, std::min(1.0f, (a * a + b * b - c * c) / (2.0f * a * b))));

    float r1, r2;
    if (b2->parent() != b1) {
        BoneChainLink& secondChild = m_FkChain[fk1->index + 2];

        const Mat2D& secondChildWorldInverse = secondChild.parentWorldInverse;

        firstChild->bone->worldTranslation(pC);
        b2->tipWorldTranslation(pB);

        Vec2D avLocal = Vec2D::transformDir(pB - pC, secondChildWorldInverse);
        float angleCorrection = -std::atan2(avLocal[1], avLocal[0]);

        if (invertDirection()) {
            r1 = std::atan2(cv[1], cv[0]) - A;
            r2 = -C + math::PI + angleCorrection;
        } else {
            r1 = A + std::atan2(cv[1], cv[0]);
            r2 = C - math::PI + angleCorrection;
        }
    } else if (invertDirection()) {
        r1 = std::atan2(cv[1], cv[0]) - A;
        r2 = -C + math::PI;
    } else {
        r1 = A + std::atan2(cv[1], cv[0]);
        r2 = C - math::PI;
    }

    constrainRotation(*fk1, r1);
    constrainRotation(*firstChild, r2);
    if (firstChild != fk2) {
        Bone* bone = fk2->bone;
        bone->mutableWorldTransform() = getParentWorld(*bone) * bone->transform();
    }

    // Simple storage, need this for interpolation.
    fk1->angle = r1;
    firstChild->angle = r2;
}

void IKConstraint::constrainRotation(BoneChainLink& fk, float rotation) {
    Bone* bone = fk.bone;
    const Mat2D& parentWorld = getParentWorld(*bone);
    Mat2D& transform = bone->mutableTransform();
    TransformComponents& c = fk.transformComponents;

    transform = Mat2D::fromRotation(rotation);

    // Translate
    transform[4] = c.x();
    transform[5] = c.y();
    // Scale
    float scaleX = c.scaleX();
    float scaleY = c.scaleY();
    transform[0] *= scaleX;
    transform[1] *= scaleX;
    transform[2] *= scaleY;
    transform[3] *= scaleY;

    // Skew
    const float skew = c.skew();
    if (skew != 0.0f) {
        transform[2] = transform[0] * skew + transform[2];
        transform[3] = transform[1] * skew + transform[3];
    }

    bone->mutableWorldTransform() = parentWorld * transform;
}

void IKConstraint::constrain(TransformComponent* component) {
    if (m_Target == nullptr) {
        return;
    }

    Vec2D worldTargetTranslation;
    m_Target->worldTranslation(worldTargetTranslation);

    // Decompose the chain.
    for (BoneChainLink& item : m_FkChain) {
        auto bone = item.bone;
        const Mat2D& parentWorld = getParentWorld(*bone);
        item.parentWorldInverse = parentWorld.invertOrIdentity();

        Mat2D& boneTransform = bone->mutableTransform();
        boneTransform = item.parentWorldInverse * bone->worldTransform();
        item.transformComponents = boneTransform.decompose();
    }

    int count = (int)m_FkChain.size();
    switch (count) {
        case 1:
            solve1(&m_FkChain[0], worldTargetTranslation);
            break;
        case 2:
            solve2(&m_FkChain[0], &m_FkChain[1], worldTargetTranslation);
            break;
        default: {
            auto last = count - 1;
            BoneChainLink* tip = &m_FkChain[last];
            for (int i = 0; i < last; i++) {
                BoneChainLink* item = &m_FkChain[i];
                solve2(item, tip, worldTargetTranslation);
                for (int j = item->index + 1, end = m_FkChain.size() - 1; j < end; j++) {
                    BoneChainLink& fk = m_FkChain[j];
                    fk.parentWorldInverse = getParentWorld(*fk.bone).invertOrIdentity();
                }
            }
            break;
        }
    }
    // At the end, mix the FK angle with the IK angle by strength
    if (strength() != 1.0f) {
        for (BoneChainLink& fk : m_FkChain) {
            float fromAngle = std::fmod(fk.transformComponents.rotation(), math::PI * 2);
            float toAngle = std::fmod(fk.angle, math::PI * 2);
            float diff = toAngle - fromAngle;
            if (diff > math::PI) {
                diff -= math::PI * 2;
            } else if (diff < -math::PI) {
                diff += math::PI * 2;
            }
            float angle = fromAngle + diff * strength();
            constrainRotation(fk, angle);
        }
    }
}
