/*
 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann
 * <zimmermann@kde.org>
 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
 *
 * 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 "core/svg/SVGMarkerElement.h"

#include "core/SVGNames.h"
#include "core/layout/svg/LayoutSVGResourceMarker.h"
#include "core/svg/SVGAngleTearOff.h"

namespace blink {

template <>
const SVGEnumerationStringEntries&
getStaticStringEntries<SVGMarkerUnitsType>() {
  DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
  if (entries.isEmpty()) {
    entries.append(
        std::make_pair(SVGMarkerUnitsUserSpaceOnUse, "userSpaceOnUse"));
    entries.append(std::make_pair(SVGMarkerUnitsStrokeWidth, "strokeWidth"));
  }
  return entries;
}

inline SVGMarkerElement::SVGMarkerElement(Document& document)
    : SVGElement(SVGNames::markerTag, document),
      SVGFitToViewBox(this),
      m_refX(
          SVGAnimatedLength::create(this,
                                    SVGNames::refXAttr,
                                    SVGLength::create(SVGLengthMode::Width))),
      m_refY(
          SVGAnimatedLength::create(this,
                                    SVGNames::refYAttr,
                                    SVGLength::create(SVGLengthMode::Height))),
      m_markerWidth(
          SVGAnimatedLength::create(this,
                                    SVGNames::markerWidthAttr,
                                    SVGLength::create(SVGLengthMode::Width))),
      m_markerHeight(
          SVGAnimatedLength::create(this,
                                    SVGNames::markerHeightAttr,
                                    SVGLength::create(SVGLengthMode::Height))),
      m_orientAngle(SVGAnimatedAngle::create(this)),
      m_markerUnits(SVGAnimatedEnumeration<SVGMarkerUnitsType>::create(
          this,
          SVGNames::markerUnitsAttr,
          SVGMarkerUnitsStrokeWidth)) {
  // Spec: If the markerWidth/markerHeight attribute is not specified, the
  // effect is as if a value of "3" were specified.
  m_markerWidth->setDefaultValueAsString("3");
  m_markerHeight->setDefaultValueAsString("3");

  addToPropertyMap(m_refX);
  addToPropertyMap(m_refY);
  addToPropertyMap(m_markerWidth);
  addToPropertyMap(m_markerHeight);
  addToPropertyMap(m_orientAngle);
  addToPropertyMap(m_markerUnits);
}

DEFINE_TRACE(SVGMarkerElement) {
  visitor->trace(m_refX);
  visitor->trace(m_refY);
  visitor->trace(m_markerWidth);
  visitor->trace(m_markerHeight);
  visitor->trace(m_orientAngle);
  visitor->trace(m_markerUnits);
  SVGElement::trace(visitor);
  SVGFitToViewBox::trace(visitor);
}

DEFINE_NODE_FACTORY(SVGMarkerElement)

AffineTransform SVGMarkerElement::viewBoxToViewTransform(
    float viewWidth,
    float viewHeight) const {
  return SVGFitToViewBox::viewBoxToViewTransform(
      viewBox()->currentValue()->value(), preserveAspectRatio()->currentValue(),
      viewWidth, viewHeight);
}

void SVGMarkerElement::svgAttributeChanged(const QualifiedName& attrName) {
  bool isLengthAttr = attrName == SVGNames::refXAttr ||
                      attrName == SVGNames::refYAttr ||
                      attrName == SVGNames::markerWidthAttr ||
                      attrName == SVGNames::markerHeightAttr;

  if (isLengthAttr)
    updateRelativeLengthsInformation();

  if (isLengthAttr || attrName == SVGNames::markerUnitsAttr ||
      attrName == SVGNames::orientAttr ||
      SVGFitToViewBox::isKnownAttribute(attrName)) {
    SVGElement::InvalidationGuard invalidationGuard(this);
    LayoutSVGResourceContainer* layoutObject =
        toLayoutSVGResourceContainer(this->layoutObject());
    if (layoutObject)
      layoutObject->invalidateCacheAndMarkForLayout();

    return;
  }

  SVGElement::svgAttributeChanged(attrName);
}

void SVGMarkerElement::childrenChanged(const ChildrenChange& change) {
  SVGElement::childrenChanged(change);

  if (change.byParser)
    return;

  if (LayoutObject* object = layoutObject())
    object->setNeedsLayoutAndFullPaintInvalidation(
        LayoutInvalidationReason::ChildChanged);
}

void SVGMarkerElement::setOrientToAuto() {
  setAttribute(SVGNames::orientAttr, "auto");
}

void SVGMarkerElement::setOrientToAngle(SVGAngleTearOff* angle) {
  ASSERT(angle);
  SVGAngle* target = angle->target();
  setAttribute(SVGNames::orientAttr, AtomicString(target->valueAsString()));
}

LayoutObject* SVGMarkerElement::createLayoutObject(const ComputedStyle&) {
  return new LayoutSVGResourceMarker(this);
}

bool SVGMarkerElement::selfHasRelativeLengths() const {
  return m_refX->currentValue()->isRelative() ||
         m_refY->currentValue()->isRelative() ||
         m_markerWidth->currentValue()->isRelative() ||
         m_markerHeight->currentValue()->isRelative();
}

}  // namespace blink
