// Copyright 2016 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 "third_party/blink/renderer/core/animation/interpolable_length.h"

#include "third_party/blink/renderer/core/animation/underlying_value.h"
#include "third_party/blink/renderer/core/css/css_math_expression_node.h"
#include "third_party/blink/renderer/core/css/css_math_function_value.h"
#include "third_party/blink/renderer/core/css/css_numeric_literal_value.h"
#include "third_party/blink/renderer/core/css/css_to_length_conversion_data.h"
#include "third_party/blink/renderer/platform/geometry/blend.h"
#include "third_party/blink/renderer/platform/geometry/calculation_value.h"

namespace blink {

using UnitType = CSSPrimitiveValue::UnitType;

namespace {

CSSMathExpressionNode* NumberNode(double number) {
  return CSSMathExpressionNumericLiteral::Create(
      CSSNumericLiteralValue::Create(number, UnitType::kNumber));
}

CSSMathExpressionNode* PercentageNode(double number) {
  return CSSMathExpressionNumericLiteral::Create(
      CSSNumericLiteralValue::Create(number, UnitType::kPercentage));
}

}  // namespace

// static
std::unique_ptr<InterpolableLength> InterpolableLength::CreatePixels(
    double pixels) {
  CSSLengthArray length_array;
  length_array.values[CSSPrimitiveValue::kUnitTypePixels] = pixels;
  length_array.type_flags.set(CSSPrimitiveValue::kUnitTypePixels);
  return std::make_unique<InterpolableLength>(std::move(length_array));
}

// static
std::unique_ptr<InterpolableLength> InterpolableLength::CreatePercent(
    double percent) {
  CSSLengthArray length_array;
  length_array.values[CSSPrimitiveValue::kUnitTypePercentage] = percent;
  length_array.type_flags.set(CSSPrimitiveValue::kUnitTypePercentage);
  return std::make_unique<InterpolableLength>(std::move(length_array));
}

// static
std::unique_ptr<InterpolableLength> InterpolableLength::CreateNeutral() {
  return std::make_unique<InterpolableLength>(CSSLengthArray());
}

// static
std::unique_ptr<InterpolableLength> InterpolableLength::MaybeConvertCSSValue(
    const CSSValue& value) {
  const auto* primitive_value = DynamicTo<CSSPrimitiveValue>(value);
  if (!primitive_value)
    return nullptr;

  if (!primitive_value->IsLength() && !primitive_value->IsPercentage() &&
      !primitive_value->IsCalculatedPercentageWithLength())
    return nullptr;

  CSSLengthArray length_array;
  if (primitive_value->AccumulateLengthArray(length_array))
    return std::make_unique<InterpolableLength>(std::move(length_array));

  DCHECK(primitive_value->IsMathFunctionValue());
  return std::make_unique<InterpolableLength>(
      *To<CSSMathFunctionValue>(primitive_value)->ExpressionNode());
}

// static
std::unique_ptr<InterpolableLength> InterpolableLength::MaybeConvertLength(
    const Length& length,
    float zoom) {
  if (!length.IsSpecified())
    return nullptr;

  if (length.IsCalculated() && length.GetCalculationValue().IsExpression()) {
    auto unzoomed_calc = length.GetCalculationValue().Zoom(1.0 / zoom);
    return std::make_unique<InterpolableLength>(
        *CSSMathExpressionNode::Create(*unzoomed_calc));
  }

  PixelsAndPercent pixels_and_percent = length.GetPixelsAndPercent();
  CSSLengthArray length_array;

  length_array.values[CSSPrimitiveValue::kUnitTypePixels] =
      pixels_and_percent.pixels / zoom;
  length_array.type_flags[CSSPrimitiveValue::kUnitTypePixels] =
      pixels_and_percent.pixels != 0;

  length_array.values[CSSPrimitiveValue::kUnitTypePercentage] =
      pixels_and_percent.percent;
  length_array.type_flags[CSSPrimitiveValue::kUnitTypePercentage] =
      length.IsPercentOrCalc();
  return std::make_unique<InterpolableLength>(std::move(length_array));
}

// static
PairwiseInterpolationValue InterpolableLength::MergeSingles(
    std::unique_ptr<InterpolableValue> start,
    std::unique_ptr<InterpolableValue> end) {
  // TODO(crbug.com/991672): We currently have a lot of "fast paths" that do not
  // go through here, and hence, do not merge the percentage info of two
  // lengths. We should stop doing that.
  auto& start_length = To<InterpolableLength>(*start);
  auto& end_length = To<InterpolableLength>(*end);
  if (start_length.HasPercentage() || end_length.HasPercentage()) {
    start_length.SetHasPercentage();
    end_length.SetHasPercentage();
  }
  if (start_length.IsExpression() || end_length.IsExpression()) {
    start_length.SetExpression(start_length.AsExpression());
    end_length.SetExpression(end_length.AsExpression());
  }
  return PairwiseInterpolationValue(std::move(start), std::move(end));
}

InterpolableLength::InterpolableLength(CSSLengthArray&& length_array) {
  SetLengthArray(std::move(length_array));
}

void InterpolableLength::SetLengthArray(CSSLengthArray&& length_array) {
  type_ = Type::kLengthArray;
  length_array_ = std::move(length_array);
  expression_.Clear();
}

InterpolableLength::InterpolableLength(
    const CSSMathExpressionNode& expression) {
  SetExpression(expression);
}

void InterpolableLength::SetExpression(
    const CSSMathExpressionNode& expression) {
  type_ = Type::kExpression;
  expression_ = &expression;
}

InterpolableLength* InterpolableLength::RawClone() const {
  return new InterpolableLength(*this);
}

bool InterpolableLength::HasPercentage() const {
  if (IsLengthArray()) {
    return length_array_.type_flags.test(
        CSSPrimitiveValue::kUnitTypePercentage);
  }
  return expression_->HasPercentage();
}

void InterpolableLength::SetHasPercentage() {
  if (HasPercentage())
    return;

  if (IsLengthArray()) {
    length_array_.type_flags.set(CSSPrimitiveValue::kUnitTypePercentage);
    return;
  }

  DEFINE_STATIC_LOCAL(Persistent<CSSMathExpressionNode>, zero_percent,
                      {PercentageNode(0)});
  SetExpression(*CSSMathExpressionBinaryOperation::Create(
      expression_, zero_percent, CSSMathOperator::kAdd));
}

void InterpolableLength::SubtractFromOneHundredPercent() {
  if (IsLengthArray()) {
    for (double& value : length_array_.values)
      value *= -1;
    length_array_.values[CSSPrimitiveValue::kUnitTypePercentage] += 100;
    length_array_.type_flags.set(CSSPrimitiveValue::kUnitTypePercentage);
    return;
  }

  DEFINE_STATIC_LOCAL(Persistent<CSSMathExpressionNode>, hundred_percent,
                      {PercentageNode(100)});
  SetExpression(*CSSMathExpressionBinaryOperation::CreateSimplified(
      hundred_percent, expression_, CSSMathOperator::kSubtract));
}

static double ClampToRange(double x, ValueRange range) {
  return (range == kValueRangeNonNegative && x < 0) ? 0 : x;
}

static const CSSNumericLiteralValue& ClampNumericLiteralValueToRange(
    const CSSNumericLiteralValue& value,
    ValueRange range) {
  if (range == kValueRangeAll || value.DoubleValue() >= 0)
    return value;
  return *CSSNumericLiteralValue::Create(0, value.GetType());
}

static UnitType IndexToUnitType(wtf_size_t index) {
  return CSSPrimitiveValue::LengthUnitTypeToUnitType(
      static_cast<CSSPrimitiveValue::LengthUnitType>(index));
}

Length InterpolableLength::CreateLength(
    const CSSToLengthConversionData& conversion_data,
    ValueRange range) const {
  // Passing true for ToCalcValue is a dirty hack to ensure that we don't create
  // a degenerate value when animating 'background-position', while we know it
  // may cause some minor animation glitches for the other properties.
  if (IsExpression())
    return Length(expression_->ToCalcValue(conversion_data, range, true));

  bool has_percentage = HasPercentage();
  double pixels = 0;
  double percentage = 0;
  for (wtf_size_t i = 0; i < length_array_.values.size(); ++i) {
    double value = length_array_.values[i];
    if (value == 0)
      continue;
    if (i == CSSPrimitiveValue::kUnitTypePercentage) {
      percentage = value;
    } else {
      pixels += conversion_data.ZoomedComputedPixels(value, IndexToUnitType(i));
    }
  }

  if (percentage != 0)
    has_percentage = true;
  if (pixels != 0 && has_percentage) {
    return Length(CalculationValue::Create(
        PixelsAndPercent(clampTo<float>(pixels), clampTo<float>(percentage)),
        range));
  }
  if (has_percentage)
    return Length::Percent(ClampToRange(percentage, range));
  return Length::Fixed(
      CSSPrimitiveValue::ClampToCSSLengthRange(ClampToRange(pixels, range)));
}

const CSSPrimitiveValue* InterpolableLength::CreateCSSValue(
    ValueRange range) const {
  if (IsExpression())
    return CSSMathFunctionValue::Create(expression_, range);

  DCHECK(IsLengthArray());
  if (length_array_.type_flags.count() > 1u) {
    const CSSMathExpressionNode& expression = AsExpression();
    if (!expression.IsNumericLiteral())
      return CSSMathFunctionValue::Create(&AsExpression(), range);

    // This creates a temporary CSSMathExpressionNode. Eliminate it if this
    // results in significant performance regression.
    return &ClampNumericLiteralValueToRange(
        To<CSSMathExpressionNumericLiteral>(expression).GetValue(), range);
  }

  for (wtf_size_t i = 0; i < length_array_.values.size(); ++i) {
    if (length_array_.type_flags.test(i)) {
      double value = ClampToRange(length_array_.values[i], range);
      UnitType unit_type = IndexToUnitType(i);
      return CSSNumericLiteralValue::Create(value, unit_type);
    }
  }

  return CSSNumericLiteralValue::Create(0, UnitType::kPixels);
}

const CSSMathExpressionNode& InterpolableLength::AsExpression() const {
  if (IsExpression())
    return *expression_;

  DCHECK(IsLengthArray());
  bool has_percentage = HasPercentage();

  CSSMathExpressionNode* root_node = nullptr;
  for (wtf_size_t i = 0; i < length_array_.values.size(); ++i) {
    double value = length_array_.values[i];
    if (value == 0 &&
        (i != CSSPrimitiveValue::kUnitTypePercentage || !has_percentage)) {
      continue;
    }
    CSSNumericLiteralValue* current_value =
        CSSNumericLiteralValue::Create(value, IndexToUnitType(i));
    CSSMathExpressionNode* current_node =
        CSSMathExpressionNumericLiteral::Create(current_value);
    if (!root_node) {
      root_node = current_node;
    } else {
      root_node = CSSMathExpressionBinaryOperation::Create(
          root_node, current_node, CSSMathOperator::kAdd);
    }
  }

  if (root_node)
    return *root_node;
  return *CSSMathExpressionNumericLiteral::Create(
      CSSNumericLiteralValue::Create(0, UnitType::kPixels));
}

void InterpolableLength::Scale(double scale) {
  if (IsLengthArray()) {
    for (auto& value : length_array_.values)
      value *= scale;
    return;
  }

  DCHECK(IsExpression());
  SetExpression(*CSSMathExpressionBinaryOperation::CreateSimplified(
      expression_, NumberNode(scale), CSSMathOperator::kMultiply));
}

void InterpolableLength::Add(const InterpolableValue& other) {
  const InterpolableLength& other_length = To<InterpolableLength>(other);
  if (IsLengthArray() && other_length.IsLengthArray()) {
    for (wtf_size_t i = 0; i < length_array_.values.size(); ++i) {
      length_array_.values[i] =
          length_array_.values[i] + other_length.length_array_.values[i];
    }
    length_array_.type_flags |= other_length.length_array_.type_flags;
    return;
  }

  CSSMathExpressionNode* result =
      CSSMathExpressionBinaryOperation::CreateSimplified(
          &AsExpression(), &other_length.AsExpression(), CSSMathOperator::kAdd);
  SetExpression(*result);
}

void InterpolableLength::ScaleAndAdd(double scale,
                                     const InterpolableValue& other) {
  const InterpolableLength& other_length = To<InterpolableLength>(other);
  if (IsLengthArray() && other_length.IsLengthArray()) {
    for (wtf_size_t i = 0; i < length_array_.values.size(); ++i) {
      length_array_.values[i] = length_array_.values[i] * scale +
                                other_length.length_array_.values[i];
    }
    length_array_.type_flags |= other_length.length_array_.type_flags;
    return;
  }

  CSSMathExpressionNode* scaled =
      CSSMathExpressionBinaryOperation::CreateSimplified(
          &AsExpression(), NumberNode(scale), CSSMathOperator::kMultiply);
  CSSMathExpressionNode* result =
      CSSMathExpressionBinaryOperation::CreateSimplified(
          scaled, &other_length.AsExpression(), CSSMathOperator::kAdd);
  SetExpression(*result);
}

void InterpolableLength::AssertCanInterpolateWith(
    const InterpolableValue& other) const {
  DCHECK(other.IsLength());
  // TODO(crbug.com/991672): Ensure that all |MergeSingles| variants that merge
  // two |InterpolableLength| objects should also assign them the same shape
  // (i.e. type flags) after merging into a |PairwiseInterpolationValue|. We
  // currently fail to do that, and hit the following DCHECK:
  // DCHECK_EQ(HasPercentage(),
  //           To<InterpolableLength>(other).HasPercentage());
}

void InterpolableLength::Interpolate(const InterpolableValue& to,
                                     const double progress,
                                     InterpolableValue& result) const {
  const auto& to_length = To<InterpolableLength>(to);
  auto& result_length = To<InterpolableLength>(result);
  if (IsLengthArray() && to_length.IsLengthArray()) {
    if (!result_length.IsLengthArray())
      result_length.SetLengthArray(CSSLengthArray());
    const CSSLengthArray& to_length_array = to_length.length_array_;
    CSSLengthArray& result_length_array =
        To<InterpolableLength>(result).length_array_;
    for (wtf_size_t i = 0; i < length_array_.values.size(); ++i) {
      result_length_array.values[i] =
          Blend(length_array_.values[i], to_length_array.values[i], progress);
    }
    result_length_array.type_flags =
        length_array_.type_flags | to_length_array.type_flags;
    return;
  }

  CSSMathExpressionNode* blended_from =
      CSSMathExpressionBinaryOperation::CreateSimplified(
          &AsExpression(), NumberNode(1 - progress),
          CSSMathOperator::kMultiply);
  CSSMathExpressionNode* blended_to =
      CSSMathExpressionBinaryOperation::CreateSimplified(
          &to_length.AsExpression(), NumberNode(progress),
          CSSMathOperator::kMultiply);
  CSSMathExpressionNode* result_expression =
      CSSMathExpressionBinaryOperation::CreateSimplified(
          blended_from, blended_to, CSSMathOperator::kAdd);
  result_length.SetExpression(*result_expression);

  DCHECK_EQ(result_length.HasPercentage(),
            HasPercentage() || to_length.HasPercentage());
}

}  // namespace blink
