#include "xlrumultigfxform.h"
#include "ui_xlrumultigfxform.h"

#include <Windows.h>
#include <qlabel.h>
#include <QWidgetAction>
#include <QDockWidget>
#include <QCheckBox>
#include <QStatusBar>
#include <QTableWidget>

#define UPDATE_TIME_DEF     2000

#define MESS_RECORD_START   "Acquisition in progress ..."
#define MESS_RECORD_STOP    "Acquisition paused."

XlruMultiGfxForm::XlruMultiGfxForm(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::XlruMultiGfxForm)
{
    ui->setupUi(this);

    this->resize(800, 600);
    this->show();
    this->setObjectName("GFX");
    this->setWindowTitle("GFX");


#ifdef TELEMETRY
    telemetry = new telemetryClass;
#endif

    report = new XlruReportClass();

    configGraph = XlruChartConfig::instance();

    if (!configGraph->loadSettings())
        return;

    //sensorsTable = new XlruSensorsTableClass();

    count = 0;

    //enabled
    QCheckBox *cbEnabled = new QCheckBox(this);
    cbEnabled->setText("Enabled");
    cbEnabled->setChecked(true);
    cbEnabled->setToolTip("Enabled/Disable acquisition data.");
    QWidgetAction *actEnabled = new QWidgetAction(this);
    actEnabled->setDefaultWidget(cbEnabled);
    ui->mainToolBar->addAction(actEnabled);
    connect(cbEnabled, &QCheckBox::stateChanged, this, [this]()
    {
        QCheckBox* cb = qobject_cast<QCheckBox*> (sender());
        if (cb->isChecked())
        {
            running_monitor = true;
            ui->statusBar->showMessage(MESS_RECORD_START);
        }
        else
        {
            running_monitor = false;
            ui->statusBar->showMessage(MESS_RECORD_STOP);
        }
    });

    ui->mainToolBar->addSeparator();

    //clear
    QAction *actClear = new QAction(this);
    actClear->setObjectName("Clear");
    actClear->setText("Clear");
    actClear->setEnabled(true);
    actClear->setCheckable(false);
    actClear->setChecked(false);
    actClear->setToolTip("Clear all data present in graphs");
    ui->mainToolBar->addAction(actClear);
    connect(actClear, &QAction::triggered, this, [this]()
    {
        foreach (XlruChartClass *ch, list_chart)
        {
            ch->clear();
        }
    });

    //purge
    ui->mainToolBar->addSeparator();
    QAction *actPurge = new QAction(this);
    actPurge->setObjectName("Purge");
    actPurge->setText("Purge");
    actPurge->setEnabled(true);
    actPurge->setCheckable(false);
    actPurge->setChecked(false);
    actPurge->setToolTip(QString("last %1 minutes").arg(PURGE_DEF));
    ui->mainToolBar->addAction(actPurge);
    connect(actPurge, &QAction::triggered, this, [this]()
    {
        foreach (XlruChartClass *ch, list_chart)
        {
            ch->purge();
        }
    });

#ifdef USE_TABLE

    QTableWidget *tableWidget = new QTableWidget(this);

    QDockWidget *dock = new QDockWidget(tr("Value"), this);
    dock->setWidget(tableWidget);
    dock->setAllowedAreas(Qt::LeftDockWidgetArea);
    this->addDockWidget(Qt::LeftDockWidgetArea,dock);

    sensorsTable = new XlruSensorsTableClass(tableWidget);

    //reste table min/max
    ui->mainToolBar->addSeparator();
    QAction *actResetTable = new QAction(this);
    actResetTable->setObjectName("ResetTable");
    actResetTable->setText("Reset min/max");
    actResetTable->setEnabled(true);
    actResetTable->setCheckable(false);
    actResetTable->setChecked(false);
    actResetTable->setToolTip(QString("Reset Min/Max int table"));
    ui->mainToolBar->addAction(actResetTable);
    connect(actResetTable, &QAction::triggered, this, [this]()
    {
        sensorsTable->resetMinMax();
    });

#endif

    //autopurge
    ui->mainToolBar->addSeparator();
    QCheckBox *cbAutopurge = new QCheckBox(this);
    cbAutopurge->setText("autopurge");
    cbAutopurge->setChecked(false);
    cbAutopurge->setTristate(true);
    cbAutopurge->setToolTip(QString("no/%1min/%2min").arg(PURGE_PARTIAL_DEF).arg(PURGE_DEF));
    QWidgetAction *actAutopurge = new QWidgetAction(this);
    actAutopurge->setDefaultWidget(cbAutopurge);
    ui->mainToolBar->addAction(actAutopurge);
    connect(cbAutopurge, &QCheckBox::stateChanged, this, [this]()
    {
        QCheckBox* cb = qobject_cast<QCheckBox*> (sender());
        foreach (XlruChartClass *ch, list_chart)
        {
            ch->autopurge_enabled = cb->checkState();
        }
    });

    //lista controlli

    //limite temperatura
    ui->mainToolBar->addSeparator();
    QCheckBox *cbTempLimit = new QCheckBox(this);
    cbTempLimit->setText("check temp");

    if (configGraph->getRemoveLimit())
        cbTempLimit->setChecked(false);
    else
        cbTempLimit->setChecked(true);

    cbTempLimit->setToolTip("Enabled/Disable check limit for temperature.");
    QWidgetAction *actTempLimit = new QWidgetAction(this);
    actTempLimit->setDefaultWidget(cbTempLimit);
    ui->mainToolBar->addAction(actTempLimit);
    connect(cbTempLimit, &QCheckBox::stateChanged, this, [this]()
    {
        QCheckBox* cb = qobject_cast<QCheckBox*> (sender());

        //abilitare per tutti i sensori di tipo temperatura il controllo del limite
        setCheckLimit(cb->isChecked(), type_s_temperature);
    });

    //limite corrente
    ui->mainToolBar->addSeparator();
    QCheckBox *cbCurrLimit = new QCheckBox(this);
    cbCurrLimit->setText("check curr");

    if (configGraph->getRemoveLimit())
        cbCurrLimit->setChecked(false);
    else
        cbCurrLimit->setChecked(true);

    cbCurrLimit->setToolTip("Enabled/Disable check limit for current.");
    QWidgetAction *actCurrLimit = new QWidgetAction(this);
    actCurrLimit->setDefaultWidget(cbCurrLimit);
    ui->mainToolBar->addAction(actCurrLimit);
    connect(cbCurrLimit, &QCheckBox::stateChanged, this, [this]()
    {
        QCheckBox* cb = qobject_cast<QCheckBox*> (sender());

        //abilitare per tutti i sensori di tipo temperatura il controllo del limite
        setCheckLimit(cb->isChecked(), type_s_current);
    });

    //limite tensione
    ui->mainToolBar->addSeparator();
    QCheckBox *cbVoltLimit = new QCheckBox(this);
    cbVoltLimit->setText("check volt");

    if (configGraph->getRemoveLimit())
        cbVoltLimit->setChecked(false);
    else
        cbVoltLimit->setChecked(true);

    cbVoltLimit->setToolTip("Enabled/Disable check limit for voltage.");
    QWidgetAction *actVoltLimit = new QWidgetAction(this);
    actVoltLimit->setDefaultWidget(cbVoltLimit);
    ui->mainToolBar->addAction(actVoltLimit);
    connect(cbVoltLimit, &QCheckBox::stateChanged, this, [this]()
    {
        QCheckBox* cb = qobject_cast<QCheckBox*> (sender());

        //abilitare per tutti i sensori di tipo temperatura il controllo del limite
        setCheckLimit(cb->isChecked(), type_s_voltage);
        //if (cb->isChecked())

    });

    //lista dei grafici
    ui->mainToolBar->addSeparator();
    QLabel *title_graph = new QLabel(this);
    title_graph->setText("Graphics: ");
    ui->mainToolBar->addWidget(title_graph);

    running_monitor = true;

    ui->statusBar->showMessage(MESS_RECORD_START);
}

XlruMultiGfxForm::~XlruMultiGfxForm()
{
    delete report;
    delete ui;
    delete configGraph;
#ifdef USE_TABLE
    delete sensorsTable;
#endif

#ifdef TELEMETRY
    delete telemetry;
#endif

}

void XlruMultiGfxForm::setUpdatesEnabled(bool _update)
{
    foreach (XlruChartClass* ch, list_chart)
    {
        ch->setUpdatesEnabled(_update);
    }
}

XlruChartClass* XlruMultiGfxForm::newGraphConfig(graph_config_t *gconfig, QStringList list_fpga, bool _main)
{
    XlruChartClass *new_chart = new XlruChartClass(this);

#ifdef USE_TABLE
    new_chart->SensorsTable = sensorsTable;
#endif

    new_chart->report = report;

    new_chart->setTitle(gconfig->name);

    foreach (sensor_config_t *sensorConfig, gconfig->list_sensors_config)
    {
        //controlla se il sensore è di tipo fpga
        if ((sensorConfig->fpga_address!="") && (list_fpga.indexOf(sensorConfig->fpga_address)!=-1))
            new_chart->addSensorFromConfig(sensorConfig);
        else
        {
            if (sensorConfig->fpga_address=="")
                new_chart->addSensorFromConfig(sensorConfig);
        }
    }

    new_chart->connectMarkers();

    new_chart->connectTooltip();

    if (_main)
    {
        this->setCentralWidget(new_chart);
        //this->addDockWidget(Qt::TopDockWidgetArea, dw);
    }
    else
    {
        QDockWidget* dw=new QDockWidget(new_chart->getTitle());
        dw->setObjectName(new_chart->getTitle());
        dw->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
        dw->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Maximum);
        dw->setWidget(new_chart);
        new_chart->dw = dw;
        addTabbedDock(Qt::BottomDockWidgetArea, dw);
        //this->addDockWidget(Qt::BottomDockWidgetArea, dw);

        //creo una nuova action
        QAction *newAction = new QAction(this);
        newAction->setObjectName(gconfig->name);
        newAction->setText(gconfig->name);
        newAction->setEnabled(true);
        newAction->setCheckable(true);
        newAction->setChecked(true);
        newAction->setToolTip(QString("Enabled/disable the %1 graph.").arg(new_chart->getTitle()));

        //collego all'azione la chiusura o apertura del dockwidget collegato
        connect(newAction, &QAction::triggered, this, [this]()
        {
            foreach (XlruChartClass *ch, list_chart)
            {
                QAction* action = qobject_cast<QAction*> (sender());
                if (ch->getTitle()==action->text())
                    ch->dw->setVisible(action->isChecked());
            }
        });

        //la aggiungo alla toolbar
        ui->mainToolBar->addAction(newAction);
    }

    return new_chart;
}


void XlruMultiGfxForm::addSampleAllGraph(QString sensor_name, float value)
{
    foreach (XlruChartClass* ch, list_chart)
    {
        if (!running_monitor)
            return;
        ch->addSample(sensor_name, value);
    }
}

void XlruMultiGfxForm::setCheckLimit(bool _test, type_series_t type_se)
{
    foreach (XlruChartClass* ch, list_chart)
    {
        foreach (Sensor *se, ch->list_sensors)
        {
            if (se->type_serie==type_se)
                se->limitFlag = _test;
        }
    }
}


void XlruMultiGfxForm::timerEvent(QTimerEvent * e)
{
    if (e->timerId()==t_id)
    {
        setUpdatesEnabled(false);
        foreach (XlruChartClass* ch, list_chart)
        {
            ch->timerEvent();
        }

        if (configGraph->getReportEnabled())
            report->saveValue();

        setUpdatesEnabled(true);
    }
}

void XlruMultiGfxForm::startAcquisition()
{
    //if (configGraph->loadSettings())
    {
        //se la configurazione è letta dal file, visualizzo i grafici indicati
        for (int i = 0; i<configGraph->list_graph_config.size(); i++)
        {  
            if (configGraph->checkFpga(i, list_fpga))
            {
                if (i==0)
                    list_chart.append(newGraphConfig(configGraph->list_graph_config[i], list_fpga,  true));    //il primo grafico è il MAIN!!
                else
                    list_chart.append(newGraphConfig(configGraph->list_graph_config[i], list_fpga));
            }
        }

#ifdef TELEMETRY
        foreach (XlruChartClass* ch, list_chart)
        {
            ch->setTelemetry(telemetry);
        }
#endif
    }

    if (configGraph->getReportEnabled())
    {
        report->generateNewFile("COMPLETE");
    }

    t_id = this->startTimer(2000);
}


void XlruMultiGfxForm::setListFpga(QStringList _list_fpga)
{
    list_fpga = _list_fpga;
}

void XlruMultiGfxForm::addTabbedDock(Qt::DockWidgetArea area, QDockWidget *widget)
{
    QList<QDockWidget*> allDockWidgets = findChildren<QDockWidget*>();
    QVector<QDockWidget*> areaDockWidgets;
    for(QDockWidget *w : allDockWidgets) {
        if(dockWidgetArea(w) == area) {
            areaDockWidgets.append(w);
        }
    }

    if(areaDockWidgets.empty()) {
        // no other widgets
        addDockWidget(area, widget);
    } else {
        tabifyDockWidget(areaDockWidgets.last(), widget);
    }

    setTabPosition(area, QTabWidget::North);
}


