/*
 * Copyright 2022-2023 Soren Stoutner <soren@stoutner.com>.
 *
 * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc>.
 *
 * Privacy Browser PC is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Privacy Browser PC 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Privacy Browser PC.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef TABWIDGET_H
#define TABWIDGET_H

// Application headers.
#include "PrivacyWebEngineView.h"
#include "helpers/UserAgentHelper.h"

// KDE Framework headers.
#include <KLineEdit>

// Qt toolkit headers.
#include <QMovie>
#include <QPushButton>
#include <QTabWidget>
#include <QWebEngineCookieStore>
#include <QWebEngineFullScreenRequest>
#include <QWebEngineHistory>
#include <QWebEngineProfile>
#include <QWebEngineSettings>
#include <QWebEngineView>

class TabWidget : public QWidget
{
    // Include the Q_OBJECT macro.
    Q_OBJECT

public:
    // The primary contructor.
    explicit TabWidget(QWidget *parent);

    // The destructor.
    ~TabWidget();

    // The public functions.
    void applyOnTheFlyZoomFactor(const double &zoomFactor) const;
    void applySpellCheckLanguages() const;
    PrivacyWebEngineView* loadBlankInitialWebsite();
    void loadInitialWebsite();
    void findPrevious(const QString &text) const;
    std::list<QNetworkCookie>* getCookieList() const;
    QString& getDomainSettingsName() const;
    void setTabBarVisible(const bool visible) const;
    void toggleDomStorage() const;
    void toggleFindCaseSensitive(const QString &text);
    void toggleJavaScript() const;
    void toggleLocalStorage();

    // The public static variables.
    static QString webEngineDefaultUserAgent;

signals:
    // The signals.
    void addCookie(const QNetworkCookie &cookie) const;
    void removeCookie(const QNetworkCookie &cookie) const;
    void clearUrlLineEditFocus() const;
    void fullScreenRequested(const bool toggleOn) const;
    void hideProgressBar() const;
    void linkHovered(const QString &linkUrl) const;
    void showProgressBar(const int &progress) const;
    void updateBackAction(const bool &isEnabled) const;
    void updateCookiesAction(const int numberOfCookies) const;
    void updateDomStorageAction(const bool &isEnabled) const;
    void updateDomainSettingsIndicator(const bool status) const;
    void updateFindText(const QString &text, const bool findCaseSensitive) const;
    void updateFindTextResults(const QWebEngineFindTextResult &findTextResult) const;
    void updateForwardAction(const bool &isEnabled) const;
    void updateJavaScriptAction(const bool &isEnabled) const;
    void updateLocalStorageAction(const bool &isEnabled) const;
    void updateSearchEngineActions(const QString &searchEngine, const bool &updateCustomSearchEngineStatus) const;
    void updateUrlLineEdit(const QUrl &newUrl) const;
    void updateUserAgentActions(const QString &userAgent, const bool &updateCustomUserAgentStatus) const;
    void updateWindowTitle(const QString &title) const;
    void updateZoomFactorAction(const double &zoomFactor) const;

public Q_SLOTS:
    // The public slots.
    void addCookieToStore(QNetworkCookie cookie, QWebEngineCookieStore *webEngineCookieStorePointer = nullptr) const;
    PrivacyWebEngineView* addTab(const bool removeUrlLineEditFocus=false, const bool backgroundTab=false);
    void applyApplicationSettings();
    void applyDomainSettingsAndReload();
    void applyOnTheFlySearchEngine(QAction *searchEngineActionPointer);
    void applyOnTheFlyUserAgent(QAction *userAgentActionPointer) const;
    void back() const;
    void deleteAllCookies() const;
    void deleteCookieFromStore(const QNetworkCookie &cookie) const;
    void findText(const QString &text) const;
    void forward() const;
    void home() const;
    void loadUrlFromLineEdit(QString url) const;
    void mouseBack() const;
    void mouseForward() const;
    void print() const;
    void printPreview() const;
    void refresh() const;

private Q_SLOTS:
    // The private slots.
    void addFirstTab();
    void deleteTab(const int tabIndex);
    void findTextFinished(const QWebEngineFindTextResult &findTextResult);
    void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest) const;
    void pageLinkHovered(const QString &linkUrl) const;
    void printWebpage(QPrinter *printerPointer) const;
    void showSaveDialog(QWebEngineDownloadItem *downloadItemPointer);
    void updateUiFromWebEngineView(const PrivacyWebEngineView *privacyWebEngineViewPointer) const;
    void updateUiWithTabSettings();
    void useNativeKdeDownloader(QUrl &downloadUrl, QString &suggestedFileName);

private:
    // The private variables.
    PrivacyWebEngineView *currentPrivacyWebEngineViewPointer;
    QWebEngineCookieStore *currentWebEngineCookieStorePointer;
    QWebEngineHistory *currentWebEngineHistoryPointer;
    QWebEnginePage *currentWebEnginePagePointer;
    QWebEngineProfile *currentWebEngineProfilePointer;
    QWebEngineSettings *currentWebEngineSettingsPointer;
    QIcon defaultFavoriteIcon = QIcon::fromTheme(QStringLiteral("globe"));
    bool isRunningKde = false;
    QMovie *loadingFavoriteIconMoviePointer;
    QString searchEngineUrl;
    QTabWidget *qTabWidgetPointer;
    UserAgentHelper *userAgentHelperPointer;
    bool wipingCurrentFindTextSelection = false;
};
#endif
