/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#pragma once

#include <QModelIndex>
#include <QSettings>
#include <QThread>

#include "MvMessageMetaData.h"

#include "MvQMainWindow.h"

class QAction;
class QActionGroup;
class QCheckBox;
class QComboBox;
class QHBoxLayout;
class QLabel;
class QListView;
class QProgressBar;
class QSortFilterProxyModel;
class QSplitter;
class QStackedLayout;
class QToolButton;
class QVBoxLayout;

class MessageControlPanel;
class MvKeyProfile;
class BufrMetaData;

class MvQArrowSpinWidget;
class MvQFileInfoLabel;
class MvQFileList;
class MvQFileListWidget;
class MvQKeyManager;
class MvQKeyProfileModel;
class MvQKeyProfileSortFilterModel;
class MvQKeyProfileTree;
class MvQLogPanel;
class MvQTreeViewSearchLine;
class MvQTreeView;

class CodesPanel;

class MvQAbstractMessageScanner;

class MvQMessagePanel : public QWidget, public MvMessageMetaDataObserver
{
    Q_OBJECT
public:
    explicit MvQMessagePanel(QWidget* parent = nullptr);

    void init(MvMessageMetaData*);
    void loadKeyProfile(MvKeyProfile* prof);
    MvKeyProfile* keyProfile() const;
    void clearProfile();

public slots:
    void selectMessage(int);
    void adjustProfile(bool, int);
    void slotMessageDataInvalid(int msg);

protected slots:
    void selectMessage(QModelIndex);

    void slotKeyProfileLoadStarted();
    void slotKeyProfileLoadFinished();
    void slotKeyProfileLoadProgress(int);
    void slotKeyProfileReady(MvKeyProfile*);

signals:
    void messageSelected(int);
    void profileLoaded();
    void messageScanProgess(int);
    void keyProfileReady();
    void keyProfileChanged();
    void keyProfileLoadProgress(int);
    void keyProfileLoadFinished();
    void messageNumDetermined();

protected:
    void messageScanStepChanged(int) override;

private:
    void loadKeyProfileCore(MvKeyProfile* prof);

    MvQKeyProfileTree* tree_;
    MvQKeyProfileModel* model_;
    MvQKeyProfileSortFilterModel* sortModel_;
    MvMessageMetaData* data_;
    MvQAbstractMessageScanner* loader_;
    QWidget* progWidget_;
    QLabel* progLabel_;
    QProgressBar* progBar_;
};

class MvQAbstractMessageExaminer : public MvQMainWindow
{
    Q_OBJECT

public:
    enum Type
    {
        GribType,
        BufrType
    };

    MvQAbstractMessageExaminer(QString, Type, QWidget* parent = nullptr);
    ~MvQAbstractMessageExaminer() override;

    void init(MvMessageMetaData*, MvQKeyManager*, MvQFileList*);
    QString currentKeyProfileName();
    void setCurrentKeyProfileName(QString);

protected slots:
    void slotManageKeyProfiles();
    void slotLoadKeyProfile(int);
    void slotKeyProfileChanged();
    void slotCreateNewProfile();
    void slotSaveAsCurrentProfile();
    virtual void slotShowAboutBox() = 0;
    void slotAddFile(bool);
    virtual void slotLoadFile(QString) = 0;
    void slotClearFilePanel(bool);
    void slotCloseFilePanel(bool);
    void slotSocketMessage(QString msg);
    virtual void updateFileInfoLabel() = 0;
#ifdef ECCODES_UI
    void slotUiStyleSelect(QAction*);
#endif

signals:
    void keyProfileChanged();

protected:
    void closeEvent(QCloseEvent*) override;

    virtual void setupFileMenu();
    virtual void setupEditMenu();
    virtual void setupViewMenu();
    virtual void setupSettingsMenu();
    virtual void setupProfilesMenu();
    virtual void setupHelpMenu();
    void setupMessagePanel();

    virtual void loadKeyProfile(MvKeyProfile*) = 0;
    void loadKeyProfileCore(MvKeyProfile*);
    virtual MvKeyProfile* loadedKeyProfile() const = 0;
    void saveKeyProfiles(bool);

    virtual void initMain(MvMessageMetaData*) = 0;
    virtual void initDumps() = 0;
    virtual void initAllKeys() = 0;

    void updateWinTitle(QString);

    void clearLog();

    void readSettings(QSettings& settings);
    void writeSettings(QSettings& settings);

    QString winTitleBase_;
    QString messageType_;
    QString appName_;
    QString settingsName_;

    Type type_;

    MvMessageMetaData* data_{nullptr};
    int currentMessageNo_{-1};

    QString sourceFileName_;

    MvQMainWindow::MenuItemMap menuItems_;

    QComboBox* keyCombo_{nullptr};
    MvQKeyManager* keyManager_{nullptr};
    QString savedKeyProfileName_;

    // Main layout components
    QSplitter* centralSplitter_{nullptr};
    QSplitter* mainSplitter_{nullptr};
    MvQFileInfoLabel* fileInfoLabel_{nullptr};
    QLabel* statusMessageLabel_{nullptr};

    // File panel
    MvQFileListWidget* filePanel_{nullptr};
    QAction* actionFilePanel_{nullptr};
    QAction* actionAddFile_{nullptr};
    MvQFileList* fileList_{nullptr};

    QList<MvKeyProfile*> allKeys_;
    qint64 fileSize_{0};

    QAction* actionFileInfo_{nullptr};
    MvQLogPanel* logPanel_{nullptr};

#ifdef ECCODES_UI
    QActionGroup* styleAg_{nullptr};
#endif

private:
    QAction* actionLog_{nullptr};
};
