/*
 * 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, 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.
 *
 */

#pragma once

#include "HTMLTextFormControlElement.h"

namespace WebCore {

class BeforeTextInsertedEvent;
class RenderTextControlMultiLine;
class VisibleSelection;

class HTMLTextAreaElement final : public HTMLTextFormControlElement {
    WTF_MAKE_ISO_ALLOCATED(HTMLTextAreaElement);
public:
    static Ref<HTMLTextAreaElement> create(const QualifiedName&, Document&, HTMLFormElement*);

    unsigned cols() const { return m_cols; }
    unsigned rows() const { return m_rows; }

    bool shouldWrapText() const { return m_wrap != NoWrap; }

    WEBCORE_EXPORT String value() const final;
    WEBCORE_EXPORT void setValue(const String&);
    WEBCORE_EXPORT String defaultValue() const;
    WEBCORE_EXPORT void setDefaultValue(const String&);
    int textLength() const { return value().length(); }
    int effectiveMaxLength() const { return maxLength(); }
    // For ValidityState
    String validationMessage() const final;
    bool valueMissing() const final;
    bool tooShort() const final;
    bool tooLong() const final;
    bool isValidValue(const String&) const;
    
    RefPtr<TextControlInnerTextElement> innerTextElement() const final;
    RenderStyle createInnerTextStyle(const RenderStyle&) final;
    void copyNonAttributePropertiesFromElement(const Element&) final;

    void rendererWillBeDestroyed();

    WEBCORE_EXPORT void setCols(unsigned);
    WEBCORE_EXPORT void setRows(unsigned);

    bool willRespondToMouseClickEvents() final;

    RenderTextControlMultiLine* renderer() const;

private:
    HTMLTextAreaElement(const QualifiedName&, Document&, HTMLFormElement*);

    enum WrapMethod { NoWrap, SoftWrap, HardWrap };

    void didAddUserAgentShadowRoot(ShadowRoot&) final;

    void maxLengthAttributeChanged(const AtomicString& newValue);
    void minLengthAttributeChanged(const AtomicString& newValue);

    void handleBeforeTextInsertedEvent(BeforeTextInsertedEvent&) const;
    static String sanitizeUserInputValue(const String&, unsigned maxLength);
    void updateValue() const;
    void setNonDirtyValue(const String&);
    void setValueCommon(const String&);

    bool supportsPlaceholder() const final { return true; }
    HTMLElement* placeholderElement() const final;
    void updatePlaceholderText() final;
    bool isEmptyValue() const final { return value().isEmpty(); }

    bool isOptionalFormControl() const final { return !isRequiredFormControl(); }
    bool isRequiredFormControl() const final { return isRequired(); }

    void defaultEventHandler(Event&) final;
    
    void subtreeHasChanged() final;

    bool isEnumeratable() const final { return true; }
    bool supportLabels() const final { return true; }

    const AtomicString& formControlType() const final;

    FormControlState saveFormControlState() const final;
    void restoreFormControlState(const FormControlState&) final;

    bool isTextField() const final { return true; }

    void childrenChanged(const ChildChange&) final;
    void parseAttribute(const QualifiedName&, const AtomicString&) final;
    bool isPresentationAttribute(const QualifiedName&) const final;
    void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) final;
    RenderPtr<RenderElement> createElementRenderer(RenderStyle&&, const RenderTreePosition&) final;
    bool appendFormData(DOMFormData&, bool) final;
    void reset() final;
    bool hasCustomFocusLogic() const final;
    bool isMouseFocusable() const final;
    bool isKeyboardFocusable(KeyboardEvent*) const final;
    void updateFocusAppearance(SelectionRestorationMode, SelectionRevealMode) final;

    void accessKeyAction(bool sendMouseEvents) final;

    bool shouldUseInputMethod() final;
    bool matchesReadWritePseudoClass() const final;

    bool valueMissing(const String& value) const { return isRequiredFormControl() && !isDisabledOrReadOnly() && value.isEmpty(); }
    bool tooShort(StringView, NeedsToCheckDirtyFlag) const;
    bool tooLong(StringView, NeedsToCheckDirtyFlag) const;

    unsigned m_rows;
    unsigned m_cols;
    WrapMethod m_wrap { SoftWrap };
    RefPtr<HTMLElement> m_placeholder;
    mutable String m_value;
    mutable bool m_isDirty { false };
    mutable bool m_wasModifiedByUser { false };
};

} //namespace
