#ifndef _LoggingPanel_h__
#define _LoggingPanel_h__

#include <QDoubleSpinBox>
#include <QGroupBox>
#include <QLabel>
#include <QMap>
#include <QTextEdit>
#include <QVector>
#include <QWidget>

#include "ConfigComboBox.h"
#include "ConfigLineEdit.h"
#include "DataSourceCheckBox.h"
#include "LoggingThread.h"
#include "TDevice.h"
#include "TextViewer.h"

class LoggingPanel : public QWidget {

    Q_OBJECT

  public:
    // Singleton instance
    static LoggingPanel &instance() {
        static LoggingPanel instance;
        return instance;
    }

    // Disable copy constructor and assignment operator
    // Required to enforce singleton pattern
    LoggingPanel(LoggingPanel const &) = delete;
    void operator=(LoggingPanel const &) = delete;

    virtual ~LoggingPanel();

    bool isRunning();

  signals:

    void loggingStatusChanged(bool running);

  public slots:

    void addDevice(const TDevice *device);
    void removeDevice(const TDevice *device);
    void stopLogging();

  private:
    LoggingPanel();

    void setAllSelected(bool selected);
    void setIntervalMultiple(int m);
    void updateIntervalSpinBox();
    void showError(const QString &message, const QString &hint);
    void addMessage(const QString &message);

    LoggingThread *thread = nullptr;

    QMap<QString, QVector<DataSourceCheckBox *> *> checkBoxesByDevice;

    QGroupBox *leftColumn;
    QGroupBox *settingsBox;
    QGroupBox *outputPathBox;
    QVBoxLayout *channelsLayout;
    QVBoxLayout *mathChannelsLayout;
    QDoubleSpinBox *intervalSpinBox;
    QLabel *statusLabel;
    QLabel *counterLabel;
    QTextEdit *messageTextEdit;

    QPushButton *startButton;
    QPushButton *stopButton;
    ConfigLineEdit *outputPathLineEdit;
    ConfigComboBox *existingFileComboBox;
    ConfigLineEdit *commentLineEdit;
    TextViewer *logViewer = nullptr;

    int globalInterval;
    int interval;
    int intervalMultiple;

  private slots:

    void selectAll();
    void selectNone();
    void browseOutputFile();
    void setGlobalInterval(int ms);
    void onIntervalSelected(double s);
    void showLogViewer();
    void onLogViewerFinished(int result);
    void clearMessages();
    void saveMessages();
    void startLogging();

    void onThreadError(int error);
    void onThreadWrite(qulonglong n);
    void onThreadFinished();
};

#endif