/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2000 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 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.
 *
 */

#ifndef FormAssociatedElement_h
#define FormAssociatedElement_h

#include "core/CoreExport.h"
#include "platform/heap/Handle.h"
#include "wtf/text/WTFString.h"

namespace blink {

class ContainerNode;
class Document;
class FormAttributeTargetObserver;
class FormData;
class HTMLElement;
class HTMLFormElement;
class Node;
class ValidityState;

class CORE_EXPORT FormAssociatedElement : public GarbageCollectedMixin {
public:
    virtual ~FormAssociatedElement();

    static HTMLFormElement* findAssociatedForm(const HTMLElement*);
    HTMLFormElement* form() const { return m_form.get(); }
    ValidityState* validity();

    virtual bool isFormControlElement() const = 0;
    virtual bool isFormControlElementWithState() const;
    virtual bool isEnumeratable() const = 0;

    // Returns the 'name' attribute value. If this element has no name
    // attribute, it returns an empty string instead of null string.
    // Note that the 'name' IDL attribute doesn't use this function.
    virtual const AtomicString& name() const;

    // Override in derived classes to get the encoded name=value pair for
    // submitting.
    virtual void appendToFormData(FormData&) { }

    void resetFormOwner();

    void formRemovedFromTree(const Node& formRoot);

    // ValidityState attribute implementations
    bool customError() const;

    // Override functions for patterMismatch, rangeOverflow, rangerUnderflow,
    // stepMismatch, tooLong, tooShort and valueMissing must call willValidate method.
    virtual bool hasBadInput() const;
    virtual bool patternMismatch() const;
    virtual bool rangeOverflow() const;
    virtual bool rangeUnderflow() const;
    virtual bool stepMismatch() const;
    virtual bool tooLong() const;
    virtual bool tooShort() const;
    virtual bool typeMismatch() const;
    virtual bool valueMissing() const;
    virtual String validationMessage() const;
    virtual String validationSubMessage() const;
    bool valid() const;
    virtual void setCustomValidity(const String&);

    void formAttributeTargetChanged();

    typedef HeapVector<Member<FormAssociatedElement>> List;

    DECLARE_VIRTUAL_TRACE();

protected:
    FormAssociatedElement();

    void insertedInto(ContainerNode*);
    void removedFrom(ContainerNode*);
    void didMoveToNewDocument(Document& oldDocument);

    // FIXME: Remove usage of setForm. resetFormOwner should be enough, and
    // setForm is confusing.
    void setForm(HTMLFormElement*);
    void associateByParser(HTMLFormElement*);
    void formAttributeChanged();

    // If you add an override of willChangeForm() or didChangeForm() to a class
    // derived from this one, you will need to add a call to setForm(0) to the
    // destructor of that class.
    virtual void willChangeForm();
    virtual void didChangeForm();

    String customValidationMessage() const;

private:
    void setFormAttributeTargetObserver(FormAttributeTargetObserver*);
    void resetFormAttributeTargetObserver();

    Member<FormAttributeTargetObserver> m_formAttributeTargetObserver;
    Member<HTMLFormElement> m_form;
    Member<ValidityState> m_validityState;
    String m_customValidationMessage;
    // If m_formWasSetByParser is true, m_form is always non-null.
    bool m_formWasSetByParser;
};

CORE_EXPORT HTMLElement* toHTMLElement(FormAssociatedElement*);
CORE_EXPORT HTMLElement& toHTMLElement(FormAssociatedElement&);
CORE_EXPORT const HTMLElement* toHTMLElement(const FormAssociatedElement*);
CORE_EXPORT const HTMLElement& toHTMLElement(const FormAssociatedElement&);

} // namespace blink

#endif // FormAssociatedElement_h
