/*
 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
 * Copyright (C) 2007 Rob Buis <buis@kde.org>
 * Copyright (C) 2008 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "SVGAnimateMotionElement.h"

#include "AffineTransform.h"
#include "ElementIterator.h"
#include "PathTraversalState.h"
#include "RenderSVGResource.h"
#include "SVGElementTypeHelpers.h"
#include "SVGImageElement.h"
#include "SVGMPathElement.h"
#include "SVGNames.h"
#include "SVGParserUtilities.h"
#include "SVGPathData.h"
#include "SVGPathElement.h"
#include "SVGPathUtilities.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/MathExtras.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/StringView.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(SVGAnimateMotionElement);
    
using namespace SVGNames;

inline SVGAnimateMotionElement::SVGAnimateMotionElement(const QualifiedName& tagName, Document& document)
    : SVGAnimationElement(tagName, document)
{
    setCalcMode(CalcMode::Paced);
    ASSERT(hasTagName(animateMotionTag));
}

Ref<SVGAnimateMotionElement> SVGAnimateMotionElement::create(const QualifiedName& tagName, Document& document)
{
    return adoptRef(*new SVGAnimateMotionElement(tagName, document));
}

bool SVGAnimateMotionElement::hasValidAttributeType() const
{
    RefPtr targetElement = this->targetElement();
    if (!targetElement)
        return false;

    // We don't have a special attribute name to verify the animation type. Check the element name instead.
    if (!targetElement->isSVGGraphicsElement())
        return false;
    // Spec: SVG 1.1 section 19.2.15
    // FIXME: svgTag is missing. Needs to be checked, if transforming <svg> could cause problems.
    if (targetElement->hasTagName(gTag)
        || targetElement->hasTagName(defsTag)
        || targetElement->hasTagName(useTag)
        || is<SVGImageElement>(*targetElement)
        || targetElement->hasTagName(switchTag)
        || targetElement->hasTagName(pathTag)
        || targetElement->hasTagName(rectTag)
        || targetElement->hasTagName(circleTag)
        || targetElement->hasTagName(ellipseTag)
        || targetElement->hasTagName(lineTag)
        || targetElement->hasTagName(polylineTag)
        || targetElement->hasTagName(polygonTag)
        || targetElement->hasTagName(textTag)
        || targetElement->hasTagName(clipPathTag)
        || targetElement->hasTagName(maskTag)
        || targetElement->hasTagName(SVGNames::aTag)
        || targetElement->hasTagName(foreignObjectTag)
        )
        return true;
    return false;
}

bool SVGAnimateMotionElement::hasValidAttributeName() const
{
    // AnimateMotion does not use attributeName so it is always valid.
    return true;
}

void SVGAnimateMotionElement::parseAttribute(const QualifiedName& name, const AtomString& value)
{
    if (name == SVGNames::pathAttr) {
        m_path = buildPathFromString(value);
        updateAnimationPath();
        return;
    }

    SVGAnimationElement::parseAttribute(name, value);
}
    
SVGAnimateMotionElement::RotateMode SVGAnimateMotionElement::rotateMode() const
{
    static MainThreadNeverDestroyed<const AtomString> autoVal("auto", AtomString::ConstructFromLiteral);
    static MainThreadNeverDestroyed<const AtomString> autoReverse("auto-reverse", AtomString::ConstructFromLiteral);
    const AtomString& rotate = getAttribute(SVGNames::rotateAttr);
    if (rotate == autoVal)
        return RotateAuto;
    if (rotate == autoReverse)
        return RotateAutoReverse;
    return RotateAngle;
}

void SVGAnimateMotionElement::updateAnimationPath()
{
    m_animationPath = Path();
    bool foundMPath = false;

    for (auto& mPath : childrenOfType<SVGMPathElement>(*this)) {
        auto pathElement = mPath.pathElement();
        if (pathElement) {
            m_animationPath = pathFromGraphicsElement(pathElement.get());
            foundMPath = true;
            break;
        }
    }

    if (!foundMPath && hasAttributeWithoutSynchronization(SVGNames::pathAttr))
        m_animationPath = m_path;

    updateAnimationMode();
}

void SVGAnimateMotionElement::startAnimation()
{
    if (!hasValidAttributeType())
        return;
    RefPtr targetElement = this->targetElement();
    if (!targetElement)
        return;
    if (AffineTransform* transform = targetElement->supplementalTransform())
        transform->makeIdentity();
}

void SVGAnimateMotionElement::stopAnimation(SVGElement* targetElement)
{
    if (!targetElement)
        return;
    if (AffineTransform* transform = targetElement->supplementalTransform())
        transform->makeIdentity();
    applyResultsToTarget();
}

bool SVGAnimateMotionElement::calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString)
{
    m_toPointAtEndOfDuration = parsePoint(toAtEndOfDurationString).value_or(FloatPoint { });
    return true;
}

bool SVGAnimateMotionElement::calculateFromAndToValues(const String& fromString, const String& toString)
{
    m_toPointAtEndOfDuration = std::nullopt;
    m_fromPoint = parsePoint(fromString).value_or(FloatPoint { });
    m_toPoint = parsePoint(toString).value_or(FloatPoint { });
    return true;
}
    
bool SVGAnimateMotionElement::calculateFromAndByValues(const String& fromString, const String& byString)
{
    m_toPointAtEndOfDuration = std::nullopt;
    if (animationMode() == AnimationMode::By && !isAdditive())
        return false;
    m_fromPoint = parsePoint(fromString).value_or(FloatPoint { });
    auto byPoint = parsePoint(byString).value_or(FloatPoint { });
    m_toPoint = FloatPoint(m_fromPoint.x() + byPoint.x(), m_fromPoint.y() + byPoint.y());
    return true;
}

void SVGAnimateMotionElement::buildTransformForProgress(AffineTransform* transform, float percentage)
{
    ASSERT(!m_animationPath.isEmpty());

    float positionOnPath = m_animationPath.length() * percentage;
    auto traversalState(m_animationPath.traversalStateAtLength(positionOnPath));
    if (!traversalState.success())
        return;

    FloatPoint position = traversalState.current();
    float angle = traversalState.normalAngle();

    transform->translate(position);
    RotateMode rotateMode = this->rotateMode();
    if (rotateMode != RotateAuto && rotateMode != RotateAutoReverse)
        return;
    if (rotateMode == RotateAutoReverse)
        angle += 180;
    transform->rotate(angle);
}

void SVGAnimateMotionElement::calculateAnimatedValue(float percentage, unsigned repeatCount)
{
    RefPtr targetElement = this->targetElement();
    if (!targetElement)
        return;

    AffineTransform* transform = targetElement->supplementalTransform();
    if (!transform)
        return;

    if (!isAdditive())
        transform->makeIdentity();

    if (animationMode() != AnimationMode::Path) {
        FloatPoint toPointAtEndOfDuration = m_toPoint;
        if (isAccumulated() && repeatCount && m_toPointAtEndOfDuration)
            toPointAtEndOfDuration = *m_toPointAtEndOfDuration;

        float animatedX = 0;
        animateAdditiveNumber(percentage, repeatCount, m_fromPoint.x(), m_toPoint.x(), toPointAtEndOfDuration.x(), animatedX);

        float animatedY = 0;
        animateAdditiveNumber(percentage, repeatCount, m_fromPoint.y(), m_toPoint.y(), toPointAtEndOfDuration.y(), animatedY);

        transform->translate(animatedX, animatedY);
        return;
    }

    buildTransformForProgress(transform, percentage);

    // Handle accumulate="sum".
    if (isAccumulated() && repeatCount) {
        for (unsigned i = 0; i < repeatCount; ++i)
            buildTransformForProgress(transform, 1);
    }
}

void SVGAnimateMotionElement::applyResultsToTarget()
{
    // We accumulate to the target element transform list so there is not much to do here.
    RefPtr targetElement = this->targetElement();
    if (!targetElement)
        return;

    if (RenderElement* renderer = targetElement->renderer()) {
        renderer->setNeedsTransformUpdate();
        RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
    }

    AffineTransform* targetSupplementalTransform = targetElement->supplementalTransform();
    if (!targetSupplementalTransform)
        return;

    // ...except in case where we have additional instances in <use> trees.
    for (auto& instance : copyToVectorOf<Ref<SVGElement>>(targetElement->instances())) {
        AffineTransform* transform = instance->supplementalTransform();
        if (!transform || *transform == *targetSupplementalTransform)
            continue;
        *transform = *targetSupplementalTransform;
        if (RenderElement* renderer = instance->renderer()) {
            renderer->setNeedsTransformUpdate();
            RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer);
        }
    }
}

std::optional<float> SVGAnimateMotionElement::calculateDistance(const String& fromString, const String& toString)
{
    auto from = parsePoint(fromString);
    if (!from)
        return { };
    auto to = parsePoint(toString);
    if (!to)
        return { };
    auto diff = *to - *from;
    return std::hypot(diff.width(), diff.height());
}

void SVGAnimateMotionElement::updateAnimationMode()
{
    if (!m_animationPath.isEmpty())
        setAnimationMode(AnimationMode::Path);
    else
        SVGAnimationElement::updateAnimationMode();
}

}
