/*
 *   This file is part of Dianara
 *   Copyright 2012-2019  JanKusanagi JRR <jancoding@gmx.com>
 *
 *   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 2 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, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .
 */

#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#include <QMainWindow>
#include <QApplication>
#include <QSettings>
#include <QMenuBar>
#include <QToolBar>
#include <QStatusBar>
#include <QSystemTrayIcon>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QToolBox>
#include <QTabWidget>
#include <QLabel>
#include <QCloseEvent>
#include <QByteArray>
#include <QPixmap>
#include <QMessageBox>
#include <QDir>
#include <QTimer>
#include <QScrollArea>
#include <QScrollBar>
#include <QVariantList>
#include <QDesktopServices>
#include <QStandardPaths>
#include <QTime>
#include <QDockWidget>
#include <QPainter>
#include <QSessionManager>

#ifdef QT_DBUS_LIB
#include <QtDBus>
#include "dbusinterface.h"
#endif

#ifdef HAVE_SONNET_SPELLCHECKER
#include <Sonnet/Speller>
#include <Sonnet/ConfigDialog>
#endif

#include <QDebug>

#include <iostream>

#include "accountdialog.h"
#include "configdialog.h"
#include "pumpcontroller.h"
#include "notifications.h"
#include "publisher.h"
#include "timeline.h"
#include "post.h"
#include "contactmanager.h"
#include "minorfeed.h"
#include "profileeditor.h"
#include "filtereditor.h"
#include "filterchecker.h"
#include "logviewer.h"
#include "helpwidget.h"
#include "groupsmanager.h"
#include "globalobject.h"
#include "userposts.h"
#include "firstrunwizard.h"
#include "bannernotification.h"


class MainWindow : public QMainWindow
{
    Q_OBJECT


public:    
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

    void prepareDataDirectory();
    void createMenus();
    void createToolbar();
    virtual QMenu *createPopupMenu();
    void createStatusbarWidgets();

    enum StatusType
    {
        Initializing,
        Autoupdating,
        Stopped
    };

    void setStateIcon(StatusType statusType);
    void createTrayIcon();
    void setTrayIconPixmap(int newCount = 0, int highlightedCount = 0);

    void loadSettings();
    void loadMainWindowConfig();
    void saveSettings();

    void enableIgnoringSslErrors();
    void enableNoHttpsMode();

    Post *findPostInTimelines(QString id, bool *ok);

    void loadPostsEverSeen();
    void savePostsEverSeen();


public slots:
    void updateUserId(QString newUserId);
    void updateConfigSettings();

    void toggleWidgetsByAuthorization(bool authorized);

    void onInitializationComplete();

    void postInit();

    void showErrorPopup(QString message);

    void trayControl(QSystemTrayIcon::ActivationReason reason);
    void showTrayFallbackMessage(QString title, QString message, int duration);

    void updateProfileData(QString avatarUrl, QString fullName,
                           QString hometown, QString bio,
                           QString eMail);

    void toggleAutoUpdates(bool checked);
    void onTimelineAutoupdate();

    void updateAllTimelines();
    void onUpdateRequestViaBanner();
    void onUpdateDelayedViaBanner();
    void updateMainAndMinorTimelines();
    void updateMainActivityMinorTimelines();
    void updateFavoritesTimeline();
    void updateActionsFeed();

    void scrollMainTimelineTo(QAbstractSlider::SliderAction sliderAction);
    void scrollDirectTimelineTo(QAbstractSlider::SliderAction sliderAction);
    void scrollActivityTimelineTo(QAbstractSlider::SliderAction sliderAction);
    void scrollFavoritesTimelineTo(QAbstractSlider::SliderAction sliderAction);

    void scrollMainTimelineToWidget(QWidget *widget);
    void scrollDirectTimelineToWidget(QWidget *widget);
    void scrollActivityTimelineToWidget(QWidget *widget);
    void scrollFavoritesTimelineToWidget(QWidget *widget);

    void scrollToNewPosts();

    void notifyTimelineUpdate(PumpController::requestTypes timelineType,
                              int newPostCount, int highlightCount,
                              int directPostCount, int hlByFilterCount,
                              int deletedPostCount, int filteredPostCount,
                              int pendingPostCount, QString currentPage);
    void setTimelineTabTitle(PumpController::requestTypes timelineType,
                             int newPostCount,
                             int highlightCount,
                             int totalFeedPostCount);

    void setTitleAndTrayInfo(int currentTab);
    void setMinorFeedTitle(int newItemsCount, int newHighlightedItemsCount);
    void setMentionsFeedTitle(int newItemsCount, int newHighlightedItemsCount);
    void notifyMinorFeedUpdate(PumpController::requestTypes feedType,
                               int newItemsCount,
                               int highlightedCount,
                               int filteredCount,
                               int pendingItemsCount);


    void storeAvatar(QByteArray avatarData, QString avatarUrl);
    void storeImage(QByteArray imageData, QString imageUrl);

    void setStatusBarMessage(QString message);
    void setTransientStatusMessage(QString message);

    void markAllAsRead();
    void startPost(QString title="", QString content="");
    void refreshAllTimestamps();
    void adjustTimelineSizes();

    void showUserTimeline(QString userId, QString userName,
                          QIcon userAvatar, QString userOutbox);


    void toggleLockedPanels(bool locked);
    void toggleSidePanel(bool shown);
    void toggleToolbar(bool shown);
    void toggleStatusBar(bool shown);
    void toggleFullscreen(bool enabled);

    void toggleMeanwhileFeed();
    void toggleMentionsFeed();
    void toggleActionsFeed();


    void showFirstRunWizard();
    void visitWebSite();
    void visitBugTracker();
    void visitPumpGuide();
    void visitTips();
    void visitUserList();
    void visitPumpStatus();
    void aboutDianara();

    void toggleMainWindow(bool firstTime=false);

    void onNotificationAction(uint id, QString action);

    void showAuthError(QString title, QString message);

    void onSessionManagerQuitRequest(QSessionManager &manager);
    void quitProgram(QString reason="");


protected:
    virtual void closeEvent(QCloseEvent *event);
    virtual void resizeEvent(QResizeEvent *event);


private:
    ////////////////////////////////////// Menus
    QMenu *sessionMenu;
    QMenu *viewMenu;
    QMenu *settingsMenu;
    QMenu *helpMenu;

    QMenu *trayContextMenu;
    QAction *m_trayTitleAction;
    QAction *trayShowWindowAction;

    QAction *sessionUpdateMainTimeline;
    QAction *sessionUpdateDirectTimeline;
    QAction *sessionUpdateActivityTimeline;
    QAction *sessionUpdateFavoritesTimeline;
    QAction *sessionUpdateMinorFeedMain;
    QAction *sessionUpdateMinorFeedDirect;
    QAction *sessionUpdateMinorFeedActivity;
    QAction *sessionAutoUpdates;
    QAction *sessionMarkAllAsRead;
    QAction *sessionPostNote;
    QAction *sessionQuit;

    QAction *viewLockPanels;
    QAction *viewSidePanel;
    QAction *viewToolbar;
    QAction *viewStatusBar;
    QAction *viewFullscreenAction;
    QAction *viewLogAction;

    QAction *settingsEditProfile;
    QAction *settingsAccount;
    QAction *settingsFilters;
    QAction *settingsConfigure;

    QAction *helpBasicHelp;
    QAction *helpShowWizard;
    QAction *helpVisitWebsite;
    QAction *helpVisitBugTracker;
    QAction *helpVisitPumpGuide;
    QAction *helpVisitPumpTips;
    QAction *helpVisitPumpUserList;
    QAction *helpVisitPumpStatus;
    QAction *helpAbout;
    ////////////////////////////////////// End menus


    // Info label for the menu
    QHBoxLayout *m_menuInfoLayout;
    QWidget *m_menuInfoWidget;
    QLabel *m_menuInfoLabel;

    // Toolbar
    QToolBar *m_mainToolBar;

    // Statusbar widgets
    QToolButton *m_statusStateButton;
    QToolButton *m_statusLogButton;

    QPushButton *m_statusAccountButton; // Shown when no account is configured
    bool m_statusAccountButtonUsed;
    QProgressBar *initializationProgressBar;


    QDockWidget *sideDockWidget;
    QWidget *sideDockTitleWidget;
    QWidget *leftSideWidget;
    QVBoxLayout *leftLayout;

    QHBoxLayout *leftTopLayout;
    QVBoxLayout *userInfoLayout;
    QToolBox *leftPanel;

    QAction *showMeanwhileFeed;
    QAction *showMentionsFeed;
    QAction *showActionsFeed;

    QWidget *m_rightSideWidget;
    QVBoxLayout *rightLayout;
    QTabWidget *tabWidget;
    int m_tabsPosition;
    bool m_tabsMovable;

    // User profile widgets
    QPushButton *avatarIconButton;
    QString m_avatarUrl;
    QLabel *m_fullNameLabel;
    QLabel *m_userIdLabel;
    QLabel *m_userHometownLabel;


    QSystemTrayIcon *trayIcon;
    bool trayIconAvailable;
    int trayIconType;
    QPixmap trayCustomPixmap;
    int trayCurrentNewCount;
    int trayCurrentHLCount;


    GlobalObject *globalObject;

    AccountDialog *m_accountDialog;
    ProfileEditor *m_profileEditor;
    ConfigDialog *m_configDialog;
    FilterChecker *m_filterChecker;
    FilterEditor *m_filterEditor;
    LogViewer *m_logViewer;
    HelpWidget *m_helpWidget;
    PumpController *pumpController;
    FDNotifications *m_fdNotifications;

    MinorFeed *meanwhileFeed;
    MinorFeed *mentionsFeed;
    MinorFeed *actionsFeed;

    BannerNotification *m_bannerNotification;

    TimeLine *mainTimeline;
    QScrollArea *mainTimelineScrollArea;

    TimeLine *directTimeline;
    QScrollArea *directTimelineScrollArea;

    TimeLine *activityTimeline;
    QScrollArea *activityTimelineScrollArea;

    TimeLine *favoritesTimeline;
    QScrollArea *favoritesTimelineScrollArea;


    ContactManager *contactManager;

    Publisher *publisher;

#ifdef HAVE_SONNET_SPELLCHECKER
    Sonnet::ConfigDialog *m_spellConfigDialog;
#endif

#ifdef QT_DBUS_LIB
    DBusInterface *m_dbusInterface;
#endif


    bool firstRun;
    QString dataDirectory; // will have /images, /avatars, etc
    bool reallyQuitProgram;
    bool initializationComplete;

    int postIdsToStore;


    // Timer stuff
    int updateInterval;
    QTimer *updateTimer;

    QTimer *timestampsTimer;
    QTimer *delayedResizeTimer;
    QTimer *postInitTimer;
    QTimer *favoritesReloadTimer;
    QTimer *userDidSomethingTimer;
    QTimer *delayedScrollTimer;

    // Statusbar stuff
    QString oldStatusBarMessage;
    QString previousStatusFeedInfo;

    // User account-related data
    QString m_userId;

};

#endif // MAINWINDOW_H
