/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "BaseClickableWithKeyInputType.h"
#include "FileChooser.h"
#include "FileIconLoader.h"
#include <wtf/RefPtr.h>

namespace WebCore {

class DragData;
class FileList;
class FileListCreator;
class Icon;

class FileInputType final : public BaseClickableWithKeyInputType, private FileChooserClient, private FileIconLoaderClient {
public:
    explicit FileInputType(HTMLInputElement&);
    virtual ~FileInputType();

    static Vector<FileChooserFileInfo> filesFromFormControlState(const FormControlState&);

private:
    const AtomString& formControlType() const final;
    FormControlState saveFormControlState() const final;
    void restoreFormControlState(const FormControlState&) final;
    bool appendFormData(DOMFormData&, bool) const final;
    bool valueMissing(const String&) const final;
    String valueMissingText() const final;
    void handleDOMActivateEvent(Event&) final;
    RenderPtr<RenderElement> createInputRenderer(RenderStyle&&) final;
    bool canSetStringValue() const final;
    FileList* files() final;
    void setFiles(RefPtr<FileList>&&) final;
    enum class RequestIcon { Yes, No };
    void setFiles(RefPtr<FileList>&&, RequestIcon);
    String displayString() const final;
    bool canSetValue(const String&) final;
    bool getTypeSpecificValue(String&) final; // Checked first, before internal storage or the value attribute.
    void setValue(const String&, bool valueChanged, TextFieldEventBehavior) final;

#if ENABLE(DRAG_SUPPORT)
    bool receiveDroppedFiles(const DragData&) final;
#endif

    Icon* icon() const final;
    bool isFileUpload() const final;
    void createShadowSubtree() final;
    void disabledStateChanged() final;
    void attributeChanged(const QualifiedName&) final;
    String defaultToolTip() const final;

    void filesChosen(const Vector<FileChooserFileInfo>&, const String& displayString = { }, Icon* = nullptr) final;

    // FileIconLoaderClient implementation.
    void iconLoaded(RefPtr<Icon>&&) final;

    void requestIcon(const Vector<String>&);

    void applyFileChooserSettings(const FileChooserSettings&);

    bool allowsDirectories() const;

    RefPtr<FileChooser> m_fileChooser;
    std::unique_ptr<FileIconLoader> m_fileIconLoader;

    Ref<FileList> m_fileList;
    RefPtr<FileListCreator> m_fileListCreator;
    RefPtr<Icon> m_icon;
    String m_displayString;
};

} // namespace WebCore
