/***************************** 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 <QStringList>

#include "MvQAbstractMessageExaminer.h"

class QAbstractButton;
class QButtonGroup;
class QComboBox;
class QLabel;
class QLineEdit;
class QSpinBox;
class QSplitter;
class QStackedWidget;
class QTabWidget;
class QTextBrowser;
class QTextEdit;
class QTreeView;

class MvQGribMvDumpModel;
class MvQGribWmoDumpModel;
class MvQGribStdDumpModel;
class MvQGribValueDumpModel;
class MvQGribArrayDumpModel;
class MvQGribPlDumpModel;
class MvQGribPvDumpModel;
class MvQTextEditSearchLine;
class MvQTreeExpandState;
class MvQTreeView;
class MvQTreeViewSearchLine;
class GribMetaData;
class MessageLabel;
class PlainTextWidget;

class MvQGribDumpPanel : public QWidget
{
    Q_OBJECT
public:
    MvQGribDumpPanel(QWidget* parent = nullptr);
    ~MvQGribDumpPanel() override;

    void init(GribMetaData* data);
    void loadDumps(int msgCnt);

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

protected slots:
    void slotCurrentDumpChanged(int);
    void slotSetGribNameSpace(const QString&);
    void slotValueRowSpinChanged(int);
    void slotSelectValueRow(const QModelIndex&);
    void slotMvDumpFilter(QString txt);
    void slotStdGroupClicked(QAbstractButton*);
    void slotWmoGroupClicked(QAbstractButton*);
    void slotPvGroupClicked(QAbstractButton*);
    void slotCopyDumpKey();

private:
    void addCopyToClipboardAction(QTreeView*, QString);

    void loadMvDump();
    void loadWmoDump();
    void loadStdDump();
    void loadTableDump();
    void loadValueDump();
    void loadPlDump();
    void loadPvDump();

    void clearDumps();
    void clearMvDump();
    void clearWmoDump();
    void clearStdDump();
    void clearTableDump();
    void clearValueDump();
    void clearPlDump();
    void clearPvDump();

    enum DumpTabIndex
    {
        NamespaceTabIndex = 0,
        StdTabIndex = 1,
        WmoTabIndex = 2,
        TableTabIndex = 3,
        ValueTabIndex = 4,
        PlTabIndex = 5,
        PvTabIndex = 6
    };

    int currentMsg_;  // starts at 0

    GribMetaData* data_;
    bool messageCanBeDecoded_{true};

    QTabWidget* dumpTab_;

    QComboBox* nsCombo_;
    QStringList gribNameSpace_;

    QWidget* mvDumpFilterHolder_;
    QLineEdit* mvDumpFilter_;
    MvQTreeView* mvDumpTree_;
    MvQGribMvDumpModel* mvDumpModel_;
    QSortFilterProxyModel* mvDumpSortModel_;
    bool mvDumpLoaded_{false};

    QStackedWidget* stdDumpStacked_;
    QButtonGroup* stdGroup_;
    MvQTreeView* stdDumpTree_;
    MvQGribStdDumpModel* stdDumpModel_;
    PlainTextWidget* stdDumpBrowser_;
    bool stdDumpLoaded_{false};
    MvQTreeExpandState* stdExpand_;

    QStackedWidget* wmoDumpStacked_;
    QButtonGroup* wmoGroup_;
    MvQTreeView* wmoDumpTree_;
    MvQGribWmoDumpModel* wmoDumpModel_;
    PlainTextWidget* wmoDumpBrowser_;
    bool wmoDumpLoaded_{false};
    MvQTreeExpandState* wmoExpand_;

    QTextEdit* tableTe_;
    bool tableDumpLoaded_{false};

    QLabel* valueRowLabel_;
    QSpinBox* valueRowSpin_;
    QLabel* valueDumpLabel_;
    MessageLabel* valueDumpMessageLabel_;
    MvQTreeView* valueDumpTree_;
    MvQGribValueDumpModel* valueDumpModel_;
    QSortFilterProxyModel* valueDumpSortModel_;
    bool valueDumpLoaded_{false};

//    QStackedWidget* plStacked_{nullptr};
//    QButtonGroup* plGroup_{nullptr};
    MvQTreeView* plTree_{nullptr};
    MvQGribPlDumpModel* plModel_{nullptr};
    QLabel* plInfoLabel_{nullptr};
    bool plDumpLoaded_{false};

    QStackedWidget* pvStacked_{nullptr};
    QButtonGroup* pvGroup_{nullptr};
    MvQTreeView* pvRawTree_{nullptr};
    MvQGribArrayDumpModel* pvRawModel_{nullptr};
    MvQTreeView* pvTree_{nullptr};
    MvQGribPvDumpModel* pvModel_{nullptr};
    QLabel* pvInfoLabel_{nullptr};
    bool pvDumpLoaded_{false};

    bool ignoreValueRowSpinChangeSignal_{false};
    bool fileInfoLabelNeedsUpdating_{true};

    std::map<QString, QTreeView*> trees_;
};

class MvQGribMainPanel : public QWidget
{
    Q_OBJECT
public:
    MvQGribMainPanel(QWidget* parent);
    void init(GribMetaData*);
    void clear();
    MvKeyProfile* keyProfile() const;
    void loadKeyProfile(MvKeyProfile* prof);
    void reloadData();

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

protected slots:
    void messageSelected(int);
    void messageChangedInGoto(int value);

signals:
    void newMessageSelected(int);
    void keyProfileChanged();
    void messageNumDetermined();

private:
    GribMetaData* data_;
    MvQMessagePanel* messagePanel_;
    MvQGribDumpPanel* dumpPanel_;
    MessageControlPanel* gotoPanel_;
    QSplitter* dataSplitter_;
};

class GribExaminer : public MvQAbstractMessageExaminer
{
    Q_OBJECT

public:
    GribExaminer(QWidget* parent = nullptr);
    ~GribExaminer() override;

protected slots:
    void slotShowAboutBox() override;
    void slotLoadFile(QString) override;
    void updateFileInfoLabel() override;

protected:
    MvKeyProfile* loadedKeyProfile() const override;

private:
    void initMain(MvMessageMetaData* data) override;
    void initDumps() override;
    void initAllKeys() override;

    void loadKeyProfile(MvKeyProfile*) override;

    void settatusMessage(QString);

    void writeSettings();
    void readSettings();

    QString lastKeyProfileName_;
    MvQGribMainPanel* mainPanel_;
    bool fileInfoLabelNeedsUpdating_;
    std::string tmpfilename_;
};
