/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2001 Peter Kelly (pmk@post.com)
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2003, 2004, 2005, 2006, 2008, 2012, 2014 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.
 *
 */

#pragma once

#include "QualifiedName.h"

namespace WebCore {

// This has no counterpart in DOM.
// It is an internal representation of the node value of an Attr.
// The actual Attr with its value as a Text child is allocated only if needed.
class Attribute {
public:
    Attribute(const QualifiedName& name, const AtomString& value)
        : m_name(name)
        , m_value(value)
    {
    }

    // NOTE: The references returned by these functions are only valid for as long
    // as the Attribute stays in place. For example, calling a function that mutates
    // an Element's internal attribute storage may invalidate them.
    const AtomString& value() const { return m_value; }
    static ptrdiff_t valueMemoryOffset() { return OBJECT_OFFSETOF(Attribute, m_value); }
    const AtomString& prefix() const { return m_name.prefix(); }
    const AtomString& localName() const { return m_name.localName(); }
    const AtomString& namespaceURI() const { return m_name.namespaceURI(); }

    const QualifiedName& name() const { return m_name; }
    static ptrdiff_t nameMemoryOffset() { return OBJECT_OFFSETOF(Attribute, m_name); }

    bool isEmpty() const { return m_value.isEmpty(); }
    static bool nameMatchesFilter(const QualifiedName&, const AtomString& filterPrefix, const AtomString& filterLocalName, const AtomString& filterNamespaceURI);
    bool matches(const AtomString& prefix, const AtomString& localName, const AtomString& namespaceURI) const;

    void setValue(const AtomString& value) { m_value = value; }
    void setPrefix(const AtomString& prefix) { m_name.setPrefix(prefix); }

    // Note: This API is only for HTMLTreeBuilder.  It is not safe to change the
    // name of an attribute once parseAttribute has been called as DOM
    // elements may have placed the Attribute in a hash by name.
    void parserSetName(const QualifiedName& name) { m_name = name; }

#if COMPILER(MSVC)
    // NOTE: This constructor is not actually implemented, it's just defined so MSVC
    // will let us use a zero-length array of Attributes.
    Attribute();
#endif

private:
    QualifiedName m_name;
    AtomString m_value;
};

inline bool Attribute::nameMatchesFilter(const QualifiedName& name, const AtomString& filterPrefix, const AtomString& filterLocalName, const AtomString& filterNamespaceURI)
{
    if (filterLocalName != name.localName())
        return false;
    return filterPrefix == starAtom() || filterNamespaceURI == name.namespaceURI();
}

inline bool Attribute::matches(const AtomString& prefix, const AtomString& localName, const AtomString& namespaceURI) const
{
    return nameMatchesFilter(m_name, prefix, localName, namespaceURI);
}

} // namespace WebCore
