/*
 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
 * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
 * Copyright (C) 2003-2020 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 "CachedResourceHandle.h"
#include "DragActions.h"
#include "DragImage.h"
#include <wtf/text/WTFString.h>

namespace WebCore {

class CachedImage;
class DataTransferItemList;
class Document;
class DragData;
class DragImageLoader;
class Element;
class FileList;
class File;
class Pasteboard;
class ScriptExecutionContext;
enum class WebContentReadingPolicy : bool;

class DataTransfer : public RefCounted<DataTransfer> {
public:
    // https://html.spec.whatwg.org/multipage/dnd.html#drag-data-store-mode
    enum class StoreMode { Invalid, ReadWrite, Readonly, Protected };

    static Ref<DataTransfer> create();
    static Ref<DataTransfer> createForCopyAndPaste(const Document&, StoreMode, std::unique_ptr<Pasteboard>&&);
    static Ref<DataTransfer> createForInputEvent(const String& plainText, const String& htmlText);

    WEBCORE_EXPORT ~DataTransfer();

    String dropEffect() const;
    void setDropEffect(const String&);

    String effectAllowed() const;
    void setEffectAllowed(const String&);

    DataTransferItemList& items(Document&);
    Vector<String> types() const;
    Vector<String> typesForItemList() const;

    FileList& files(Document*) const;
    FileList& files(Document&) const;

    void clearData(const String& type = String());

    String getData(Document&, const String& type) const;
    String getDataForItem(Document&, const String& type) const;

    void setData(const String& type, const String& data);
    void setDataFromItemList(const String& type, const String& data);

    void setDragImage(Element&, int x, int y);

    void makeInvalidForSecurity() { m_storeMode = StoreMode::Invalid; }

    bool canReadTypes() const;
    bool canReadData() const;
    bool canWriteData() const;

    bool hasFileOfType(const String&);
    bool hasStringOfType(const String&);

    Pasteboard& pasteboard() { return *m_pasteboard; }
    void commitToPasteboard(Pasteboard&);

#if ENABLE(DRAG_SUPPORT)
    static Ref<DataTransfer> createForDrag(const Document&);
    static Ref<DataTransfer> createForDragStartEvent(const Document&);
    static Ref<DataTransfer> createForDrop(const Document&, std::unique_ptr<Pasteboard>&&, OptionSet<DragOperation>, bool draggingFiles);
    static Ref<DataTransfer> createForUpdatingDropTarget(const Document&, std::unique_ptr<Pasteboard>&&, OptionSet<DragOperation>, bool draggingFiles);

    bool dropEffectIsUninitialized() const { return m_dropEffect == "uninitialized"; }

    OptionSet<DragOperation> sourceOperationMask() const;
    OptionSet<DragOperation> destinationOperationMask() const;
    void setSourceOperationMask(OptionSet<DragOperation>);
    void setDestinationOperationMask(OptionSet<DragOperation>);

    void setDragHasStarted() { m_shouldUpdateDragImage = true; }
    DragImageRef createDragImage(IntPoint& dragLocation) const;
    void updateDragImage();
    RefPtr<Element> dragImageElement() const;

    void moveDragState(Ref<DataTransfer>&&);
    bool hasDragImage() const;
#endif

    void didAddFileToItemList();
    void updateFileList(ScriptExecutionContext*);

private:
    enum class Type { CopyAndPaste, DragAndDropData, DragAndDropFiles, InputEvent };
    DataTransfer(StoreMode, std::unique_ptr<Pasteboard>, Type = Type::CopyAndPaste, String&& effectAllowed = "uninitialized"_s);

#if ENABLE(DRAG_SUPPORT)
    bool forDrag() const { return m_type == Type::DragAndDropData || m_type == Type::DragAndDropFiles; }
    bool forFileDrag() const { return m_type == Type::DragAndDropFiles; }
#else
    bool forDrag() const { return false; }
    bool forFileDrag() const { return false; }
#endif

    String readStringFromPasteboard(Document&, const String& lowercaseType, WebContentReadingPolicy) const;
    bool shouldSuppressGetAndSetDataToAvoidExposingFilePaths() const;

    enum class AddFilesType { No, Yes };
    Vector<String> types(AddFilesType) const;
    Vector<Ref<File>> filesFromPasteboardAndItemList(ScriptExecutionContext*) const;

    String m_originIdentifier;
    StoreMode m_storeMode;
    std::unique_ptr<Pasteboard> m_pasteboard;
    std::unique_ptr<DataTransferItemList> m_itemList;

    mutable RefPtr<FileList> m_fileList;

#if ENABLE(DRAG_SUPPORT)
    Type m_type;
    String m_dropEffect;
    String m_effectAllowed;
    bool m_shouldUpdateDragImage;
    IntPoint m_dragLocation;
    CachedResourceHandle<CachedImage> m_dragImage;
    RefPtr<Element> m_dragImageElement;
    std::unique_ptr<DragImageLoader> m_dragImageLoader;
#endif
};

} // namespace WebCore
