#ifndef SBK_AGENTINSTANCEFILTERPROXYMODELWRAPPER_H
#define SBK_AGENTINSTANCEFILTERPROXYMODELWRAPPER_H

// Workaround to access protected functions
#ifndef protected
#  define protected public
#endif

#include <agentinstancefilterproxymodel.h>

#include <sbkpython.h>

#include <array>
namespace Shiboken { struct AutoDecRef; class GilState; }

namespace PySide { class DynamicQMetaObject; }

class AgentInstanceFilterProxyModelWrapper : public Akonadi::AgentInstanceFilterProxyModel
{
public:
    AgentInstanceFilterProxyModelWrapper(::QObject * parent = nullptr);
    AgentInstanceFilterProxyModelWrapper(const AgentInstanceFilterProxyModelWrapper &) = delete;
    AgentInstanceFilterProxyModelWrapper& operator=(const AgentInstanceFilterProxyModelWrapper &) = delete;
    AgentInstanceFilterProxyModelWrapper(AgentInstanceFilterProxyModelWrapper &&) = delete;
    AgentInstanceFilterProxyModelWrapper& operator=(AgentInstanceFilterProxyModelWrapper &&) = delete;
    ~AgentInstanceFilterProxyModelWrapper() override;

    ::QModelIndex buddy(const ::QModelIndex & index) const override;
    bool canDropMimeData(const ::QMimeData * data, ::Qt::DropAction action, int row, int column, const ::QModelIndex & parent) const override;
    bool canFetchMore(const ::QModelIndex & parent) const override;
    void childEvent(::QChildEvent * event) override;
    bool clearItemData(const ::QModelIndex & index) override;
    int columnCount(const ::QModelIndex & parent = QModelIndex()) const override;
    void connectNotify(const ::QMetaMethod & signal) override;
    void customEvent(::QEvent * event) override;
    ::QVariant data(const ::QModelIndex & index, int role = Qt::DisplayRole) const override;
    void disconnectNotify(const ::QMetaMethod & signal) override;
    bool dropMimeData(const ::QMimeData * data, ::Qt::DropAction action, int row, int column, const ::QModelIndex & parent) override;
    bool event(::QEvent * event) override;
    bool eventFilter(::QObject * watched, ::QEvent * event) override;
    void fetchMore(const ::QModelIndex & parent) override;
    bool filterAcceptsColumn(int source_column, const ::QModelIndex & source_parent) const override;
    bool filterAcceptsRow(int row, const ::QModelIndex & parent) const override;
    ::QFlags<Qt::ItemFlag> flags(const ::QModelIndex & index) const override;
    bool hasChildren(const ::QModelIndex & parent = QModelIndex()) const override;
    ::QVariant headerData(int section, ::Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
    ::QModelIndex index(int row, int column, const ::QModelIndex & parent = QModelIndex()) const override;
    bool insertColumns(int column, int count, const ::QModelIndex & parent = QModelIndex()) override;
    bool insertRows(int row, int count, const ::QModelIndex & parent = QModelIndex()) override;
    ::QMap<int,QVariant> itemData(const ::QModelIndex & index) const override;
    bool lessThan(const ::QModelIndex & source_left, const ::QModelIndex & source_right) const override;
    ::QModelIndex mapFromSource(const ::QModelIndex & sourceIndex) const override;
    ::QItemSelection mapSelectionFromSource(const ::QItemSelection & sourceSelection) const override;
    ::QItemSelection mapSelectionToSource(const ::QItemSelection & proxySelection) const override;
    ::QModelIndex mapToSource(const ::QModelIndex & proxyIndex) const override;
    ::QList<QModelIndex> match(const ::QModelIndex & start, int role, const ::QVariant & value, int hits = 1, ::QFlags<Qt::MatchFlag> flags = Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const override;
    ::QMimeData * mimeData(const ::QList<QModelIndex> & indexes) const override;
    ::QStringList mimeTypes() const override;
    bool moveColumns(const ::QModelIndex & sourceParent, int sourceColumn, int count, const ::QModelIndex & destinationParent, int destinationChild) override;
    bool moveRows(const ::QModelIndex & sourceParent, int sourceRow, int count, const ::QModelIndex & destinationParent, int destinationChild) override;
    void multiData(const ::QModelIndex & index, ::QModelRoleDataSpan roleDataSpan) const override;
    ::QModelIndex parent(const ::QModelIndex & child) const override;
    bool removeColumns(int column, int count, const ::QModelIndex & parent = QModelIndex()) override;
    bool removeRows(int row, int count, const ::QModelIndex & parent = QModelIndex()) override;
    void resetInternalData() override;
    void revert() override;
    ::QHash<int,QByteArray> roleNames() const override;
    int rowCount(const ::QModelIndex & parent = QModelIndex()) const override;
    bool setData(const ::QModelIndex & index, const ::QVariant & value, int role = Qt::EditRole) override;
    bool setHeaderData(int section, ::Qt::Orientation orientation, const ::QVariant & value, int role = Qt::EditRole) override;
    bool setItemData(const ::QModelIndex & index, const ::QMap<int,QVariant> & roles) override;
    void setSourceModel(::QAbstractItemModel * sourceModel) override;
    ::QModelIndex sibling(int row, int column, const ::QModelIndex & idx) const override;
    void sort(int column, ::Qt::SortOrder order = Qt::AscendingOrder) override;
    ::QSize span(const ::QModelIndex & index) const override;
    bool submit() override;
    ::QFlags<Qt::DropAction> supportedDragActions() const override;
    ::QFlags<Qt::DropAction> supportedDropActions() const override;
    void timerEvent(::QTimerEvent * event) override;

    const ::QMetaObject * metaObject() const override;
    int qt_metacall(QMetaObject::Call call, int id, void **args) override;
    void *qt_metacast(const char *_clname) override;
    static void pysideInitQtMetaTypes();

    void resetPyMethodCache();

private:
    mutable std::array<PyObject *, 52> m_PyMethodCache = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
};

#endif // SBK_AGENTINSTANCEFILTERPROXYMODELWRAPPER_H
