/* SPDX-License-Identifier: GPL-3.0-or-later
 * SPDX-FileCopyrightText: 2022-2024 Soren Stoutner <soren@stoutner.com>
 *
 * This file is part of Privacy Browser PC <https://www.stoutner.com/privacy-browser-pc/>.
 *
 * This program 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.
 *
 * This program 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
 * this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef TAB_WIDGET_H
#define TAB_WIDGET_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 *windowPointer);

    // The destructor.
    ~TabWidget();

    // The public variables.
    PrivacyWebEngineView *currentPrivacyWebEngineViewPointer;

    // The public functions.
    void applyOnTheFlyZoomFactor(const double zoomFactorDouble) const;
    PrivacyWebEngineView* loadBlankInitialWebsite();
    void loadInitialWebsite();
    void findPrevious(const QString &text) const;
    std::list<QNetworkCookie>* getCookieList() const;
    QIcon getCurrentTabFavoritIcon() const;
    QString getCurrentTabTitle() const;
    QString getCurrentTabUrl() const;
    QString getCurrentUserAgent() const;
    QString& getDomainSettingsName() const;
    void setTabBarVisible(const bool visible) const;
    void toggleDeveloperTools(const bool enabled) const;
    void toggleDomStorage() const;
    void toggleFindCaseSensitive(const QString &text);
    void toggleJavaScript() const;
    void toggleLocalStorage();

    // The public static variables.
    static QString webEngineDefaultUserAgent;

Q_SIGNALS:
    // The signals.
    void addCookie(const QNetworkCookie &cookie) const;
    void blockedRequestsUpdated(const QVector<int> blockedRequests) const;
    void cookiesChanged(const int numberOfCookies) const;
    void easyListStatusChanged(const bool isEnabled) const;
    void easyPrivacyStatusChanged(const bool isEnabled) const;
    void fanboysAnnoyanceListStatusChanged(const bool isEnabled) 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 ultraListStatusChanged(const bool) const;
    void ultraPrivacyStatusChanged(const bool) const;
    void updateBackAction(const bool isEnabled) const;
    void updateDefaultZoomFactor(const double newDefaultZoomFactorDouble) const;
    void updateDeveloperToolsAction(const bool isEnabled) 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 updateZoomActions(const double zoomFactorDouble) const;

public Q_SLOTS:
    // The public slots.
    void addCookieToStore(QNetworkCookie cookie, QWebEngineCookieStore *webEngineCookieStorePointer = nullptr) const;
    PrivacyWebEngineView* addTab(const bool removeUrlLineEditFocus = false, const bool adjacent = false, const bool backgroundTab = false, const QString urlString = QLatin1String(""));
    void applyApplicationSettings();
    void applyDomainSettingsAndReload();
    void applyOnTheFlySearchEngine(QAction *searchEngineActionPointer);
    void applyOnTheFlyUserAgent(QAction *userAgentActionPointer) const;
    void applySpellCheckLanguages() 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;
    void reloadAndBypassCache() const;
    void saveArchive();
    void stop() const;
    void storeCurrentUrlText(const QString &urlText) const;
    void toggleEasyList() const;
    void toggleEasyPrivacy() const;
    void toggleFanboysAnnoyanceList() const;
    void toggleUltraList() const;
    void toggleUltraPrivacy() 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 showSaveDialog(QWebEngineDownloadRequest *downloadRequestPointer);
    void stopLoadingFavoriteIconMovie() const;
    void updateUiFromWebEngineView(const PrivacyWebEngineView *privacyWebEngineViewPointer) const;
    void updateUiWithTabSettings();
    void useNativeKdeDownloader(QUrl &downloadUrl, QString &suggestedFileName);

private:
    // The private functions.
    void updateDownloadDirectory(QString newDownloadDirectory) const;

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