#ifndef SBK_PLUGININTERFACEWRAPPER_H
#define SBK_PLUGININTERFACEWRAPPER_H

#include <plugininterface.h>


// Argument includes
#include <QString>
#include <plugininterface.h>
#include <qevent.h>
#include <qmenu.h>
#include <qobject.h>
#include <qurl.h>
#include <qwebenginepage.h>
#include <qwidget.h>
#include <qzcommon.h>
#include <webhittestresult.h>
#include <webpage.h>
#include <webview.h>
#include <sbkpython.h>

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

class PluginInterfaceWrapper : public PluginInterface
{
public:
    PluginInterfaceWrapper();
    PluginInterfaceWrapper(const PluginInterfaceWrapper &) = delete;
    PluginInterfaceWrapper& operator=(const PluginInterfaceWrapper &) = delete;
    PluginInterfaceWrapper(PluginInterfaceWrapper &&) = delete;
    PluginInterfaceWrapper& operator=(PluginInterfaceWrapper &&) = delete;
    ~PluginInterfaceWrapper() override;

    bool acceptNavigationRequest(::WebPage * page, const ::QUrl & url, ::QWebEnginePage::NavigationType type, bool isMainFrame) override;
    static bool sbk_o_acceptNavigationRequest([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] ::WebPage * page, [[maybe_unused]] const ::QUrl & url, [[maybe_unused]] ::QWebEnginePage::NavigationType type, [[maybe_unused]] bool isMainFrame);
    void init(::PluginInterface::InitState state, const ::QString & settingsPath) override;
    static void sbk_o_init([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] ::PluginInterface::InitState state, [[maybe_unused]] const ::QString & settingsPath);
    bool keyPress(::Qz::ObjectName type, ::QObject * obj, ::QKeyEvent * event) override;
    static bool sbk_o_keyPress([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] ::Qz::ObjectName type, [[maybe_unused]] ::QObject * obj, [[maybe_unused]] ::QKeyEvent * event);
    bool keyRelease(::Qz::ObjectName type, ::QObject * obj, ::QKeyEvent * event) override;
    bool mouseDoubleClick(::Qz::ObjectName type, ::QObject * obj, ::QMouseEvent * event) override;
    static bool sbk_o_mouseDoubleClick([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] ::Qz::ObjectName type, [[maybe_unused]] ::QObject * obj, [[maybe_unused]] ::QMouseEvent * event);
    bool mouseMove(::Qz::ObjectName type, ::QObject * obj, ::QMouseEvent * event) override;
    bool mousePress(::Qz::ObjectName type, ::QObject * obj, ::QMouseEvent * event) override;
    bool mouseRelease(::Qz::ObjectName type, ::QObject * obj, ::QMouseEvent * event) override;
    bool newWindowRequested(::WebPage * page, ::QWebEngineNewWindowRequest & request) override;
    static bool sbk_o_newWindowRequested([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] ::WebPage * page, [[maybe_unused]] ::QWebEngineNewWindowRequest & request);
    void populateExtensionsMenu(::QMenu * menu) override;
    void populateWebViewMenu(::QMenu * menu, ::WebView * view, const ::WebHitTestResult & r) override;
    static void sbk_o_populateWebViewMenu([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] ::QMenu * menu, [[maybe_unused]] ::WebView * view, [[maybe_unused]] const ::WebHitTestResult & r);
    void showSettings(::QWidget * parent = nullptr) override;
    static void sbk_o_showSettings([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] ::QWidget * parent = nullptr);
    bool testPlugin() override;
    void unload() override;
    bool wheelEvent(::Qz::ObjectName type, ::QObject * obj, ::QWheelEvent * event) override;
    static bool sbk_o_wheelEvent([[maybe_unused]] const char *ownerClassName, [[maybe_unused]] const char *funcName, [[maybe_unused]] Shiboken::GilState &gil, [[maybe_unused]] const Shiboken::AutoDecRef &pyOverride, [[maybe_unused]] ::Qz::ObjectName type, [[maybe_unused]] ::QObject * obj, [[maybe_unused]] ::QWheelEvent * event);
    static void pysideInitQtMetaTypes();

    void resetPyMethodCache();

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

#endif // SBK_PLUGININTERFACEWRAPPER_H
