/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 * Copyright (C) 2003, 2004, 2005, 2006, 2007 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 "CachedHTMLCollection.h"
#include "NodeRareData.h"
#include <wtf/text/AtomicString.h>

namespace WebCore {

class Document;

template <typename HTMLCollectionClass, CollectionTraversalType traversalType>
class HTMLNameCollection : public CachedHTMLCollection<HTMLCollectionClass, traversalType> {
public:
    virtual ~HTMLNameCollection();

    Document& document() { return downcast<Document>(this->ownerNode()); }

protected:
    HTMLNameCollection(Document&, CollectionType, const AtomicString& name);

    AtomicString m_name;
};

template <typename HTMLCollectionClass, CollectionTraversalType traversalType>
HTMLNameCollection<HTMLCollectionClass, traversalType>::HTMLNameCollection(Document& document, CollectionType type, const AtomicString& name)
    : CachedHTMLCollection<HTMLCollectionClass, traversalType>(document, type)
    , m_name(name)
{
}

template <typename HTMLCollectionClass, CollectionTraversalType traversalType>
HTMLNameCollection<HTMLCollectionClass, traversalType>::~HTMLNameCollection()
{
    ASSERT(this->type() == WindowNamedItems || this->type() == DocumentNamedItems);

    document().nodeLists()->removeCachedCollection(this, m_name);
}

class WindowNameCollection final : public HTMLNameCollection<WindowNameCollection, CollectionTraversalType::Descendants> {
public:
    static Ref<WindowNameCollection> create(Document& document, CollectionType type, const AtomicString& name)
    {
        return adoptRef(*new WindowNameCollection(document, type, name));
    }

    // For CachedHTMLCollection.
    bool elementMatches(const Element& element) const { return elementMatches(element, m_name.impl()); }

    static bool elementMatchesIfIdAttributeMatch(const Element&) { return true; }
    static bool elementMatchesIfNameAttributeMatch(const Element&);
    static bool elementMatches(const Element&, const AtomicStringImpl*);

private:
    WindowNameCollection(Document& document, CollectionType type, const AtomicString& name)
        : HTMLNameCollection<WindowNameCollection, CollectionTraversalType::Descendants>(document, type, name)
    {
        ASSERT(type == WindowNamedItems);
    }
};

class DocumentNameCollection final : public HTMLNameCollection<DocumentNameCollection, CollectionTraversalType::Descendants> {
public:
    static Ref<DocumentNameCollection> create(Document& document, CollectionType type, const AtomicString& name)
    {
        return adoptRef(*new DocumentNameCollection(document, type, name));
    }

    static bool elementMatchesIfIdAttributeMatch(const Element&);
    static bool elementMatchesIfNameAttributeMatch(const Element&);

    // For CachedHTMLCollection.
    bool elementMatches(const Element& element) const { return elementMatches(element, m_name.impl()); }

    static bool elementMatches(const Element&, const AtomicStringImpl*);

private:
    DocumentNameCollection(Document& document, CollectionType type, const AtomicString& name)
        : HTMLNameCollection<DocumentNameCollection, CollectionTraversalType::Descendants>(document, type, name)
    {
        ASSERT(type == DocumentNamedItems);
    }
};

} // namespace WebCore

SPECIALIZE_TYPE_TRAITS_HTMLCOLLECTION(WindowNameCollection, WindowNamedItems)
SPECIALIZE_TYPE_TRAITS_HTMLCOLLECTION(DocumentNameCollection, DocumentNamedItems)
