/*
 * 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) 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
 *           (C) 2007 Eric Seidel (eric@webkit.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 "config.h"
#include "core/dom/NamedNodeMap.h"

#include "bindings/v8/ExceptionState.h"
#include "core/dom/Attr.h"
#include "core/dom/Document.h"
#include "core/dom/Element.h"
#include "core/dom/ExceptionCode.h"

namespace WebCore {

using namespace HTMLNames;

void NamedNodeMap::ref()
{
    m_element->ref();
}

void NamedNodeMap::deref()
{
    m_element->deref();
}

PassRefPtr<Node> NamedNodeMap::getNamedItem(const AtomicString& name) const
{
    return m_element->getAttributeNode(name);
}

PassRefPtr<Node> NamedNodeMap::getNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName) const
{
    return m_element->getAttributeNodeNS(namespaceURI, localName);
}

PassRefPtr<Node> NamedNodeMap::removeNamedItem(const AtomicString& name, ExceptionState& es)
{
    size_t index = m_element->hasAttributes() ? m_element->getAttributeItemIndex(name, m_element->shouldIgnoreAttributeCase()) : kNotFound;
    if (index == kNotFound) {
        es.throwUninformativeAndGenericDOMException(NotFoundError);
        return 0;
    }
    return m_element->detachAttribute(index);
}

PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const AtomicString& namespaceURI, const AtomicString& localName, ExceptionState& es)
{
    size_t index = m_element->hasAttributes() ? m_element->getAttributeItemIndex(QualifiedName(nullAtom, localName, namespaceURI)) : kNotFound;
    if (index == kNotFound) {
        es.throwUninformativeAndGenericDOMException(NotFoundError);
        return 0;
    }
    return m_element->detachAttribute(index);
}

PassRefPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionState& es)
{
    if (!node) {
        es.throwUninformativeAndGenericDOMException(NotFoundError);
        return 0;
    }

    // Not mentioned in spec: throw a HIERARCHY_REQUEST_ERROR if the user passes in a non-attribute node
    if (!node->isAttributeNode()) {
        es.throwUninformativeAndGenericDOMException(HierarchyRequestError);
        return 0;
    }

    return m_element->setAttributeNode(toAttr(node), es);
}

PassRefPtr<Node> NamedNodeMap::setNamedItemNS(Node* node, ExceptionState& es)
{
    return setNamedItem(node, es);
}

PassRefPtr<Node> NamedNodeMap::item(unsigned index) const
{
    if (index >= length())
        return 0;
    return m_element->ensureAttr(m_element->attributeItem(index)->name());
}

size_t NamedNodeMap::length() const
{
    if (!m_element->hasAttributes())
        return 0;
    return m_element->attributeCount();
}

} // namespace WebCore
