/*
    Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
                  2004, 2005, 2006 Rob Buis <buis@kde.org>

    This file is part of the KDE project

    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., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#ifndef SVGElement_h
#define SVGElement_h

#if ENABLE(SVG)

#include "Document.h"
#include "FloatRect.h"
#include "StyledElement.h"
#include "SVGAnimatedTemplate.h"
#include "SVGDocumentExtensions.h"
#include "SVGNames.h"

#define ANIMATED_PROPERTY_EMPTY_DECLARATIONS(BareType, NullType, UpperProperty, LowerProperty) \
public: \
    virtual BareType LowerProperty() const { ASSERT_NOT_REACHED(); return NullType; } \
    virtual void set##UpperProperty(BareType newValue) { ASSERT_NOT_REACHED(); }\
    virtual BareType LowerProperty##BaseValue() const { ASSERT_NOT_REACHED(); return NullType; } \
    virtual void set##UpperProperty##BaseValue(BareType newValue) { ASSERT_NOT_REACHED(); } \
    virtual void start##UpperProperty() const { ASSERT_NOT_REACHED(); } \
    virtual void stop##UpperProperty() { ASSERT_NOT_REACHED(); }

#define ANIMATED_PROPERTY_FORWARD_DECLARATIONS(ForwardClass, BareType, UpperProperty, LowerProperty) \
public: \
    virtual BareType LowerProperty() const { return ForwardClass::LowerProperty(); } \
    virtual void set##UpperProperty(BareType newValue) { ForwardClass::set##UpperProperty(newValue); } \
    virtual BareType LowerProperty##BaseValue() const { return ForwardClass::LowerProperty##BaseValue(); } \
    virtual void set##UpperProperty##BaseValue(BareType newValue) { ForwardClass::set##UpperProperty##BaseValue(newValue); } \
    virtual void start##UpperProperty() const { ForwardClass::start##UpperProperty(); } \
    virtual void stop##UpperProperty() { ForwardClass::stop##UpperProperty(); }

#define ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(ClassType, ClassStorageType, BareType, StorageType, UpperProperty, LowerProperty) \
class SVGAnimatedTemplate##UpperProperty \
: public SVGAnimatedTemplate<BareType> \
{ \
public: \
    SVGAnimatedTemplate##UpperProperty(const ClassType* element); \
    virtual ~SVGAnimatedTemplate##UpperProperty() { } \
    virtual BareType baseVal() const; \
    virtual void setBaseVal(BareType newBaseVal); \
    virtual BareType animVal() const; \
    virtual void setAnimVal(BareType newAnimVal); \
\
protected: \
    ClassStorageType m_element; \
}; \
public: \
    BareType LowerProperty() const; \
    void set##UpperProperty(BareType newValue); \
    BareType LowerProperty##BaseValue() const; \
    void set##UpperProperty##BaseValue(BareType newValue); \
    PassRefPtr<SVGAnimatedTemplate##UpperProperty> LowerProperty##Animated() const; \
    void start##UpperProperty() const; \
    void stop##UpperProperty(); \
\
private: \
    StorageType m_##LowerProperty;

#define ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, ClassType, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter, ContextElement) \
ClassName::SVGAnimatedTemplate##UpperProperty::SVGAnimatedTemplate##UpperProperty(const ClassType* element) \
: m_element(const_cast<ClassType*>(element)) { } \
BareType ClassName::SVGAnimatedTemplate##UpperProperty::baseVal() const \
{ \
    return m_element->LowerProperty##BaseValue(); \
} \
void ClassName::SVGAnimatedTemplate##UpperProperty::setBaseVal(BareType newBaseVal) \
{ \
    m_element->set##UpperProperty##BaseValue(newBaseVal); \
} \
BareType ClassName::SVGAnimatedTemplate##UpperProperty::animVal() const \
{ \
    return m_element->LowerProperty(); \
} \
void ClassName::SVGAnimatedTemplate##UpperProperty::setAnimVal(BareType newAnimVal) \
{ \
    m_element->set##UpperProperty(newAnimVal); \
} \
BareType ClassName::LowerProperty() const \
{ \
    return StorageGetter; \
} \
void ClassName::set##UpperProperty(BareType newValue) \
{ \
    m_##LowerProperty = newValue; \
} \
BareType ClassName::LowerProperty##BaseValue() const \
{ \
    const SVGElement* context = ContextElement; \
    ASSERT(context); \
    SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \
    if (extensions && extensions->hasBaseValue<BareType>(context, AttrName)) \
         return extensions->baseValue<BareType>(context, AttrName); \
    return LowerProperty(); \
} \
void ClassName::set##UpperProperty##BaseValue(BareType newValue) \
{ \
    const SVGElement* context = ContextElement; \
    ASSERT(context); \
    SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \
    if (extensions && extensions->hasBaseValue<BareType>(context, AttrName)) { \
        extensions->setBaseValue<BareType>(context, AttrName, newValue); \
        return; \
    } \
    /* Only update stored property, if not animating */ \
    set##UpperProperty(newValue); \
} \
\
void ClassName::start##UpperProperty() const \
{ \
    const SVGElement* context = ContextElement; \
    ASSERT(context); \
    SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \
    if (extensions) { \
        ASSERT(!extensions->hasBaseValue<BareType>(context, AttrName)); \
        extensions->setBaseValue<BareType>(context, AttrName, LowerProperty()); \
    } \
} \
\
void ClassName::stop##UpperProperty() \
{ \
    const SVGElement* context = ContextElement; \
    ASSERT(context); \
    SVGDocumentExtensions* extensions = (context->document() ? context->document()->accessSVGExtensions() : 0); \
    if (extensions) { \
        ASSERT(extensions->hasBaseValue<BareType>(context, AttrName)); \
        set##UpperProperty(extensions->baseValue<BareType>(context, AttrName)); \
        extensions->removeBaseValue<BareType>(context, AttrName); \
    } \
}

// These are the macros which will be used to declare/implement the svg animated properties...
#define ANIMATED_PROPERTY_DECLARATIONS_WITH_CONTEXT(ClassName, BareType, StorageType, UpperProperty, LowerProperty) \
ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(SVGElement, RefPtr<SVGElement>, BareType, StorageType, UpperProperty, LowerProperty)

#define ANIMATED_PROPERTY_DECLARATIONS(ClassName, BareType, StorageType, UpperProperty, LowerProperty) \
ANIMATED_PROPERTY_DECLARATIONS_INTERNAL(ClassName, RefPtr<ClassName>, BareType, StorageType, UpperProperty, LowerProperty)

#define ANIMATED_PROPERTY_DEFINITIONS_WITH_CONTEXT(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter) \
ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, SVGElement, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter, contextElement()) \
PassRefPtr<ClassName::SVGAnimatedTemplate##UpperProperty> ClassName::LowerProperty##Animated() const \
{ \
    const SVGElement* context = contextElement(); \
    ASSERT(context); \
    return RefPtr<ClassName::SVGAnimatedTemplate##UpperProperty>(new ClassName::SVGAnimatedTemplate##UpperProperty(context)); \
}

#define ANIMATED_PROPERTY_DEFINITIONS(ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter) \
ANIMATED_PROPERTY_DEFINITIONS_INTERNAL(ClassName, ClassName, BareType, UpperClassName, LowerClassName, UpperProperty, LowerProperty, AttrName, StorageGetter, this) \
PassRefPtr<ClassName::SVGAnimatedTemplate##UpperProperty> ClassName::LowerProperty##Animated() const \
{ \
    return RefPtr<ClassName::SVGAnimatedTemplate##UpperProperty>(new ClassName::SVGAnimatedTemplate##UpperProperty(this)); \
}

namespace WebCore {
    class Ecma;
    class SVGPreserveAspectRatio;
    class SVGMatrix;
    class SVGStyledElement;
    class SVGSVGElement;

    class SVGElement : public StyledElement {
    public:
        SVGElement(const QualifiedName&, Document*);
        virtual ~SVGElement();
        virtual bool isSVGElement() const { return true; }
        virtual bool isSupported(StringImpl* feature, StringImpl* version) const;
        
        String id() const;
        void setId(const String&, ExceptionCode&);
        String xmlbase() const;
        void setXmlbase(const String&, ExceptionCode&);

        SVGSVGElement* ownerSVGElement() const;
        SVGElement* viewportElement() const;

        // Internal
        virtual void parseMappedAttribute(MappedAttribute*);
        
        virtual bool isStyled() const { return false; }
        virtual bool isStyledTransformable() const { return false; }
        virtual bool isStyledLocatable() const { return false; }
        virtual bool isSVG() const { return false; }
        virtual bool isFilterEffect() const { return false; }
        virtual bool isGradientStop() const { return false; }
        virtual bool isTextContent() const { return false; }

        virtual bool isShadowNode() const { return m_shadowParent; }
        virtual Node* shadowParentNode() { return m_shadowParent; }
        void setShadowParentNode(Node* node) { m_shadowParent = node; }
        virtual Node* eventParentNode() { return isShadowNode() ? shadowParentNode() : parentNode(); }

        // For SVGTests
        virtual bool isValid() const { return true; }
  
        virtual void finishedParsing();
        virtual bool rendererIsNeeded(RenderStyle*) { return false; }
        virtual bool childShouldCreateRenderer(Node*) const;

        virtual void insertedIntoDocument();
        virtual void buildPendingResource() { }

        virtual void notifyAttributeChange() const { }
        void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false);

        // Forwarded properties (declared/defined anywhere else in the inheritance structure)

        // -> For SVGURIReference
        ANIMATED_PROPERTY_EMPTY_DECLARATIONS(String, String(), Href, href)

        // -> For SVGFitToViewBox
        ANIMATED_PROPERTY_EMPTY_DECLARATIONS(FloatRect, FloatRect(), ViewBox, viewBox)    
        ANIMATED_PROPERTY_EMPTY_DECLARATIONS(SVGPreserveAspectRatio*, 0, PreserveAspectRatio, preserveAspectRatio)

        // -> For SVGExternalResourcesRequired
        ANIMATED_PROPERTY_EMPTY_DECLARATIONS(bool, false, ExternalResourcesRequired, externalResourcesRequired)

        virtual bool dispatchEvent(PassRefPtr<Event> e, ExceptionCode& ec, bool tempEvent = false);

    private:
        void addSVGEventListener(const AtomicString& eventType, const Attribute*);
        virtual bool haveLoadedRequiredResources();

        Node* m_shadowParent;
    };

    static inline SVGElement* svg_dynamic_cast(Node* node)
    {
        SVGElement* svgElement = 0;
        if (node && node->isSVGElement())
            svgElement = static_cast<SVGElement*>(node);
        return svgElement;
    }

} // namespace WebCore 

#endif // ENABLE(SVG)
#endif // SVGElement_h

// vim:ts=4:noet
