// Copyright 2014 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/AnimationInputHelpers.h"

#include "bindings/core/v8/ExceptionState.h"
#include "core/animation/PropertyHandle.h"
#include "core/css/CSSValueList.h"
#include "core/css/parser/CSSParser.h"
#include "core/css/parser/CSSVariableParser.h"
#include "core/css/resolver/CSSToStyleMap.h"
#include "core/dom/Document.h"
#include "core/frame/Deprecation.h"
#include "core/svg/SVGElement.h"
#include "core/svg/animation/SVGSMILElement.h"
#include "core/svg_names.h"
#include "platform/wtf/text/StringBuilder.h"

namespace blink {

const char kSVGPrefix[] = "svg-";
const unsigned kSVGPrefixLength = sizeof(kSVGPrefix) - 1;

static bool IsSVGPrefixed(const String& property) {
  return property.StartsWith(kSVGPrefix);
}

static String RemoveSVGPrefix(const String& property) {
  DCHECK(IsSVGPrefixed(property));
  return property.Substring(kSVGPrefixLength);
}

static String CSSPropertyToKeyframeAttribute(CSSPropertyID property) {
  DCHECK_NE(property, CSSPropertyInvalid);
  DCHECK_NE(property, CSSPropertyVariable);

  switch (property) {
    case CSSPropertyFloat:
      return "cssFloat";
    case CSSPropertyOffset:
      return "cssOffset";
    default:
      return getJSPropertyName(property);
  }
}

static String PresentationAttributeToKeyframeAttribute(
    CSSPropertyID presentation_attribute) {
  StringBuilder builder;
  builder.Append(kSVGPrefix, kSVGPrefixLength);
  builder.Append(getPropertyName(presentation_attribute));
  return builder.ToString();
}

CSSPropertyID AnimationInputHelpers::KeyframeAttributeToCSSProperty(
    const String& property,
    const Document& document) {
  if (CSSVariableParser::IsValidVariableName(property))
    return CSSPropertyVariable;

  // Disallow prefixed properties.
  if (property[0] == '-')
    return CSSPropertyInvalid;
  if (IsASCIIUpper(property[0]))
    return CSSPropertyInvalid;
  if (property == "cssFloat")
    return CSSPropertyFloat;
  if (property == "cssOffset")
    return CSSPropertyOffset;

  StringBuilder builder;
  for (size_t i = 0; i < property.length(); ++i) {
    // Disallow hyphenated properties.
    if (property[i] == '-')
      return CSSPropertyInvalid;
    if (IsASCIIUpper(property[i]))
      builder.Append('-');
    builder.Append(property[i]);
  }
  return cssPropertyID(builder.ToString());
}

CSSPropertyID AnimationInputHelpers::KeyframeAttributeToPresentationAttribute(
    const String& property,
    const Element& element) {
  if (!RuntimeEnabledFeatures::WebAnimationsSVGEnabled() ||
      !element.IsSVGElement() || !IsSVGPrefixed(property))
    return CSSPropertyInvalid;

  String unprefixed_property = RemoveSVGPrefix(property);
  if (SVGElement::IsAnimatableCSSProperty(QualifiedName(
          g_null_atom, AtomicString(unprefixed_property), g_null_atom)))
    return cssPropertyID(unprefixed_property);

  return CSSPropertyInvalid;
}

using AttributeNameMap = HashMap<QualifiedName, const QualifiedName*>;

const AttributeNameMap& GetSupportedAttributes() {
  DEFINE_STATIC_LOCAL(AttributeNameMap, supported_attributes, ());
  if (supported_attributes.IsEmpty()) {
    // Fill the set for the first use.
    // Animatable attributes from http://www.w3.org/TR/SVG/attindex.html
    const QualifiedName* attributes[] = {
        &HTMLNames::classAttr,
        &SVGNames::amplitudeAttr,
        &SVGNames::azimuthAttr,
        &SVGNames::baseFrequencyAttr,
        &SVGNames::biasAttr,
        &SVGNames::clipPathUnitsAttr,
        &SVGNames::cxAttr,
        &SVGNames::cyAttr,
        &SVGNames::dAttr,
        &SVGNames::diffuseConstantAttr,
        &SVGNames::divisorAttr,
        &SVGNames::dxAttr,
        &SVGNames::dyAttr,
        &SVGNames::edgeModeAttr,
        &SVGNames::elevationAttr,
        &SVGNames::exponentAttr,
        &SVGNames::filterUnitsAttr,
        &SVGNames::fxAttr,
        &SVGNames::fyAttr,
        &SVGNames::gradientTransformAttr,
        &SVGNames::gradientUnitsAttr,
        &SVGNames::heightAttr,
        &SVGNames::hrefAttr,
        &SVGNames::in2Attr,
        &SVGNames::inAttr,
        &SVGNames::interceptAttr,
        &SVGNames::k1Attr,
        &SVGNames::k2Attr,
        &SVGNames::k3Attr,
        &SVGNames::k4Attr,
        &SVGNames::kernelMatrixAttr,
        &SVGNames::kernelUnitLengthAttr,
        &SVGNames::lengthAdjustAttr,
        &SVGNames::limitingConeAngleAttr,
        &SVGNames::markerHeightAttr,
        &SVGNames::markerUnitsAttr,
        &SVGNames::markerWidthAttr,
        &SVGNames::maskContentUnitsAttr,
        &SVGNames::maskUnitsAttr,
        &SVGNames::methodAttr,
        &SVGNames::modeAttr,
        &SVGNames::numOctavesAttr,
        &SVGNames::offsetAttr,
        &SVGNames::operatorAttr,
        &SVGNames::orderAttr,
        &SVGNames::orientAttr,
        &SVGNames::pathLengthAttr,
        &SVGNames::patternContentUnitsAttr,
        &SVGNames::patternTransformAttr,
        &SVGNames::patternUnitsAttr,
        &SVGNames::pointsAtXAttr,
        &SVGNames::pointsAtYAttr,
        &SVGNames::pointsAtZAttr,
        &SVGNames::pointsAttr,
        &SVGNames::preserveAlphaAttr,
        &SVGNames::preserveAspectRatioAttr,
        &SVGNames::primitiveUnitsAttr,
        &SVGNames::rAttr,
        &SVGNames::radiusAttr,
        &SVGNames::refXAttr,
        &SVGNames::refYAttr,
        &SVGNames::resultAttr,
        &SVGNames::rotateAttr,
        &SVGNames::rxAttr,
        &SVGNames::ryAttr,
        &SVGNames::scaleAttr,
        &SVGNames::seedAttr,
        &SVGNames::slopeAttr,
        &SVGNames::spacingAttr,
        &SVGNames::specularConstantAttr,
        &SVGNames::specularExponentAttr,
        &SVGNames::spreadMethodAttr,
        &SVGNames::startOffsetAttr,
        &SVGNames::stdDeviationAttr,
        &SVGNames::stitchTilesAttr,
        &SVGNames::surfaceScaleAttr,
        &SVGNames::tableValuesAttr,
        &SVGNames::targetAttr,
        &SVGNames::targetXAttr,
        &SVGNames::targetYAttr,
        &SVGNames::textLengthAttr,
        &SVGNames::transformAttr,
        &SVGNames::typeAttr,
        &SVGNames::valuesAttr,
        &SVGNames::viewBoxAttr,
        &SVGNames::widthAttr,
        &SVGNames::x1Attr,
        &SVGNames::x2Attr,
        &SVGNames::xAttr,
        &SVGNames::xChannelSelectorAttr,
        &SVGNames::y1Attr,
        &SVGNames::y2Attr,
        &SVGNames::yAttr,
        &SVGNames::yChannelSelectorAttr,
        &SVGNames::zAttr,
    };
    for (size_t i = 0; i < WTF_ARRAY_LENGTH(attributes); i++) {
      DCHECK(!SVGElement::IsAnimatableCSSProperty(*attributes[i]));
      supported_attributes.Set(*attributes[i], attributes[i]);
    }
  }
  return supported_attributes;
}

QualifiedName SvgAttributeName(const String& property) {
  DCHECK(!IsSVGPrefixed(property));
  return QualifiedName(g_null_atom, AtomicString(property), g_null_atom);
}

const QualifiedName* AnimationInputHelpers::KeyframeAttributeToSVGAttribute(
    const String& property,
    Element& element) {
  if (!RuntimeEnabledFeatures::WebAnimationsSVGEnabled() ||
      !element.IsSVGElement() || !IsSVGPrefixed(property))
    return nullptr;

  SVGElement& svg_element = ToSVGElement(element);
  if (IsSVGSMILElement(svg_element))
    return nullptr;

  String unprefixed_property = RemoveSVGPrefix(property);
  QualifiedName attribute_name = SvgAttributeName(unprefixed_property);
  const AttributeNameMap& supported_attributes = GetSupportedAttributes();
  auto iter = supported_attributes.find(attribute_name);
  if (iter == supported_attributes.end() ||
      !svg_element.PropertyFromAttribute(*iter->value))
    return nullptr;

  return iter->value;
}

scoped_refptr<TimingFunction> AnimationInputHelpers::ParseTimingFunction(
    const String& string,
    Document* document,
    ExceptionState& exception_state) {
  if (string.IsEmpty()) {
    exception_state.ThrowTypeError("Easing may not be the empty string");
    return nullptr;
  }

  // Fallback to an insecure parsing mode if we weren't provided with a
  // document.
  SecureContextMode secure_context_mode =
      document ? document->SecureContextMode()
               : SecureContextMode::kInsecureContext;
  const CSSValue* value =
      CSSParser::ParseSingleValue(CSSPropertyTransitionTimingFunction, string,
                                  StrictCSSParserContext(secure_context_mode));
  if (!value || !value->IsValueList()) {
    DCHECK(!value || value->IsCSSWideKeyword());
    exception_state.ThrowTypeError("'" + string +
                                   "' is not a valid value for easing");
    return nullptr;
  }
  const CSSValueList* value_list = ToCSSValueList(value);
  if (value_list->length() > 1) {
    exception_state.ThrowTypeError("Easing may not be set to a list of values");
    return nullptr;
  }
  return CSSToStyleMap::MapAnimationTimingFunction(value_list->Item(0), true,
                                                   document);
}

String AnimationInputHelpers::PropertyHandleToKeyframeAttribute(
    PropertyHandle property) {
  if (property.IsCSSProperty()) {
    return property.IsCSSCustomProperty()
               ? property.CustomPropertyName()
               : CSSPropertyToKeyframeAttribute(
                     property.GetCSSProperty().PropertyID());
  }

  if (property.IsPresentationAttribute()) {
    return PresentationAttributeToKeyframeAttribute(
        property.PresentationAttribute().PropertyID());
  }

  DCHECK(property.IsSVGAttribute());
  return property.SvgAttribute().LocalName();
}

}  // namespace blink
