/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Data Visualization module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtDataVisualization/q3dbars.h>
#include <QtDataVisualization/q3dsurface.h>
#include <QtDataVisualization/qcategory3daxis.h>
#include <QtDataVisualization/qitemmodelbardataproxy.h>
#include <QtDataVisualization/qitemmodelsurfacedataproxy.h>
#include <QtDataVisualization/qvalue3daxis.h>
#include <QtDataVisualization/q3dscene.h>
#include <QtDataVisualization/q3dcamera.h>
#include <QtDataVisualization/qbar3dseries.h>
#include <QtDataVisualization/q3dtheme.h>

#include <QtWidgets/QApplication>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QTableWidget>
#include <QtGui/QScreen>
#include <QtCore/QTimer>
#include <QtCore/QRandomGenerator>
#include <QtCore/QDebug>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QPushButton>

#define USE_STATIC_DATA

using namespace QtDataVisualization;

class GraphDataGenerator : public QObject
{
public:
    explicit GraphDataGenerator(Q3DBars *bargraph, Q3DSurface * surfaceGraph,
                                QTableWidget *tableWidget);
    ~GraphDataGenerator();

    void setupModel();
    void addRow();
    void start();
    void selectFromTable(const QPoint &selection);
    void selectedFromTable(int currentRow, int currentColumn, int previousRow, int previousColumn);
    void fixTableSize();
    void changeSelectedButtonClicked();

private:
    Q3DBars *m_barGraph;
    Q3DSurface *m_surfaceGraph;
    QTimer *m_dataTimer;
    QTimer *m_styleTimer;
    QTimer *m_presetTimer;
    QTimer *m_themeTimer;
    int m_columnCount;
    int m_rowCount;
    QTableWidget *m_tableWidget; // not owned
};

GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, Q3DSurface * surfaceGraph,
                                       QTableWidget *tableWidget)
    : m_barGraph(bargraph),
      m_surfaceGraph(surfaceGraph),
      m_dataTimer(0),
      m_styleTimer(0),
      m_presetTimer(0),
      m_themeTimer(0),
      m_columnCount(100),
      m_rowCount(50),
      m_tableWidget(tableWidget)
{
    // Set up bar specifications; make the bars as wide as they are deep,
    // and add a small space between them
    m_barGraph->setBarThickness(1.0f);
    m_barGraph->setBarSpacing(QSizeF(0.2, 0.2));

#ifndef USE_STATIC_DATA
    // Set up sample space; make it as deep as it's wide
    m_barGraph->rowAxis()->setRange(0, m_rowCount);
    m_barGraph->columnAxis()->setRange(0, m_columnCount);
    m_tableWidget->setColumnCount(m_columnCount);

    // Set selection mode to full
    m_barGraph->setSelectionMode(QAbstract3DGraph::SelectionItemRowAndColumn);

    // Hide axis labels by explicitly setting one empty string as label list
    m_barGraph->rowAxis()->setLabels(QStringList(QString()));
    m_barGraph->columnAxis()->setLabels(QStringList(QString()));

    m_barGraph->seriesList().at(0)->setItemLabelFormat(QStringLiteral("@valueLabel"));
#else
    // Set selection mode to slice row
    m_barGraph->setSelectionMode(
                QAbstract3DGraph::SelectionItemAndRow | QAbstract3DGraph::SelectionSlice);
    m_surfaceGraph->setSelectionMode(
                QAbstract3DGraph::SelectionItemAndRow | QAbstract3DGraph::SelectionSlice);
#endif
}

GraphDataGenerator::~GraphDataGenerator()
{
    if (m_dataTimer) {
        m_dataTimer->stop();
        delete m_dataTimer;
    }
    delete m_barGraph;
    delete m_surfaceGraph;
}

void GraphDataGenerator::start()
{
#ifndef USE_STATIC_DATA
    m_dataTimer = new QTimer();
    m_dataTimer->setTimerType(Qt::CoarseTimer);
    QObject::connect(m_dataTimer, &QTimer::timeout, this, &GraphDataGenerator::addRow);
    m_dataTimer->start(0);
    m_tableWidget->setFixedWidth(m_graph->width());
#else
    setupModel();

    // Table needs to be shown before the size of its headers can be accurately obtained,
    // so we postpone it a bit
    m_dataTimer = new QTimer();
    m_dataTimer->setSingleShot(true);
    QObject::connect(m_dataTimer, &QTimer::timeout, this, &GraphDataGenerator::fixTableSize);
    m_dataTimer->start(0);
#endif
}

void GraphDataGenerator::setupModel()
{
    // Set up row and column names
    QStringList days;
    days << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday" << "Saturday" << "Sunday";
    QStringList weeks;
    weeks << "week 1" << "week 2" << "week 3" << "week 4" << "week 5";

    // Set up data
    const char *hours[5][7] =
    //    Mon            Tue            Wed            Thu            Fri            Sat            Sun
        {{"9/10/2.0/30", "9/11/1.0/30", "9/12/3.0/30", "9/13/0.2/30", "9/14/1.0/30", "9/15/5.0/30", "9/16/10.0/30"},     // week 1
         {"8/10/0.5/45", "8/11/1.0/45", "8/12/3.0/45", "8/13/1.0/45", "8/14/2.0/45", "8/15/2.0/45", "8/16/3.0/45"},      // week 2
         {"7/10/1.0/60", "7/11/1.0/60", "7/12/2.0/60", "7/13/1.0/60", "7/14/4.0/60", "7/15/4.0/60", "7/16/4.0/60"},      // week 3
         {"6/10/0.0/75", "6/11/1.0/75", "6/12/0.0/75", "6/13/0.0/75", "6/14/2.0/75", "6/15/2.0/75", "6/16/0.3/75"},      // week 4
         {"5/10/3.0/90", "5/11/3.0/90", "5/12/6.0/90", "5/13/2.0/90", "5/14/2.0/90", "5/15/1.0/90", "5/16/1.0/90"}};     // week 5

    // Add labels
    m_barGraph->rowAxis()->setTitle("Week of year");
    m_barGraph->columnAxis()->setTitle("Day of week");
    m_barGraph->valueAxis()->setTitle("Hours spent on the Internet");
    m_barGraph->valueAxis()->setLabelFormat("%.1f h");

    m_surfaceGraph->axisZ()->setTitle("Week of year");
    m_surfaceGraph->axisX()->setTitle("Day of week");
    m_surfaceGraph->axisY()->setTitle("Hours spent on the Internet");
    m_surfaceGraph->axisY()->setLabelFormat("%.1f h");

    m_tableWidget->setRowCount(5);
    m_tableWidget->setColumnCount(7);
    m_tableWidget->setHorizontalHeaderLabels(days);
    m_tableWidget->setVerticalHeaderLabels(weeks);
    m_tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_tableWidget->setCurrentCell(-1, -1);

    for (int week = 0; week < weeks.size(); week++) {
        for (int day = 0; day < days.size(); day++) {
            QModelIndex index = m_tableWidget->model()->index(week, day);
            m_tableWidget->model()->setData(index, hours[week][day]);
        }
    }
}

void GraphDataGenerator::addRow()
{
    m_tableWidget->model()->insertRow(0);
    if (m_tableWidget->model()->rowCount() > m_rowCount)
        m_tableWidget->model()->removeRow(m_rowCount);
    for (int i = 0; i < m_columnCount; i++) {
        QModelIndex index = m_tableWidget->model()->index(0, i);
        m_tableWidget->model()->setData(index,
                                        ((float)i / (float)m_columnCount) / 2.0f
                                        + QRandomGenerator::global()->bounded(30.0 / 100.0f));
    }
    m_tableWidget->resizeColumnsToContents();
}

void GraphDataGenerator::selectFromTable(const QPoint &selection)
{
    m_tableWidget->setFocus();
    m_tableWidget->setCurrentCell(selection.x(), selection.y());
}

void GraphDataGenerator::selectedFromTable(int currentRow, int currentColumn,
                                           int previousRow, int previousColumn)
{
    Q_UNUSED(previousRow)
    Q_UNUSED(previousColumn)
    m_barGraph->seriesList().at(0)->setSelectedBar(QPoint(currentRow, currentColumn));
    m_surfaceGraph->seriesList().at(0)->setSelectedPoint(QPoint(currentRow, currentColumn));
}

void GraphDataGenerator::fixTableSize()
{
    int width = m_tableWidget->horizontalHeader()->length();
    width += m_tableWidget->verticalHeader()->width();
    m_tableWidget->setFixedWidth(width + 2);
    int height = m_tableWidget->verticalHeader()->length();
    height += m_tableWidget->horizontalHeader()->height();
    m_tableWidget->setFixedHeight(height + 2);
}

void GraphDataGenerator::changeSelectedButtonClicked()
{
    // Change all selected cells to a random value 1-10
    QVariant value = QVariant::fromValue(QRandomGenerator::global()->bounded(10.0) + 1);
    QList<QTableWidgetItem *> selectedItems = m_tableWidget->selectedItems();
    foreach (QTableWidgetItem *item, selectedItems) {
        QString oldData = item->data(Qt::DisplayRole).toString();
        item->setData(Qt::DisplayRole,
                      oldData.left(5)
                      .append(QString::number(value.toReal()))
                      .append("/")
                      .append(QString::number(value.toReal() * 10)));
    }
}

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    Q3DBars *barGraph = new Q3DBars();
    Q3DSurface *surfaceGraph = new Q3DSurface();
    QWidget *barContainer = QWidget::createWindowContainer(barGraph);
    QWidget *surfaceContainer = QWidget::createWindowContainer(surfaceGraph);

    barContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    barContainer->setFocusPolicy(Qt::StrongFocus);
    surfaceContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    surfaceContainer->setFocusPolicy(Qt::StrongFocus);

    QWidget widget;
    QVBoxLayout *mainLayout = new QVBoxLayout(&widget);
    QHBoxLayout *graphLayout = new QHBoxLayout();
    QVBoxLayout *buttonLayout = new QVBoxLayout();
    QHBoxLayout *bottomLayout = new QHBoxLayout();
    QTableWidget *tableWidget = new QTableWidget(&widget);
    QPushButton *changeSelectedButton = new QPushButton(&widget);
    changeSelectedButton->setText(QStringLiteral("Change Selected"));

    buttonLayout->addWidget(changeSelectedButton);
    graphLayout->addWidget(barContainer);
    graphLayout->addWidget(surfaceContainer);
    bottomLayout->addLayout(buttonLayout);
    bottomLayout->addWidget(tableWidget);
    mainLayout->addLayout(graphLayout);
    mainLayout->addLayout(bottomLayout);

    tableWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    tableWidget->setAlternatingRowColors(true);
    widget.setWindowTitle(QStringLiteral("Hours spent on the Internet"));

    // Since we are dealing with QTableWidget, the model will already have data sorted properly
    // into rows and columns, so we simply set useModelCategories property to true to utilize this.
    QItemModelBarDataProxy *barProxy = new QItemModelBarDataProxy(tableWidget->model());
    QItemModelSurfaceDataProxy *surfaceProxy = new QItemModelSurfaceDataProxy(tableWidget->model());
    barProxy->setUseModelCategories(true);
    surfaceProxy->setUseModelCategories(true);
    barProxy->setRotationRole(tableWidget->model()->roleNames().value(Qt::DisplayRole));
    barProxy->setValueRolePattern(QRegExp(QStringLiteral("^(\\d*)(\\/)(\\d*)\\/(\\d*[\\.\\,]?\\d*)\\/\\d*[\\.\\,]?\\d*$")));
    barProxy->setRotationRolePattern(QRegExp(QStringLiteral("^(\\d*)(\\/)\\d*\\/\\d*([\\.\\,]?)\\d*(\\/)(\\d*[\\.\\,]?\\d*)$")));
    barProxy->setValueRoleReplace(QStringLiteral("\\4"));
    barProxy->setRotationRoleReplace(QStringLiteral("\\5"));
    surfaceProxy->setXPosRole(tableWidget->model()->roleNames().value(Qt::DisplayRole));
    surfaceProxy->setZPosRole(tableWidget->model()->roleNames().value(Qt::DisplayRole));
    surfaceProxy->setXPosRolePattern(QRegExp(QStringLiteral("^(\\d*)\\/(\\d*)\\/\\d*[\\.\\,]?\\d*\\/\\d*[\\.\\,]?\\d*$")));
    surfaceProxy->setXPosRoleReplace(QStringLiteral("\\2"));
    surfaceProxy->setYPosRolePattern(QRegExp(QStringLiteral("^\\d*(\\/)(\\d*)\\/(\\d*[\\.\\,]?\\d*)\\/\\d*[\\.\\,]?\\d*$")));
    surfaceProxy->setYPosRoleReplace(QStringLiteral("\\3"));
    surfaceProxy->setZPosRolePattern(QRegExp(QStringLiteral("^(\\d*)(\\/)(\\d*)\\/\\d*[\\.\\,]?\\d*\\/\\d*[\\.\\,]?\\d*$")));
    surfaceProxy->setZPosRoleReplace(QStringLiteral("\\1"));
    QBar3DSeries *barSeries = new QBar3DSeries(barProxy);
    QSurface3DSeries *surfaceSeries = new QSurface3DSeries(surfaceProxy);
    barSeries->setMesh(QAbstract3DSeries::MeshPyramid);
    barGraph->addSeries(barSeries);
    surfaceGraph->addSeries(surfaceSeries);

    barGraph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetBehind);
    surfaceGraph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);

    GraphDataGenerator generator(barGraph, surfaceGraph, tableWidget);
    QObject::connect(barSeries, &QBar3DSeries::selectedBarChanged, &generator,
                     &GraphDataGenerator::selectFromTable);
    QObject::connect(surfaceSeries, &QSurface3DSeries::selectedPointChanged, &generator,
                     &GraphDataGenerator::selectFromTable);
    QObject::connect(tableWidget, &QTableWidget::currentCellChanged, &generator,
                     &GraphDataGenerator::selectedFromTable);
    QObject::connect(changeSelectedButton, &QPushButton::clicked, &generator,
                     &GraphDataGenerator::changeSelectedButtonClicked);

    QSize screenSize = barGraph->screen()->size();
    widget.resize(QSize(screenSize.width() / 2, screenSize.height() / 2));
    widget.show();
    generator.start();
    return app.exec();
}
