/**
 * Copyright (c) 2022
 *    Marcus Britanicus (https://gitlab.com/marcusbritanicus)
 *    Abrar (https://gitlab.com/s96Abrar)
 *    rahmanshaber (https://gitlab.com/rahmanshaber)
 *
 * The DFL::Clipboard::Manager class manages the wayland clipboard.
 **/

#pragma once

#include <QtCore>
#include <wayqt/DataControl.hpp>

namespace DFL {
    namespace Clipboard {
        class Manager;
        class Table;

        enum Type {
            Clipboard = 0x6b52c7,       // Clipboard accessible through Ctrl-X/Ctrl-C
            Selection                   // Primary accessible through Selection
        };
    }
}

class DFL::Clipboard::Manager : public QObject {
    Q_OBJECT;

    public:

        /**
         * @path is the location where the history will be stored
         */
        Manager( QString path );

        /**
         * Request the manager to offer data at index @idx
         * from ClipboardType @type. The manager is free to
         * deny this reuest.
         *
         * Accepting this request entails the data at index @idx
         * to be promoted to top. This will require the UIs to
         * be reloaded.
         */
        void requestOffer( DFL::Clipboard::Type type, int idx );

        /**
         * Disable selections.
         */
        bool isSelectionEnabled();
        void setSelectionDisabled( bool yes );

        /**
         * Ignore selections.
         * If the selections are ignored, then selections work
         * as if this manager did not exist.
         */
        bool isSelectionIgnored();
        void setSelectionIgnored( bool yes );

        /**
         * Store the selections in a file.
         * If the selections are stored, then they can be restored
         * next time the clipboard is started.
         */
        bool isHistoryStored();
        void setStoreHistory( bool yes );

        /**
         * Number of entries stored
         */
        quint64 historySize();
        void setHistorySize( quint64 size );

        /**
         * Large data limit
         */
        bool isSizeLimitSet();
        quint64 largeDataSizeLimit();
        void setLargeDataSizeLimit( quint64 size );

    private:
        /** DataControlManager pointer; Used multiple times */
        WQt::DataControlManager *mDataMgr;

        /** DataControlDevice pointer; Used multiple times */
        WQt::DataControlDevice *mDataDev;

        /** Clipboard table */
        DFL::Clipboard::Table *clipboard;

        /** Selection table */
        DFL::Clipboard::Table *selection;

        /** Stores the last gathered Clipboard data which is not null */
        WQt::MimeData lastClipboard;

        /** Stores the last gathered Primary data which is not null */
        WQt::MimeData lastSelection;

        /** For testing purposes */
        WQt::DataControlSource *clpSrc;
        WQt::DataControlSource *selSrc;

        /** Flag to completely disable selection */
        bool mDisableSelections = false;

        /** Flag to ignore selection */
        bool mIgnoreSelections = false;

        /** Flag to store selections */
        bool mStoreHistory = true;

        /** History size */
        quint64 mHistorySize = 30;

        /** Large data size limit */
        bool mLimitSize      = true;
        quint64 mMaxDataSize = 26214400;

        /**
         * Clipboard offer - Store the data if not null.
         * Then, offer the last stored data.
         */
        void handleClipboardOffer( WQt::DataControlOffer *offer );

        /**
         * Selection offer - Store the data if not null.
         * Then, offer the last stored data.
         */
        void handleSelectionOffer( WQt::DataControlOffer *offer );

        /**
         * Offer the last collected data as Clipboard
         */
        void offerClipboard( WQt::MimeData mData );

        /**
         * Selection offer - Store the data if not null.
         * Then, offer the last stored data.
         */
        void offerSelection( WQt::MimeData mData );

        /**
         * Gather the offered data
         */
        WQt::MimeData gatherOfferedData( WQt::DataControlOffer *offer );

    Q_SIGNALS:
        void updateView( int );
        void largeData( int );
};
