/*
 * Copyright (C) Research In Motion Limited 2010, 2011. All rights reserved.
 * Copyright (C) 2015 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 "SVGPathBlender.h"

#include "AnimationUtilities.h"
#include "SVGPathSeg.h"
#include "SVGPathSource.h"
#include <functional>
#include <wtf/SetForScope.h>

namespace WebCore {

bool SVGPathBlender::addAnimatedPath(SVGPathSource& fromSource, SVGPathSource& toSource, SVGPathConsumer& consumer, unsigned repeatCount)
{
    SVGPathBlender blender(fromSource, toSource, &consumer);
    return blender.addAnimatedPath(repeatCount);
}

bool SVGPathBlender::blendAnimatedPath(SVGPathSource& fromSource, SVGPathSource& toSource, SVGPathConsumer& consumer, float progress)
{
    SVGPathBlender blender(fromSource, toSource, &consumer);
    return blender.blendAnimatedPath(progress);
}

bool SVGPathBlender::canBlendPaths(SVGPathSource& fromSource, SVGPathSource& toSource)
{
    SVGPathBlender blender(fromSource, toSource);
    return blender.canBlendPaths();
}

SVGPathBlender::SVGPathBlender(SVGPathSource& fromSource, SVGPathSource& toSource, SVGPathConsumer* consumer)
    : m_fromSource(fromSource)
    , m_toSource(toSource)
    , m_consumer(consumer)
{
}

// Helper functions
static inline FloatPoint blendFloatPoint(const FloatPoint& a, const FloatPoint& b, float progress)
{
    BlendingContext context { progress };
    return FloatPoint(blend(a.x(), b.x(), context), blend(a.y(), b.y(), context));
}

float SVGPathBlender::blendAnimatedDimensonalFloat(float from, float to, FloatBlendMode blendMode, float progress)
{
    if (m_addTypesCount) {
        ASSERT(m_fromMode == m_toMode);
        return from + to * m_addTypesCount;
    }

    if (m_fromMode == m_toMode)
        return blend(from, to, { progress });
    
    float fromValue = blendMode == BlendHorizontal ? m_fromCurrentPoint.x() : m_fromCurrentPoint.y();
    float toValue = blendMode == BlendHorizontal ? m_toCurrentPoint.x() : m_toCurrentPoint.y();

    // Transform toY to the coordinate mode of fromY
    float animValue = blend(from, m_fromMode == AbsoluteCoordinates ? to + toValue : to - toValue, { progress });
    
    if (m_isInFirstHalfOfAnimation)
        return animValue;
    
    // Transform the animated point to the coordinate mode, needed for the current progress.
    float currentValue = blend(fromValue, toValue, { progress });
    return m_toMode == AbsoluteCoordinates ? animValue + currentValue : animValue - currentValue;
}

FloatPoint SVGPathBlender::blendAnimatedFloatPoint(const FloatPoint& fromPoint, const FloatPoint& toPoint, float progress)
{
    if (m_addTypesCount) {
        ASSERT(m_fromMode == m_toMode);
        FloatPoint repeatedToPoint = toPoint;
        repeatedToPoint.scale(m_addTypesCount);
        return fromPoint + repeatedToPoint;
    }

    if (m_fromMode == m_toMode)
        return blendFloatPoint(fromPoint, toPoint, progress);

    // Transform toPoint to the coordinate mode of fromPoint
    FloatPoint animatedPoint = toPoint;
    if (m_fromMode == AbsoluteCoordinates)
        animatedPoint += m_toCurrentPoint;
    else
        animatedPoint.move(-m_toCurrentPoint.x(), -m_toCurrentPoint.y());

    animatedPoint = blendFloatPoint(fromPoint, animatedPoint, progress);

    if (m_isInFirstHalfOfAnimation)
        return animatedPoint;

    // Transform the animated point to the coordinate mode, needed for the current progress.
    FloatPoint currentPoint = blendFloatPoint(m_fromCurrentPoint, m_toCurrentPoint, progress);
    if (m_toMode == AbsoluteCoordinates)
        return animatedPoint + currentPoint;

    animatedPoint.move(-currentPoint.x(), -currentPoint.y());
    return animatedPoint;
}

template<typename Function> using InvokeResult = typename std::invoke_result_t<Function, SVGPathSource>::value_type;
template<typename Function> using ResultPair = std::pair<InvokeResult<Function>, InvokeResult<Function>>;
template<typename Function> static std::optional<ResultPair<Function>> pullFromSources(SVGPathSource& fromSource, SVGPathSource& toSource, Function&& function)
{
    InvokeResult<Function> fromResult;
    if (fromSource.hasMoreData()) {
        auto parsedFrom = std::invoke(function, fromSource);
        if (!parsedFrom)
            return std::nullopt;
        fromResult = WTFMove(*parsedFrom);
    }

    auto parsedTo = std::invoke(std::forward<Function>(function), toSource);
    if (!parsedTo)
        return std::nullopt;

    return ResultPair<Function> { WTFMove(fromResult), WTFMove(*parsedTo) };
}

bool SVGPathBlender::blendMoveToSegment(float progress)
{
    auto result = pullFromSources(m_fromSource, m_toSource, &SVGPathSource::parseMoveToSegment);
    if (!result)
        return false;

    if (!m_consumer)
        return true;

    auto [from, to] = *result;

    m_consumer->moveTo(blendAnimatedFloatPoint(from.targetPoint, to.targetPoint, progress), false, m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
    m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? from.targetPoint : m_fromCurrentPoint + from.targetPoint;
    m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? to.targetPoint : m_toCurrentPoint + to.targetPoint;
    return true;
}

bool SVGPathBlender::blendLineToSegment(float progress)
{
    auto result = pullFromSources(m_fromSource, m_toSource, &SVGPathSource::parseLineToSegment);
    if (!result)
        return false;

    if (!m_consumer)
        return true;

    auto [from, to] = *result;

    m_consumer->lineTo(blendAnimatedFloatPoint(from.targetPoint, to.targetPoint, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
    m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? from.targetPoint : m_fromCurrentPoint + from.targetPoint;
    m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? to.targetPoint : m_toCurrentPoint + to.targetPoint;
    return true;
}

bool SVGPathBlender::blendLineToHorizontalSegment(float progress)
{
    auto result = pullFromSources(m_fromSource, m_toSource, &SVGPathSource::parseLineToHorizontalSegment);
    if (!result)
        return false;

    if (!m_consumer)
        return true;

    auto [from, to] = *result;

    m_consumer->lineToHorizontal(blendAnimatedDimensonalFloat(from.x, to.x, BlendHorizontal, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
    m_fromCurrentPoint.setX(m_fromMode == AbsoluteCoordinates ? from.x : m_fromCurrentPoint.x() + from.x);
    m_toCurrentPoint.setX(m_toMode == AbsoluteCoordinates ? to.x : m_toCurrentPoint.x() + to.x);
    return true;
}

bool SVGPathBlender::blendLineToVerticalSegment(float progress)
{
    auto result = pullFromSources(m_fromSource, m_toSource, &SVGPathSource::parseLineToVerticalSegment);
    if (!result)
        return false;

    if (!m_consumer)
        return true;

    auto [from, to] = *result;

    m_consumer->lineToVertical(blendAnimatedDimensonalFloat(from.y, to.y, BlendVertical, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
    m_fromCurrentPoint.setY(m_fromMode == AbsoluteCoordinates ? from.y : m_fromCurrentPoint.y() + from.y);
    m_toCurrentPoint.setY(m_toMode == AbsoluteCoordinates ? to.y : m_toCurrentPoint.y() + to.y);
    return true;
}

bool SVGPathBlender::blendCurveToCubicSegment(float progress)
{
    auto result = pullFromSources(m_fromSource, m_toSource, &SVGPathSource::parseCurveToCubicSegment);
    if (!result)
        return false;

    if (!m_consumer)
        return true;

    auto [from, to] = *result;

    m_consumer->curveToCubic(blendAnimatedFloatPoint(from.point1, to.point1, progress),
        blendAnimatedFloatPoint(from.point2, to.point2, progress),
        blendAnimatedFloatPoint(from.targetPoint, to.targetPoint, progress),
        m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
    m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? from.targetPoint : m_fromCurrentPoint + from.targetPoint;
    m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? to.targetPoint : m_toCurrentPoint + to.targetPoint;
    return true;
}

bool SVGPathBlender::blendCurveToCubicSmoothSegment(float progress)
{
    auto result = pullFromSources(m_fromSource, m_toSource, &SVGPathSource::parseCurveToCubicSmoothSegment);
    if (!result)
        return false;

    if (!m_consumer)
        return true;

    auto [from, to] = *result;

    m_consumer->curveToCubicSmooth(blendAnimatedFloatPoint(from.point2, to.point2, progress),
        blendAnimatedFloatPoint(from.targetPoint, to.targetPoint, progress),
        m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
    m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? from.targetPoint : m_fromCurrentPoint + from.targetPoint;
    m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? to.targetPoint : m_toCurrentPoint + to.targetPoint;
    return true;
}

bool SVGPathBlender::blendCurveToQuadraticSegment(float progress)
{
    auto result = pullFromSources(m_fromSource, m_toSource, &SVGPathSource::parseCurveToQuadraticSegment);
    if (!result)
        return false;

    if (!m_consumer)
        return true;

    auto [from, to] = *result;

    m_consumer->curveToQuadratic(blendAnimatedFloatPoint(from.point1, to.point1, progress),
        blendAnimatedFloatPoint(from.targetPoint, to.targetPoint, progress),
        m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
    m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? from.targetPoint : m_fromCurrentPoint + from.targetPoint;
    m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? to.targetPoint : m_toCurrentPoint + to.targetPoint;
    return true;
}

bool SVGPathBlender::blendCurveToQuadraticSmoothSegment(float progress)
{
    auto result = pullFromSources(m_fromSource, m_toSource, &SVGPathSource::parseCurveToQuadraticSmoothSegment);
    if (!result)
        return false;

    if (!m_consumer)
        return true;

    auto [from, to] = *result;

    m_consumer->curveToQuadraticSmooth(blendAnimatedFloatPoint(from.targetPoint, to.targetPoint, progress), m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
    m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? from.targetPoint : m_fromCurrentPoint + from.targetPoint;
    m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? to.targetPoint : m_toCurrentPoint + to.targetPoint;
    return true;
}

bool SVGPathBlender::blendArcToSegment(float progress)
{
    auto result = pullFromSources(m_fromSource, m_toSource, &SVGPathSource::parseArcToSegment);
    if (!result)
        return false;

    if (!m_consumer)
        return true;

    auto [from, to] = *result;

    if (m_addTypesCount) {
        ASSERT(m_fromMode == m_toMode);
        auto scaledToTargetPoint = to.targetPoint;
        scaledToTargetPoint.scale(m_addTypesCount);
        m_consumer->arcTo(from.rx + to.rx * m_addTypesCount,
            from.ry + to.ry * m_addTypesCount,
            from.angle + to.angle * m_addTypesCount,
            from.largeArc || to.largeArc,
            from.sweep || to.sweep,
            from.targetPoint + scaledToTargetPoint,
            m_fromMode);
    } else {
        BlendingContext context { progress };
        m_consumer->arcTo(blend(from.rx, to.rx, context),
            blend(from.ry, to.ry, context),
            blend(from.angle, to.angle, context),
            m_isInFirstHalfOfAnimation ? from.largeArc : to.largeArc,
            m_isInFirstHalfOfAnimation ? from.sweep : to.sweep,
            blendAnimatedFloatPoint(from.targetPoint, to.targetPoint, progress),
            m_isInFirstHalfOfAnimation ? m_fromMode : m_toMode);
    }
    m_fromCurrentPoint = m_fromMode == AbsoluteCoordinates ? from.targetPoint : m_fromCurrentPoint + from.targetPoint;
    m_toCurrentPoint = m_toMode == AbsoluteCoordinates ? to.targetPoint : m_toCurrentPoint + to.targetPoint;
    return true;
}

static inline PathCoordinateMode coordinateModeOfCommand(const SVGPathSegType& type)
{
    if (type < PathSegMoveToAbs)
        return AbsoluteCoordinates;

    // Odd number = relative command
    if (type % 2)
        return RelativeCoordinates;

    return AbsoluteCoordinates;
}

static inline bool isSegmentEqual(const SVGPathSegType& fromType, const SVGPathSegType& toType, const PathCoordinateMode& fromMode, const PathCoordinateMode& toMode)
{
    if (fromType == toType && (fromType == PathSegUnknown || fromType == PathSegClosePath))
        return true;

    unsigned short from = fromType;
    unsigned short to = toType;
    if (fromMode == toMode)
        return from == to;
    if (fromMode == AbsoluteCoordinates)
        return from == to - 1;
    return to == from - 1;
}

bool SVGPathBlender::addAnimatedPath(unsigned repeatCount)
{
    SetForScope<unsigned> change(m_addTypesCount, repeatCount);
    return blendAnimatedPath(0);
}

bool SVGPathBlender::canBlendPaths()
{
    float progress = 0.5;
    bool fromSourceHadData = m_fromSource.hasMoreData();
    while (m_toSource.hasMoreData()) {
        SVGPathSegType fromCommand;
        if (fromSourceHadData) {
            auto parsedFromCommand = m_fromSource.parseSVGSegmentType();
            if (!parsedFromCommand)
                return false;
            fromCommand = *parsedFromCommand;
        }
        auto parsedtoCommand = m_toSource.parseSVGSegmentType();
        if (!parsedtoCommand)
            return false;
        SVGPathSegType toCommand = *parsedtoCommand;

        m_toMode = coordinateModeOfCommand(toCommand);
        m_fromMode = fromSourceHadData ? coordinateModeOfCommand(fromCommand) : m_toMode;
        if (m_fromMode != m_toMode && m_addTypesCount)
            return false;

        if (fromSourceHadData && !isSegmentEqual(fromCommand, toCommand, m_fromMode, m_toMode))
            return false;

        switch (toCommand) {
        case PathSegMoveToRel:
        case PathSegMoveToAbs:
            if (!blendMoveToSegment(progress))
                return false;
            break;
        case PathSegLineToRel:
        case PathSegLineToAbs:
            if (!blendLineToSegment(progress))
                return false;
            break;
        case PathSegLineToHorizontalRel:
        case PathSegLineToHorizontalAbs:
            if (!blendLineToHorizontalSegment(progress))
                return false;
            break;
        case PathSegLineToVerticalRel:
        case PathSegLineToVerticalAbs:
            if (!blendLineToVerticalSegment(progress))
                return false;
            break;
        case PathSegClosePath:
            break;
        case PathSegCurveToCubicRel:
        case PathSegCurveToCubicAbs:
            if (!blendCurveToCubicSegment(progress))
                return false;
            break;
        case PathSegCurveToCubicSmoothRel:
        case PathSegCurveToCubicSmoothAbs:
            if (!blendCurveToCubicSmoothSegment(progress))
                return false;
            break;
        case PathSegCurveToQuadraticRel:
        case PathSegCurveToQuadraticAbs:
            if (!blendCurveToQuadraticSegment(progress))
                return false;
            break;
        case PathSegCurveToQuadraticSmoothRel:
        case PathSegCurveToQuadraticSmoothAbs:
            if (!blendCurveToQuadraticSmoothSegment(progress))
                return false;
            break;
        case PathSegArcRel:
        case PathSegArcAbs:
            if (!blendArcToSegment(progress))
                return false;
            break;
        case PathSegUnknown:
            return false;
        }

        if (!fromSourceHadData)
            continue;
        if (m_fromSource.hasMoreData() != m_toSource.hasMoreData())
            return false;
        if (!m_fromSource.hasMoreData() || !m_toSource.hasMoreData())
            return true;
    }

    return true;
}

bool SVGPathBlender::blendAnimatedPath(float progress)
{
    m_isInFirstHalfOfAnimation = progress < 0.5f;

    bool fromSourceHadData = m_fromSource.hasMoreData();
    while (m_toSource.hasMoreData()) {
        SVGPathSegType fromCommand;
        if (fromSourceHadData) {
            auto parsedFromCommand = m_fromSource.parseSVGSegmentType();
            if (!parsedFromCommand)
                return false;
            fromCommand = *parsedFromCommand;
        }
        auto parsedToCommand = m_toSource.parseSVGSegmentType();
        if (!parsedToCommand)
            return false;
        SVGPathSegType toCommand = *parsedToCommand;

        m_toMode = coordinateModeOfCommand(toCommand);
        m_fromMode = fromSourceHadData ? coordinateModeOfCommand(fromCommand) : m_toMode;
        if (m_fromMode != m_toMode && m_addTypesCount)
            return false;

        if (fromSourceHadData && !isSegmentEqual(fromCommand, toCommand, m_fromMode, m_toMode))
            return false;

        switch (toCommand) {
        case PathSegMoveToRel:
        case PathSegMoveToAbs:
            if (!blendMoveToSegment(progress))
                return false;
            break;
        case PathSegLineToRel:
        case PathSegLineToAbs:
            if (!blendLineToSegment(progress))
                return false;
            break;
        case PathSegLineToHorizontalRel:
        case PathSegLineToHorizontalAbs:
            if (!blendLineToHorizontalSegment(progress))
                return false;
            break;
        case PathSegLineToVerticalRel:
        case PathSegLineToVerticalAbs:
            if (!blendLineToVerticalSegment(progress))
                return false;
            break;
        case PathSegClosePath:
            m_consumer->closePath();
            break;
        case PathSegCurveToCubicRel:
        case PathSegCurveToCubicAbs:
            if (!blendCurveToCubicSegment(progress))
                return false;
            break;
        case PathSegCurveToCubicSmoothRel:
        case PathSegCurveToCubicSmoothAbs:
            if (!blendCurveToCubicSmoothSegment(progress))
                return false;
            break;
        case PathSegCurveToQuadraticRel:
        case PathSegCurveToQuadraticAbs:
            if (!blendCurveToQuadraticSegment(progress))
                return false;
            break;
        case PathSegCurveToQuadraticSmoothRel:
        case PathSegCurveToQuadraticSmoothAbs:
            if (!blendCurveToQuadraticSmoothSegment(progress))
                return false;
            break;
        case PathSegArcRel:
        case PathSegArcAbs:
            if (!blendArcToSegment(progress))
                return false;
            break;
        case PathSegUnknown:
            return false;
        }

        if (!fromSourceHadData)
            continue;
        if (m_fromSource.hasMoreData() != m_toSource.hasMoreData())
            return false;
        if (!m_fromSource.hasMoreData() || !m_toSource.hasMoreData())
            return true;
    }

    return true;
}

}
