/**
 * This file is part of the DOM implementation for KDE.
 *
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
 *
 * 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 "HTMLFormCollection.h"

#include "HTMLGenericFormElement.h"
#include "HTMLFormElement.h"
#include "HTMLImageElement.h"
#include "HTMLNames.h"

namespace WebCore {

using namespace HTMLNames;

// since the collections are to be "live", we have to do the
// calculation every time if anything has changed

HTMLFormCollection::HTMLFormCollection(Node* _base)
    : HTMLCollection(_base, HTMLCollection::Type(0))
{
    HTMLFormElement *formBase = static_cast<HTMLFormElement*>(m_base.get());
    if (!formBase->collectionInfo)
        formBase->collectionInfo = new CollectionInfo();
    info = formBase->collectionInfo;
}

HTMLFormCollection::~HTMLFormCollection()
{
}

unsigned HTMLFormCollection::calcLength() const
{
    return static_cast<HTMLFormElement*>(m_base.get())->length();
}

Node *HTMLFormCollection::item(unsigned index) const
{
    resetCollectionInfo();

    if (info->current && info->position == index)
        return info->current;

    if (info->haslength && info->length <= index)
        return 0;

    if (!info->current || info->position > index) {
        info->current = 0;
        info->position = 0;
        info->elementsArrayPosition = 0;
    }

    Vector<HTMLGenericFormElement*>& l = static_cast<HTMLFormElement*>(m_base.get())->formElements;
    unsigned currentIndex = info->position;
    
    for (unsigned i = info->elementsArrayPosition; i < l.size(); i++) {
        if (l[i]->isEnumeratable() ) {
            if (index == currentIndex) {
                info->position = index;
                info->current = l[i];
                info->elementsArrayPosition = i;
                return l[i];
            }

            currentIndex++;
        }
    }

    return 0;
}

Node* HTMLFormCollection::getNamedItem(Node*, const QualifiedName& attrName, const String& name, bool caseSensitive) const
{
    info->position = 0;
    return getNamedFormItem(attrName, name, 0, caseSensitive);
}

Node* HTMLFormCollection::getNamedFormItem(const QualifiedName& attrName, const String& name, int duplicateNumber, bool caseSensitive) const
{
    if (m_base->isElementNode()) {
        HTMLElement* baseElement = static_cast<HTMLElement*>(m_base.get());
        bool foundInputElements = false;
        if (baseElement->hasLocalName(formTag)) {
            HTMLFormElement* f = static_cast<HTMLFormElement*>(baseElement);
            for (unsigned i = 0; i < f->formElements.size(); ++i) {
                HTMLGenericFormElement* e = f->formElements[i];
                if (e->isEnumeratable()) {
                    bool found;
                    if (caseSensitive)
                        found = e->getAttribute(attrName) == name;
                    else
                        found = e->getAttribute(attrName).domString().lower() == name.lower();
                    if (found) {
                        foundInputElements = true;
                        if (!duplicateNumber)
                            return e;
                        --duplicateNumber;
                    }
                }
            }
        }

        if (!foundInputElements) {
            HTMLFormElement* f = static_cast<HTMLFormElement*>(baseElement);

            for(unsigned i = 0; i < f->imgElements.size(); ++i)
            {
                HTMLImageElement* e = f->imgElements[i];
                bool found;
                if (caseSensitive)
                    found = e->getAttribute(attrName) == name;
                else
                    found = e->getAttribute(attrName).domString().lower() == name.lower();
                if (found) {
                    if (!duplicateNumber)
                        return e;
                    --duplicateNumber;
                }
            }
        }
    }
    return 0;
}

Node * HTMLFormCollection::firstItem() const
{
    return item(0);
}

Node * HTMLFormCollection::nextItem() const
{
    return item(info->position + 1);
}

Node * HTMLFormCollection::nextNamedItemInternal(const String &name) const
{
    Node *retval = getNamedFormItem( idsDone ? nameAttr : idAttr, name, ++info->position, true );
    if (retval)
        return retval;
    if (idsDone) // we're done
        return 0;
    // After doing id, do name
    idsDone = true;
    return getNamedItem(m_base->firstChild(), nameAttr, name, true);
}

Node *HTMLFormCollection::namedItem( const String &name, bool caseSensitive ) const
{
    // http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/nameditem.asp
    // This method first searches for an object with a matching id
    // attribute. If a match is not found, the method then searches for an
    // object with a matching name attribute, but only on those elements
    // that are allowed a name attribute.
    resetCollectionInfo();
    idsDone = false;
    info->current = getNamedItem(m_base->firstChild(), idAttr, name, true);
    if(info->current)
        return info->current;
    idsDone = true;
    info->current = getNamedItem(m_base->firstChild(), nameAttr, name, true);
    return info->current;
}

Node *HTMLFormCollection::nextNamedItem( const String &name ) const
{
    // nextNamedItemInternal can return an item that has both id=<name> and name=<name>
    // Here, we have to filter out such cases.
    Node *impl = nextNamedItemInternal( name );
    if (!idsDone) // looking for id=<name> -> no filtering
        return impl;
    // looking for name=<name> -> filter out if id=<name>
    bool ok = false;
    while (impl && !ok)
    {
        if(impl->isElementNode())
        {
            HTMLElement *e = static_cast<HTMLElement *>(impl);
            ok = (e->getAttribute(idAttr) != name);
            if (!ok)
                impl = nextNamedItemInternal( name );
        } else // can't happen
            ok = true;
    }
    return impl;
}

void HTMLFormCollection::updateNameCache() const
{
    if (info->hasNameCache)
        return;

    HashSet<AtomicStringImpl*> foundInputElements;

    if (!m_base->hasTagName(formTag)) {
        info->hasNameCache = true;
        return;
    }

    HTMLElement* baseElement = static_cast<HTMLElement*>(m_base.get());

    HTMLFormElement* f = static_cast<HTMLFormElement*>(baseElement);
    for (unsigned i = 0; i < f->formElements.size(); ++i) {
        HTMLGenericFormElement* e = f->formElements[i];
        if (e->isEnumeratable()) {
            const AtomicString& idAttrVal = e->getAttribute(idAttr);
            const AtomicString& nameAttrVal = e->getAttribute(nameAttr);
            if (!idAttrVal.isEmpty()) {
                // add to id cache
                Vector<Node*>* idVector = info->idCache.get(idAttrVal.impl());
                if (!idVector) {
                    idVector = new Vector<Node*>;
                    info->idCache.add(idAttrVal.impl(), idVector);
                }
                idVector->append(e);
                foundInputElements.add(idAttrVal.impl());
            }
            if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal) {
                // add to name cache
                Vector<Node*>* nameVector = info->nameCache.get(nameAttrVal.impl());
                if (!nameVector) {
                    nameVector = new Vector<Node*>;
                    info->nameCache.add(nameAttrVal.impl(), nameVector);
                }
                nameVector->append(e);
                foundInputElements.add(nameAttrVal.impl());
            }
        }
    }

    for (unsigned i = 0; i < f->imgElements.size(); ++i) {
        HTMLImageElement* e = f->imgElements[i];
        const AtomicString& idAttrVal = e->getAttribute(idAttr);
        const AtomicString& nameAttrVal = e->getAttribute(nameAttr);
        if (!idAttrVal.isEmpty() && !foundInputElements.contains(idAttrVal.impl())) {
            // add to id cache
            Vector<Node*>* idVector = info->idCache.get(idAttrVal.impl());
            if (!idVector) {
                idVector = new Vector<Node*>;
                info->idCache.add(idAttrVal.impl(), idVector);
            }
            idVector->append(e);
        }
        if (!nameAttrVal.isEmpty() && idAttrVal != nameAttrVal && !foundInputElements.contains(nameAttrVal.impl())) {
            // add to name cache
            Vector<Node*>* nameVector = info->nameCache.get(nameAttrVal.impl());
            if (!nameVector) {
                nameVector = new Vector<Node*>;
                info->nameCache.add(nameAttrVal.impl(), nameVector);
            }
            nameVector->append(e);
        }
    }

    info->hasNameCache = true;
}

}
