/*
 * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
 * Copyright (C) 2004, 2005, 2010 Rob Buis <buis@kde.org>
 * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com>
 * Copyright (C) 2006-2019 Apple Inc. 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.
 */

// FIXME: no css::ViewCSS available!
// FIXME: Fix SVGSVGElement inheritance (css::DocumentCSS)!
// FIXME: no events::DocumentEvent available!

[
    JSGenerateToNativeObject,
    ExportMacro=WEBCORE_EXPORT,
] interface SVGSVGElement : SVGGraphicsElement {
    [SameObject] readonly attribute SVGAnimatedLength x;
    [SameObject] readonly attribute SVGAnimatedLength y;
    [SameObject] readonly attribute SVGAnimatedLength width;
    [SameObject] readonly attribute SVGAnimatedLength height;

    attribute float currentScale;
    [SameObject] readonly attribute SVGPoint currentTranslate;
    
    readonly attribute boolean useCurrentView;
    readonly attribute SVGViewSpec currentView;

    NodeList getIntersectionList(SVGRect rect, SVGElement? referenceElement);
    NodeList getEnclosureList(SVGRect rect, SVGElement? referenceElement);
    boolean checkIntersection(SVGElement element, SVGRect rect);
    boolean checkEnclosure(SVGElement element, SVGRect rect);

    void deselectAll();

    [NewObject] SVGNumber createSVGNumber();
    [NewObject] SVGLength createSVGLength();
    [NewObject] SVGAngle createSVGAngle();
    [NewObject] SVGPoint createSVGPoint();
    [NewObject] SVGMatrix createSVGMatrix();
    [NewObject] SVGRect createSVGRect();
    [NewObject] SVGTransform createSVGTransform();
    [NewObject] SVGTransform createSVGTransformFromMatrix(optional DOMMatrix2DInit matrix);

    Element getElementById([RequiresExistingAtomString] DOMString elementId);

    // SVG animations extensions
    // https://svgwg.org/specs/animations/#InterfaceSVGSVGElement
    void pauseAnimations();
    void unpauseAnimations();
    boolean animationsPaused();
    unrestricted float getCurrentTime();
    void setCurrentTime(optional unrestricted float seconds = NaN);

    // Deprecated SVG redrawing
    unsigned long suspendRedraw(optional unsigned long maxWaitMilliseconds = 0);
    void unsuspendRedraw(optional unsigned long suspendHandleId = 0);
    void unsuspendRedrawAll();
    void forceRedraw();
};

SVGSVGElement implements SVGFitToViewBox;
SVGSVGElement implements SVGZoomAndPan;
