#ifndef RKTWEBVIEW_QT_H
#define RKTWEBVIEW_QT_H

#include "rktutils.h"
#include "rktwebview_types.h"

#include <QApplication>
#include <QWebEngineView>
#include <QMutex>
#include <QThread>
#include <QHash>
#include <QQueue>
#include <QTimer>
#include <QEventLoop>
#include <QFileDialog>
#include <QSystemTrayIcon>


class WebViewQt;
class WebviewWindow;
class Command;
class CommandEvent;
class QSystemTrayIcon;
class QMenu;

class Rktwebview_qt : public QObject
{
    Q_OBJECT
private:
    QApplication                            *_app;
    rktwebview_t                             _current_handle;

    int                                      _context_counter;
    QHash<int, QWebEngineProfile *>          _contexts;
    QHash<int, WebviewWindow *>              _views;
    QHash<int, QSystemTrayIcon *>            _trays;
    QHash<int, QMenu *>                      _tray_menus;
    QHash<int, event_cb_t>                   _view_js_callbacks;

    QTimer                                   _process_events;

    int                                      _evt_loop_depth;
    QTimer                                   _evt_loop_timer;

    int                              _argc;
    char                           **_argv;

private:
    void runJs(rktwebview_t wv, const char *js);
    result_t doWindow(rktwebview_t w, int cmd, result_t on_error);

private slots:
    void stopEventloop();
    void handleTrayActivation(QSystemTrayIcon::ActivationReason reason);
    void handleTrayMessageClick();

private:
    void postCommand(Command *cmd);
    void handleCommandEvent(CommandEvent *e);
    void processCommand(Command *cmd);

    result_t fileDlg(rktwebview_t w,
                     const QString &title, const QString &base,
                     const QString &filters,
                     QFileDialog::FileMode mode, QFileDialog::AcceptMode am,
                     QString evt_ok, QString evt_cancel);

    void msgBox(rktwebview_t w,
                const QString &title, const QString &message, const QString &submessage,
                rkt_messagetype_t type);

public:
    void execApp();
    QApplication *app();
    void deleteApp();
    void initApp();

protected:
    void customEvent(QEvent *event);

public:
    void removeView(int id);

public:
    int nextHandle();

public:
    void closeAllWindows();

public:
    rkt_wv_context_t newContext(const QString &boilerplate_js, bool has_pem, const QString &optional_server_cert_pem);
    int  rktWebViewCreate(rkt_wv_context_t context, rktwebview_t parent, event_cb_t js_evt_cb);
    void rktWebViewClose(int wv);
    void rktSetOUToken(rktwebview_t wv, const char *ou_token);

    result_t rktOpenDevtools(rktwebview_t wv);
    result_t rktSetUrl(rktwebview_t wv, const char *url);
    result_t rktSetHtml(rktwebview_t wv, const char *html);
    result_t rktRunJs(rktwebview_t wv, const QString &js);
    rkt_data_t *rktCallJs(rktwebview_t wv, const char *js);

    result_t rktMove(rktwebview_t wv, int x, int y);
    result_t rktResize(rktwebview_t wv, int w, int h);
    result_t rktHideWindow(rktwebview_t w);
    result_t rktShowWindow(rktwebview_t w);
    result_t rktPresentWindow(rktwebview_t w);
    result_t rktMaximizeWindow(rktwebview_t w);
    result_t rktMinimizeWindow(rktwebview_t w);
    result_t rktShowNormalWindow(rktwebview_t w);
    window_state_t rktWindowState(rktwebview_t w);

    void rktQuit();

    result_t rktChooseDir(rktwebview_t w, const char *title, const char *base_dir);
    result_t rktFileOpen(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);
    result_t rktFileSave(rktwebview_t w, const char *title, const char *base_dir, const char *permitted_exts);

    result_t rktWindowSetTitle(rktwebview_t wv, const char *title);
    result_t rktWindowSetIcon(rktwebview_t wv, const char *icon_file);
    result_t rktMessageBox(rktwebview_t w, const char *title, const char *message, const char *submessage, rkt_messagetype_t type);

    bool rktValid(rktwebview_t wv);

public: // Tray
    rktwebview_t rktTrayCreate(const char *icon_file, const char *tooltip, event_cb_t evt_cb);
    result_t rktTraySetIcon(rktwebview_t tray, const char *icon_file);
    result_t rktTraySetTooltip(rktwebview_t tray, const char *tooltip);
    result_t rktTrayShowMessage(rktwebview_t tray, const char *title, const char *message);
    result_t rktTraySetMenu(rktwebview_t tray, const char *menu_json);

public:
    // Events for the backend
    void pageLoaded(rktwebview_t w, bool ok);
    void onPageLoad(rktwebview_t w);

public:
    int openWindows();

public:
    void triggerEvent(rktwebview_t wv, const QString &msg);
    void triggerEvent(rktwebview_t wv, const EventContainer &e);

public:
    void doEvents();

public:
    void runCommandThread();

public:
    Rktwebview_qt(int argc, char *argv[]);
    ~Rktwebview_qt();
};



#endif // RKTWEBVIEW_QT_H
