// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "core/animation/SVGPathSegInterpolationFunctions.h"

#include <memory>

namespace blink {

std::unique_ptr<InterpolableNumber> consumeControlAxis(double value,
                                                       bool isAbsolute,
                                                       double currentValue) {
  return InterpolableNumber::create(isAbsolute ? value : currentValue + value);
}

double consumeInterpolableControlAxis(const InterpolableValue* number,
                                      bool isAbsolute,
                                      double currentValue) {
  double value = toInterpolableNumber(number)->value();
  return isAbsolute ? value : value - currentValue;
}

std::unique_ptr<InterpolableNumber>
consumeCoordinateAxis(double value, bool isAbsolute, double& currentValue) {
  if (isAbsolute)
    currentValue = value;
  else
    currentValue += value;
  return InterpolableNumber::create(currentValue);
}

double consumeInterpolableCoordinateAxis(const InterpolableValue* number,
                                         bool isAbsolute,
                                         double& currentValue) {
  double previousValue = currentValue;
  currentValue = toInterpolableNumber(number)->value();
  return isAbsolute ? currentValue : currentValue - previousValue;
}

std::unique_ptr<InterpolableValue> consumeClosePath(
    const PathSegmentData&,
    PathCoordinates& coordinates) {
  coordinates.currentX = coordinates.initialX;
  coordinates.currentY = coordinates.initialY;
  return InterpolableList::create(0);
}

PathSegmentData consumeInterpolableClosePath(const InterpolableValue&,
                                             SVGPathSegType segType,
                                             PathCoordinates& coordinates) {
  coordinates.currentX = coordinates.initialX;
  coordinates.currentY = coordinates.initialY;

  PathSegmentData segment;
  segment.command = segType;
  return segment;
}

std::unique_ptr<InterpolableValue> consumeSingleCoordinate(
    const PathSegmentData& segment,
    PathCoordinates& coordinates) {
  bool isAbsolute = isAbsolutePathSegType(segment.command);
  std::unique_ptr<InterpolableList> result = InterpolableList::create(2);
  result->set(
      0, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.currentX));
  result->set(
      1, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.currentY));

  if (toAbsolutePathSegType(segment.command) == PathSegMoveToAbs) {
    // Any upcoming 'closepath' commands bring us back to the location we have
    // just moved to.
    coordinates.initialX = coordinates.currentX;
    coordinates.initialY = coordinates.currentY;
  }

  return std::move(result);
}

PathSegmentData consumeInterpolableSingleCoordinate(
    const InterpolableValue& value,
    SVGPathSegType segType,
    PathCoordinates& coordinates) {
  const InterpolableList& list = toInterpolableList(value);
  bool isAbsolute = isAbsolutePathSegType(segType);
  PathSegmentData segment;
  segment.command = segType;
  segment.targetPoint.setX(consumeInterpolableCoordinateAxis(
      list.get(0), isAbsolute, coordinates.currentX));
  segment.targetPoint.setY(consumeInterpolableCoordinateAxis(
      list.get(1), isAbsolute, coordinates.currentY));

  if (toAbsolutePathSegType(segType) == PathSegMoveToAbs) {
    // Any upcoming 'closepath' commands bring us back to the location we have
    // just moved to.
    coordinates.initialX = coordinates.currentX;
    coordinates.initialY = coordinates.currentY;
  }

  return segment;
}

std::unique_ptr<InterpolableValue> consumeCurvetoCubic(
    const PathSegmentData& segment,
    PathCoordinates& coordinates) {
  bool isAbsolute = isAbsolutePathSegType(segment.command);
  std::unique_ptr<InterpolableList> result = InterpolableList::create(6);
  result->set(
      0, consumeControlAxis(segment.x1(), isAbsolute, coordinates.currentX));
  result->set(
      1, consumeControlAxis(segment.y1(), isAbsolute, coordinates.currentY));
  result->set(
      2, consumeControlAxis(segment.x2(), isAbsolute, coordinates.currentX));
  result->set(
      3, consumeControlAxis(segment.y2(), isAbsolute, coordinates.currentY));
  result->set(
      4, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.currentX));
  result->set(
      5, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.currentY));
  return std::move(result);
}

PathSegmentData consumeInterpolableCurvetoCubic(const InterpolableValue& value,
                                                SVGPathSegType segType,
                                                PathCoordinates& coordinates) {
  const InterpolableList& list = toInterpolableList(value);
  bool isAbsolute = isAbsolutePathSegType(segType);
  PathSegmentData segment;
  segment.command = segType;
  segment.point1.setX(consumeInterpolableControlAxis(list.get(0), isAbsolute,
                                                     coordinates.currentX));
  segment.point1.setY(consumeInterpolableControlAxis(list.get(1), isAbsolute,
                                                     coordinates.currentY));
  segment.point2.setX(consumeInterpolableControlAxis(list.get(2), isAbsolute,
                                                     coordinates.currentX));
  segment.point2.setY(consumeInterpolableControlAxis(list.get(3), isAbsolute,
                                                     coordinates.currentY));
  segment.targetPoint.setX(consumeInterpolableCoordinateAxis(
      list.get(4), isAbsolute, coordinates.currentX));
  segment.targetPoint.setY(consumeInterpolableCoordinateAxis(
      list.get(5), isAbsolute, coordinates.currentY));
  return segment;
}

std::unique_ptr<InterpolableValue> consumeCurvetoQuadratic(
    const PathSegmentData& segment,
    PathCoordinates& coordinates) {
  bool isAbsolute = isAbsolutePathSegType(segment.command);
  std::unique_ptr<InterpolableList> result = InterpolableList::create(4);
  result->set(
      0, consumeControlAxis(segment.x1(), isAbsolute, coordinates.currentX));
  result->set(
      1, consumeControlAxis(segment.y1(), isAbsolute, coordinates.currentY));
  result->set(
      2, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.currentX));
  result->set(
      3, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.currentY));
  return std::move(result);
}

PathSegmentData consumeInterpolableCurvetoQuadratic(
    const InterpolableValue& value,
    SVGPathSegType segType,
    PathCoordinates& coordinates) {
  const InterpolableList& list = toInterpolableList(value);
  bool isAbsolute = isAbsolutePathSegType(segType);
  PathSegmentData segment;
  segment.command = segType;
  segment.point1.setX(consumeInterpolableControlAxis(list.get(0), isAbsolute,
                                                     coordinates.currentX));
  segment.point1.setY(consumeInterpolableControlAxis(list.get(1), isAbsolute,
                                                     coordinates.currentY));
  segment.targetPoint.setX(consumeInterpolableCoordinateAxis(
      list.get(2), isAbsolute, coordinates.currentX));
  segment.targetPoint.setY(consumeInterpolableCoordinateAxis(
      list.get(3), isAbsolute, coordinates.currentY));
  return segment;
}

std::unique_ptr<InterpolableValue> consumeArc(const PathSegmentData& segment,
                                              PathCoordinates& coordinates) {
  bool isAbsolute = isAbsolutePathSegType(segment.command);
  std::unique_ptr<InterpolableList> result = InterpolableList::create(7);
  result->set(
      0, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.currentX));
  result->set(
      1, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.currentY));
  result->set(2, InterpolableNumber::create(segment.r1()));
  result->set(3, InterpolableNumber::create(segment.r2()));
  result->set(4, InterpolableNumber::create(segment.arcAngle()));
  result->set(5, InterpolableBool::create(segment.largeArcFlag()));
  result->set(6, InterpolableBool::create(segment.sweepFlag()));
  return std::move(result);
}

PathSegmentData consumeInterpolableArc(const InterpolableValue& value,
                                       SVGPathSegType segType,
                                       PathCoordinates& coordinates) {
  const InterpolableList& list = toInterpolableList(value);
  bool isAbsolute = isAbsolutePathSegType(segType);
  PathSegmentData segment;
  segment.command = segType;
  segment.targetPoint.setX(consumeInterpolableCoordinateAxis(
      list.get(0), isAbsolute, coordinates.currentX));
  segment.targetPoint.setY(consumeInterpolableCoordinateAxis(
      list.get(1), isAbsolute, coordinates.currentY));
  segment.arcRadii().setX(toInterpolableNumber(list.get(2))->value());
  segment.arcRadii().setY(toInterpolableNumber(list.get(3))->value());
  segment.setArcAngle(toInterpolableNumber(list.get(4))->value());
  segment.arcLarge = toInterpolableBool(list.get(5))->value();
  segment.arcSweep = toInterpolableBool(list.get(6))->value();
  return segment;
}

std::unique_ptr<InterpolableValue> consumeLinetoHorizontal(
    const PathSegmentData& segment,
    PathCoordinates& coordinates) {
  bool isAbsolute = isAbsolutePathSegType(segment.command);
  return consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.currentX);
}

PathSegmentData consumeInterpolableLinetoHorizontal(
    const InterpolableValue& value,
    SVGPathSegType segType,
    PathCoordinates& coordinates) {
  bool isAbsolute = isAbsolutePathSegType(segType);
  PathSegmentData segment;
  segment.command = segType;
  segment.targetPoint.setX(consumeInterpolableCoordinateAxis(
      &value, isAbsolute, coordinates.currentX));
  return segment;
}

std::unique_ptr<InterpolableValue> consumeLinetoVertical(
    const PathSegmentData& segment,
    PathCoordinates& coordinates) {
  bool isAbsolute = isAbsolutePathSegType(segment.command);
  return consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.currentY);
}

PathSegmentData consumeInterpolableLinetoVertical(
    const InterpolableValue& value,
    SVGPathSegType segType,
    PathCoordinates& coordinates) {
  bool isAbsolute = isAbsolutePathSegType(segType);
  PathSegmentData segment;
  segment.command = segType;
  segment.targetPoint.setY(consumeInterpolableCoordinateAxis(
      &value, isAbsolute, coordinates.currentY));
  return segment;
}

std::unique_ptr<InterpolableValue> consumeCurvetoCubicSmooth(
    const PathSegmentData& segment,
    PathCoordinates& coordinates) {
  bool isAbsolute = isAbsolutePathSegType(segment.command);
  std::unique_ptr<InterpolableList> result = InterpolableList::create(4);
  result->set(
      0, consumeControlAxis(segment.x2(), isAbsolute, coordinates.currentX));
  result->set(
      1, consumeControlAxis(segment.y2(), isAbsolute, coordinates.currentY));
  result->set(
      2, consumeCoordinateAxis(segment.x(), isAbsolute, coordinates.currentX));
  result->set(
      3, consumeCoordinateAxis(segment.y(), isAbsolute, coordinates.currentY));
  return std::move(result);
}

PathSegmentData consumeInterpolableCurvetoCubicSmooth(
    const InterpolableValue& value,
    SVGPathSegType segType,
    PathCoordinates& coordinates) {
  const InterpolableList& list = toInterpolableList(value);
  bool isAbsolute = isAbsolutePathSegType(segType);
  PathSegmentData segment;
  segment.command = segType;
  segment.point2.setX(consumeInterpolableControlAxis(list.get(0), isAbsolute,
                                                     coordinates.currentX));
  segment.point2.setY(consumeInterpolableControlAxis(list.get(1), isAbsolute,
                                                     coordinates.currentY));
  segment.targetPoint.setX(consumeInterpolableCoordinateAxis(
      list.get(2), isAbsolute, coordinates.currentX));
  segment.targetPoint.setY(consumeInterpolableCoordinateAxis(
      list.get(3), isAbsolute, coordinates.currentY));
  return segment;
}

std::unique_ptr<InterpolableValue>
SVGPathSegInterpolationFunctions::consumePathSeg(const PathSegmentData& segment,
                                                 PathCoordinates& coordinates) {
  switch (segment.command) {
    case PathSegClosePath:
      return consumeClosePath(segment, coordinates);

    case PathSegMoveToAbs:
    case PathSegMoveToRel:
    case PathSegLineToAbs:
    case PathSegLineToRel:
    case PathSegCurveToQuadraticSmoothAbs:
    case PathSegCurveToQuadraticSmoothRel:
      return consumeSingleCoordinate(segment, coordinates);

    case PathSegCurveToCubicAbs:
    case PathSegCurveToCubicRel:
      return consumeCurvetoCubic(segment, coordinates);

    case PathSegCurveToQuadraticAbs:
    case PathSegCurveToQuadraticRel:
      return consumeCurvetoQuadratic(segment, coordinates);

    case PathSegArcAbs:
    case PathSegArcRel:
      return consumeArc(segment, coordinates);

    case PathSegLineToHorizontalAbs:
    case PathSegLineToHorizontalRel:
      return consumeLinetoHorizontal(segment, coordinates);

    case PathSegLineToVerticalAbs:
    case PathSegLineToVerticalRel:
      return consumeLinetoVertical(segment, coordinates);

    case PathSegCurveToCubicSmoothAbs:
    case PathSegCurveToCubicSmoothRel:
      return consumeCurvetoCubicSmooth(segment, coordinates);

    case PathSegUnknown:
    default:
      NOTREACHED();
      return nullptr;
  }
}

PathSegmentData SVGPathSegInterpolationFunctions::consumeInterpolablePathSeg(
    const InterpolableValue& value,
    SVGPathSegType segType,
    PathCoordinates& coordinates) {
  switch (segType) {
    case PathSegClosePath:
      return consumeInterpolableClosePath(value, segType, coordinates);

    case PathSegMoveToAbs:
    case PathSegMoveToRel:
    case PathSegLineToAbs:
    case PathSegLineToRel:
    case PathSegCurveToQuadraticSmoothAbs:
    case PathSegCurveToQuadraticSmoothRel:
      return consumeInterpolableSingleCoordinate(value, segType, coordinates);

    case PathSegCurveToCubicAbs:
    case PathSegCurveToCubicRel:
      return consumeInterpolableCurvetoCubic(value, segType, coordinates);

    case PathSegCurveToQuadraticAbs:
    case PathSegCurveToQuadraticRel:
      return consumeInterpolableCurvetoQuadratic(value, segType, coordinates);

    case PathSegArcAbs:
    case PathSegArcRel:
      return consumeInterpolableArc(value, segType, coordinates);

    case PathSegLineToHorizontalAbs:
    case PathSegLineToHorizontalRel:
      return consumeInterpolableLinetoHorizontal(value, segType, coordinates);

    case PathSegLineToVerticalAbs:
    case PathSegLineToVerticalRel:
      return consumeInterpolableLinetoVertical(value, segType, coordinates);

    case PathSegCurveToCubicSmoothAbs:
    case PathSegCurveToCubicSmoothRel:
      return consumeInterpolableCurvetoCubicSmooth(value, segType, coordinates);

    case PathSegUnknown:
    default:
      NOTREACHED();
      return PathSegmentData();
  }
}

}  // namespace blink
