/*
 * Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
 * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
 *
 * 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 "third_party/blink/renderer/core/svg/svg_fe_composite_element.h"

#include "third_party/blink/renderer/core/svg/graphics/filters/svg_filter_builder.h"
#include "third_party/blink/renderer/core/svg/svg_enumeration_map.h"
#include "third_party/blink/renderer/core/svg_names.h"

namespace blink {

template <>
const SVGEnumerationMap& GetEnumerationMap<CompositeOperationType>() {
  static const SVGEnumerationMap::Entry enum_items[] = {
      {FECOMPOSITE_OPERATOR_OVER, "over"},
      {FECOMPOSITE_OPERATOR_IN, "in"},
      {FECOMPOSITE_OPERATOR_OUT, "out"},
      {FECOMPOSITE_OPERATOR_ATOP, "atop"},
      {FECOMPOSITE_OPERATOR_XOR, "xor"},
      {FECOMPOSITE_OPERATOR_ARITHMETIC, "arithmetic"},
      {FECOMPOSITE_OPERATOR_LIGHTER, "lighter"},
  };
  static const SVGEnumerationMap entries(enum_items,
                                         FECOMPOSITE_OPERATOR_ARITHMETIC);
  return entries;
}

inline SVGFECompositeElement::SVGFECompositeElement(Document& document)
    : SVGFilterPrimitiveStandardAttributes(svg_names::kFECompositeTag,
                                           document),
      k1_(SVGAnimatedNumber::Create(this, svg_names::kK1Attr, 0.0f)),
      k2_(SVGAnimatedNumber::Create(this, svg_names::kK2Attr, 0.0f)),
      k3_(SVGAnimatedNumber::Create(this, svg_names::kK3Attr, 0.0f)),
      k4_(SVGAnimatedNumber::Create(this, svg_names::kK4Attr, 0.0f)),
      in1_(SVGAnimatedString::Create(this, svg_names::kInAttr)),
      in2_(SVGAnimatedString::Create(this, svg_names::kIn2Attr)),
      svg_operator_(SVGAnimatedEnumeration<CompositeOperationType>::Create(
          this,
          svg_names::kOperatorAttr,
          FECOMPOSITE_OPERATOR_OVER)) {
  AddToPropertyMap(k1_);
  AddToPropertyMap(k2_);
  AddToPropertyMap(k3_);
  AddToPropertyMap(k4_);
  AddToPropertyMap(in1_);
  AddToPropertyMap(in2_);
  AddToPropertyMap(svg_operator_);
}

void SVGFECompositeElement::Trace(blink::Visitor* visitor) {
  visitor->Trace(k1_);
  visitor->Trace(k2_);
  visitor->Trace(k3_);
  visitor->Trace(k4_);
  visitor->Trace(in1_);
  visitor->Trace(in2_);
  visitor->Trace(svg_operator_);
  SVGFilterPrimitiveStandardAttributes::Trace(visitor);
}

DEFINE_NODE_FACTORY(SVGFECompositeElement)

bool SVGFECompositeElement::SetFilterEffectAttribute(
    FilterEffect* effect,
    const QualifiedName& attr_name) {
  FEComposite* composite = static_cast<FEComposite*>(effect);
  if (attr_name == svg_names::kOperatorAttr)
    return composite->SetOperation(svg_operator_->CurrentValue()->EnumValue());
  if (attr_name == svg_names::kK1Attr)
    return composite->SetK1(k1_->CurrentValue()->Value());
  if (attr_name == svg_names::kK2Attr)
    return composite->SetK2(k2_->CurrentValue()->Value());
  if (attr_name == svg_names::kK3Attr)
    return composite->SetK3(k3_->CurrentValue()->Value());
  if (attr_name == svg_names::kK4Attr)
    return composite->SetK4(k4_->CurrentValue()->Value());

  return SVGFilterPrimitiveStandardAttributes::SetFilterEffectAttribute(
      effect, attr_name);
}

void SVGFECompositeElement::SvgAttributeChanged(
    const QualifiedName& attr_name) {
  if (attr_name == svg_names::kOperatorAttr ||
      attr_name == svg_names::kK1Attr || attr_name == svg_names::kK2Attr ||
      attr_name == svg_names::kK3Attr || attr_name == svg_names::kK4Attr) {
    SVGElement::InvalidationGuard invalidation_guard(this);
    PrimitiveAttributeChanged(attr_name);
    return;
  }

  if (attr_name == svg_names::kInAttr || attr_name == svg_names::kIn2Attr) {
    SVGElement::InvalidationGuard invalidation_guard(this);
    Invalidate();
    return;
  }

  SVGFilterPrimitiveStandardAttributes::SvgAttributeChanged(attr_name);
}

FilterEffect* SVGFECompositeElement::Build(SVGFilterBuilder* filter_builder,
                                           Filter* filter) {
  FilterEffect* input1 = filter_builder->GetEffectById(
      AtomicString(in1_->CurrentValue()->Value()));
  FilterEffect* input2 = filter_builder->GetEffectById(
      AtomicString(in2_->CurrentValue()->Value()));
  DCHECK(input1);
  DCHECK(input2);

  FilterEffect* effect = FEComposite::Create(
      filter, svg_operator_->CurrentValue()->EnumValue(),
      k1_->CurrentValue()->Value(), k2_->CurrentValue()->Value(),
      k3_->CurrentValue()->Value(), k4_->CurrentValue()->Value());
  FilterEffectVector& input_effects = effect->InputEffects();
  input_effects.ReserveCapacity(2);
  input_effects.push_back(input1);
  input_effects.push_back(input2);
  return effect;
}

}  // namespace blink
