// 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/css/cssom/css_rotate.h"

#include "third_party/blink/renderer/core/css/css_function_value.h"
#include "third_party/blink/renderer/core/css/css_primitive_value.h"
#include "third_party/blink/renderer/core/css/cssom/css_unit_value.h"
#include "third_party/blink/renderer/core/geometry/dom_matrix.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"

namespace blink {

namespace {

bool IsValidRotateCoord(const CSSNumericValue* value) {
  return value && value->Type().MatchesNumber();
}

bool IsValidRotateAngle(const CSSNumericValue* value) {
  return value &&
         value->Type().MatchesBaseType(CSSNumericValueType::BaseType::kAngle);
}

CSSRotate* FromCSSRotate(const CSSFunctionValue& value) {
  DCHECK_EQ(value.length(), 1UL);
  CSSNumericValue* angle =
      CSSNumericValue::FromCSSValue(To<CSSPrimitiveValue>(value.Item(0)));
  return CSSRotate::Create(angle);
}

CSSRotate* FromCSSRotate3d(const CSSFunctionValue& value) {
  DCHECK_EQ(value.length(), 4UL);

  CSSNumericValue* x =
      CSSNumericValue::FromCSSValue(To<CSSPrimitiveValue>(value.Item(0)));
  CSSNumericValue* y =
      CSSNumericValue::FromCSSValue(To<CSSPrimitiveValue>(value.Item(1)));
  CSSNumericValue* z =
      CSSNumericValue::FromCSSValue(To<CSSPrimitiveValue>(value.Item(2)));
  CSSNumericValue* angle =
      CSSNumericValue::FromCSSValue(To<CSSPrimitiveValue>(value.Item(3)));

  return CSSRotate::Create(x, y, z, angle);
}

CSSRotate* FromCSSRotateXYZ(const CSSFunctionValue& value) {
  DCHECK_EQ(value.length(), 1UL);

  CSSNumericValue* angle =
      CSSNumericValue::FromCSSValue(To<CSSPrimitiveValue>(value.Item(0)));

  switch (value.FunctionType()) {
    case CSSValueID::kRotateX:
      return CSSRotate::Create(CSSUnitValue::Create(1), CSSUnitValue::Create(0),
                               CSSUnitValue::Create(0), angle);
    case CSSValueID::kRotateY:
      return CSSRotate::Create(CSSUnitValue::Create(0), CSSUnitValue::Create(1),
                               CSSUnitValue::Create(0), angle);
    case CSSValueID::kRotateZ:
      return CSSRotate::Create(CSSUnitValue::Create(0), CSSUnitValue::Create(0),
                               CSSUnitValue::Create(1), angle);
    default:
      NOTREACHED();
      return nullptr;
  }
}

}  // namespace

CSSRotate* CSSRotate::Create(CSSNumericValue* angle,
                             ExceptionState& exception_state) {
  if (!IsValidRotateAngle(angle)) {
    exception_state.ThrowTypeError("Must pass an angle to CSSRotate");
    return nullptr;
  }
  return MakeGarbageCollected<CSSRotate>(
      CSSUnitValue::Create(0), CSSUnitValue::Create(0), CSSUnitValue::Create(1),
      angle, true /* is2D */);
}

CSSRotate* CSSRotate::Create(const CSSNumberish& x,
                             const CSSNumberish& y,
                             const CSSNumberish& z,
                             CSSNumericValue* angle,
                             ExceptionState& exception_state) {
  CSSNumericValue* x_value = CSSNumericValue::FromNumberish(x);
  CSSNumericValue* y_value = CSSNumericValue::FromNumberish(y);
  CSSNumericValue* z_value = CSSNumericValue::FromNumberish(z);

  if (!IsValidRotateCoord(x_value) || !IsValidRotateCoord(y_value) ||
      !IsValidRotateCoord(z_value)) {
    exception_state.ThrowTypeError("Must specify an number unit");
    return nullptr;
  }
  if (!IsValidRotateAngle(angle)) {
    exception_state.ThrowTypeError("Must pass an angle to CSSRotate");
    return nullptr;
  }
  return MakeGarbageCollected<CSSRotate>(x_value, y_value, z_value, angle,
                                         false /* is2D */);
}

CSSRotate* CSSRotate::Create(CSSNumericValue* angle) {
  return MakeGarbageCollected<CSSRotate>(
      CSSUnitValue::Create(0), CSSUnitValue::Create(0), CSSUnitValue::Create(1),
      angle, true /* is2D */);
}

CSSRotate* CSSRotate::Create(CSSNumericValue* x,
                             CSSNumericValue* y,
                             CSSNumericValue* z,
                             CSSNumericValue* angle) {
  return MakeGarbageCollected<CSSRotate>(x, y, z, angle, false /* is2D */);
}

CSSRotate* CSSRotate::FromCSSValue(const CSSFunctionValue& value) {
  switch (value.FunctionType()) {
    case CSSValueID::kRotate:
      return FromCSSRotate(value);
    case CSSValueID::kRotate3d:
      return FromCSSRotate3d(value);
    case CSSValueID::kRotateX:
    case CSSValueID::kRotateY:
    case CSSValueID::kRotateZ:
      return FromCSSRotateXYZ(value);
    default:
      NOTREACHED();
      return nullptr;
  }
}

void CSSRotate::setAngle(CSSNumericValue* angle,
                         ExceptionState& exception_state) {
  if (!IsValidRotateAngle(angle)) {
    exception_state.ThrowTypeError("Must pass an angle to CSSRotate");
    return;
  }
  angle_ = angle;
}

DOMMatrix* CSSRotate::toMatrix(ExceptionState& exception_state) const {
  CSSUnitValue* x = x_->to(CSSPrimitiveValue::UnitType::kNumber);
  CSSUnitValue* y = y_->to(CSSPrimitiveValue::UnitType::kNumber);
  CSSUnitValue* z = z_->to(CSSPrimitiveValue::UnitType::kNumber);
  if (!x || !y || !z) {
    exception_state.ThrowTypeError(
        "Cannot create matrix if units cannot be converted to CSSUnitValue");
    return nullptr;
  }

  DOMMatrix* matrix = DOMMatrix::Create();
  CSSUnitValue* angle = angle_->to(CSSPrimitiveValue::UnitType::kDegrees);
  if (is2D()) {
    matrix->rotateAxisAngleSelf(0, 0, 1, angle->value());
  } else {
    matrix->rotateAxisAngleSelf(x->value(), y->value(), z->value(),
                                angle->value());
  }
  return matrix;
}

const CSSFunctionValue* CSSRotate::ToCSSValue() const {
  DCHECK(x_->to(CSSPrimitiveValue::UnitType::kNumber));
  DCHECK(y_->to(CSSPrimitiveValue::UnitType::kNumber));
  DCHECK(z_->to(CSSPrimitiveValue::UnitType::kNumber));
  DCHECK(angle_->to(CSSPrimitiveValue::UnitType::kRadians));

  CSSFunctionValue* result = MakeGarbageCollected<CSSFunctionValue>(
      is2D() ? CSSValueID::kRotate : CSSValueID::kRotate3d);
  if (!is2D()) {
    const CSSValue* x = x_->ToCSSValue();
    const CSSValue* y = y_->ToCSSValue();
    const CSSValue* z = z_->ToCSSValue();
    if (!x || !y || !z)
      return nullptr;

    result->Append(*x);
    result->Append(*y);
    result->Append(*z);
  }

  const CSSValue* angle = angle_->ToCSSValue();
  if (!angle)
    return nullptr;

  result->Append(*angle);
  return result;
}

void CSSRotate::setX(const CSSNumberish& x, ExceptionState& exception_state) {
  CSSNumericValue* value = CSSNumericValue::FromNumberish(x);
  if (!IsValidRotateCoord(value)) {
    exception_state.ThrowTypeError("Must specify a number unit");
    return;
  }
  x_ = value;
}

void CSSRotate::setY(const CSSNumberish& y, ExceptionState& exception_state) {
  CSSNumericValue* value = CSSNumericValue::FromNumberish(y);
  if (!IsValidRotateCoord(value)) {
    exception_state.ThrowTypeError("Must specify a number unit");
    return;
  }
  y_ = value;
}

void CSSRotate::setZ(const CSSNumberish& z, ExceptionState& exception_state) {
  CSSNumericValue* value = CSSNumericValue::FromNumberish(z);
  if (!IsValidRotateCoord(value)) {
    exception_state.ThrowTypeError("Must specify a number unit");
    return;
  }
  z_ = value;
}

CSSRotate::CSSRotate(CSSNumericValue* x,
                     CSSNumericValue* y,
                     CSSNumericValue* z,
                     CSSNumericValue* angle,
                     bool is2D)
    : CSSTransformComponent(is2D), angle_(angle), x_(x), y_(y), z_(z) {
  DCHECK(IsValidRotateCoord(x));
  DCHECK(IsValidRotateCoord(y));
  DCHECK(IsValidRotateCoord(z));
  DCHECK(IsValidRotateAngle(angle));
}

}  // namespace blink
