/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Charts 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 <QtCharts/QBarCategoryAxis>
#include <QtCharts/QCandlestickSeries>
#include <QtCharts/QCandlestickSet>
#include <QtCharts/QDateTimeAxis>
#include <QtCharts/QHCandlestickModelMapper>
#include <QtCharts/QValueAxis>
#include <QtCore/QDateTime>
#include <QtCore/QDebug>
#include <QtCore/QRandomGenerator>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QDoubleSpinBox>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QTableView>
#include "customtablemodel.h"
#include "mainwidget.h"

QT_CHARTS_USE_NAMESPACE

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent),
      m_chart(new QChart()),
      m_chartView(new QChartView(m_chart, this)),
      m_axisX(nullptr),
      m_axisY(nullptr),
      m_maximumColumnWidth(-1.0),
      m_minimumColumnWidth(5.0),
      m_bodyOutlineVisible(true),
      m_capsVisible(false),
      m_bodyWidth(0.5),
      m_capsWidth(0.5),
      m_customIncreasingColor(false),
      m_customDecreasingColor(false),
      m_hModelMapper(new QHCandlestickModelMapper(this))
{
    m_chartView->setRenderHint(QPainter::Antialiasing, false);

    m_hModelMapper->setModel(new CustomTableModel(this));
    m_hModelMapper->setTimestampColumn(0);
    m_hModelMapper->setOpenColumn(1);
    m_hModelMapper->setHighColumn(2);
    m_hModelMapper->setLowColumn(3);
    m_hModelMapper->setCloseColumn(4);

    QGridLayout *mainLayout = new QGridLayout();
    mainLayout->addLayout(createSeriesControlsLayout(), 0, 0);
    mainLayout->addLayout(createSetsControlsLayout(), 1, 0);
    mainLayout->addLayout(createCandlestickControlsLayout(), 2, 0);
    mainLayout->addLayout(createMiscellaneousControlsLayout(), 3, 0);
    mainLayout->addWidget(m_chartView, 0, 1, mainLayout->rowCount() + 1, 1);
    mainLayout->addLayout(createModelMapperControlsLayout(), 0, 2, mainLayout->rowCount(), 1);
    setLayout(mainLayout);

    addSeries();
}

MainWidget::~MainWidget()
{
}

QGridLayout *MainWidget::createSeriesControlsLayout()
{
    QGridLayout *layout = new QGridLayout();
    int row = 0;

    layout->addWidget(new QLabel(QStringLiteral("Series controls:")), row, 0, Qt::AlignLeft);

    QPushButton *addSeriesButton = new QPushButton(QStringLiteral("Add a series"));
    connect(addSeriesButton, SIGNAL(clicked(bool)), this, SLOT(addSeries()));
    layout->addWidget(addSeriesButton, row++, 1, Qt::AlignLeft);

    QPushButton *removeSeriesButton = new QPushButton(QStringLiteral("Remove a series"));
    connect(removeSeriesButton, SIGNAL(clicked(bool)), this, SLOT(removeSeries()));
    layout->addWidget(removeSeriesButton, row++, 1, Qt::AlignLeft);

    QPushButton *removeAllSeriesButton = new QPushButton(QStringLiteral("Remove all series"));
    connect(removeAllSeriesButton, SIGNAL(clicked(bool)), this, SLOT(removeAllSeries()));
    layout->addWidget(removeAllSeriesButton, row++, 1, Qt::AlignLeft);

    return layout;
}

QGridLayout *MainWidget::createSetsControlsLayout()
{
    QGridLayout *layout = new QGridLayout();
    int row = 0;

    layout->addWidget(new QLabel(QStringLiteral("Sets controls:")), row, 0, Qt::AlignLeft);

    QPushButton *addSetButton = new QPushButton(QStringLiteral("Add a set"));
    connect(addSetButton, SIGNAL(clicked(bool)), this, SLOT(addSet()));
    layout->addWidget(addSetButton, row++, 1, Qt::AlignLeft);

    QPushButton *insertSetButton = new QPushButton(QStringLiteral("Insert a set"));
    connect(insertSetButton, SIGNAL(clicked(bool)), this, SLOT(insertSet()));
    layout->addWidget(insertSetButton, row++, 1, Qt::AlignLeft);

    QPushButton *removeSetButton = new QPushButton(QStringLiteral("Remove a set"));
    connect(removeSetButton, SIGNAL(clicked(bool)), this, SLOT(removeSet()));
    layout->addWidget(removeSetButton, row++, 1, Qt::AlignLeft);

    QPushButton *removeAllSetsButton = new QPushButton(QStringLiteral("Remove all sets"));
    connect(removeAllSetsButton, SIGNAL(clicked(bool)), this, SLOT(removeAllSets()));
    layout->addWidget(removeAllSetsButton, row++, 1, Qt::AlignLeft);

    return layout;
}

QGridLayout *MainWidget::createCandlestickControlsLayout()
{
    QGridLayout *layout = new QGridLayout();
    int row = 0;

    layout->addWidget(new QLabel(QStringLiteral("Maximum column width:")), row, 0, Qt::AlignLeft);
    QDoubleSpinBox *maximumColumnWidthSpinBox = new QDoubleSpinBox();
    maximumColumnWidthSpinBox->setRange(-1.0, 1024.0);
    maximumColumnWidthSpinBox->setDecimals(0);
    maximumColumnWidthSpinBox->setValue(m_maximumColumnWidth);
    maximumColumnWidthSpinBox->setSingleStep(1.0);
    connect(maximumColumnWidthSpinBox, SIGNAL(valueChanged(double)),
            this, SLOT(changeMaximumColumnWidth(double)));
    layout->addWidget(maximumColumnWidthSpinBox, row++, 1, Qt::AlignLeft);

    layout->addWidget(new QLabel(QStringLiteral("Minimum column width:")), row, 0, Qt::AlignLeft);
    QDoubleSpinBox *minimumColumnWidthSpinBox = new QDoubleSpinBox();
    minimumColumnWidthSpinBox->setRange(-1.0, 1024.0);
    minimumColumnWidthSpinBox->setDecimals(0);
    minimumColumnWidthSpinBox->setValue(m_minimumColumnWidth);
    minimumColumnWidthSpinBox->setSingleStep(1.0);
    connect(minimumColumnWidthSpinBox, SIGNAL(valueChanged(double)),
            this, SLOT(changeMinimumColumnWidth(double)));
    layout->addWidget(minimumColumnWidthSpinBox, row++, 1, Qt::AlignLeft);

    QCheckBox *bodyOutlineVisible = new QCheckBox(QStringLiteral("Body outline visible"));
    connect(bodyOutlineVisible, SIGNAL(toggled(bool)), this, SLOT(bodyOutlineVisibleToggled(bool)));
    bodyOutlineVisible->setChecked(m_bodyOutlineVisible);
    layout->addWidget(bodyOutlineVisible, row++, 0, Qt::AlignLeft);

    QCheckBox *capsVisible = new QCheckBox(QStringLiteral("Caps visible"));
    connect(capsVisible, SIGNAL(toggled(bool)), this, SLOT(capsVisibleToggled(bool)));
    capsVisible->setChecked(m_capsVisible);
    layout->addWidget(capsVisible, row++, 0, Qt::AlignLeft);

    layout->addWidget(new QLabel(QStringLiteral("Candlestick body width:")), row, 0, Qt::AlignLeft);
    QDoubleSpinBox *bodyWidthSpinBox = new QDoubleSpinBox();
    bodyWidthSpinBox->setRange(-1.0, 2.0);
    bodyWidthSpinBox->setValue(m_bodyWidth);
    bodyWidthSpinBox->setSingleStep(0.1);
    connect(bodyWidthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeBodyWidth(double)));
    layout->addWidget(bodyWidthSpinBox, row++, 1, Qt::AlignLeft);

    layout->addWidget(new QLabel(QStringLiteral("Candlestick caps width:")), row, 0, Qt::AlignLeft);
    QDoubleSpinBox *capsWidthSpinBox = new QDoubleSpinBox();
    capsWidthSpinBox->setRange(-1.0, 2.0);
    capsWidthSpinBox->setValue(m_capsWidth);
    capsWidthSpinBox->setSingleStep(0.1);
    connect(capsWidthSpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeCapsWidth(double)));
    layout->addWidget(capsWidthSpinBox, row++, 1, Qt::AlignLeft);

    QCheckBox *increasingColor = new QCheckBox(QStringLiteral("Custom increasing color (only S1)"));
    connect(increasingColor, SIGNAL(toggled(bool)), this, SLOT(customIncreasingColorToggled(bool)));
    increasingColor->setChecked(m_customIncreasingColor);
    layout->addWidget(increasingColor, row++, 0, 1, 2, Qt::AlignLeft);

    QCheckBox *decreasingColor = new QCheckBox(QStringLiteral("Custom decreasing color (only S1)"));
    connect(decreasingColor, SIGNAL(toggled(bool)), this, SLOT(customDecreasingColorToggled(bool)));
    decreasingColor->setChecked(m_customDecreasingColor);
    layout->addWidget(decreasingColor, row++, 0, 1, 2, Qt::AlignLeft);

    return layout;
}

QGridLayout *MainWidget::createMiscellaneousControlsLayout()
{
    QGridLayout *layout = new QGridLayout();
    int row = 0;

    layout->addWidget(new QLabel(QStringLiteral("Miscellaneous:")), row, 0, Qt::AlignLeft);

    QCheckBox *antialiasingCheckBox = new QCheckBox(QStringLiteral("Antialiasing"));
    connect(antialiasingCheckBox, SIGNAL(toggled(bool)), this, SLOT(antialiasingToggled(bool)));
    antialiasingCheckBox->setChecked(false);
    layout->addWidget(antialiasingCheckBox, row++, 1, Qt::AlignLeft);

    QCheckBox *animationCheckBox = new QCheckBox(QStringLiteral("Animation"));
    connect(animationCheckBox, SIGNAL(toggled(bool)), this, SLOT(animationToggled(bool)));
    animationCheckBox->setChecked(false);
    layout->addWidget(animationCheckBox, row++, 1, Qt::AlignLeft);

    QCheckBox *legendCheckBox = new QCheckBox(QStringLiteral("Legend"));
    connect(legendCheckBox, SIGNAL(toggled(bool)), this, SLOT(legendToggled(bool)));
    legendCheckBox->setChecked(true);
    layout->addWidget(legendCheckBox, row++, 1, Qt::AlignLeft);

    QCheckBox *titleCheckBox = new QCheckBox(QStringLiteral("Title"));
    connect(titleCheckBox, SIGNAL(toggled(bool)), this, SLOT(titleToggled(bool)));
    titleCheckBox->setChecked(true);
    layout->addWidget(titleCheckBox, row++, 1, Qt::AlignLeft);

    layout->addWidget(new QLabel(QStringLiteral("Chart theme:")), row, 0, Qt::AlignLeft);
    QComboBox *chartThemeComboBox = new QComboBox();
    chartThemeComboBox->addItem(QStringLiteral("Light"));
    chartThemeComboBox->addItem(QStringLiteral("Blue Cerulean"));
    chartThemeComboBox->addItem(QStringLiteral("Dark"));
    chartThemeComboBox->addItem(QStringLiteral("Brown Sand"));
    chartThemeComboBox->addItem(QStringLiteral("Blue Ncs"));
    chartThemeComboBox->addItem(QStringLiteral("High Contrast"));
    chartThemeComboBox->addItem(QStringLiteral("Blue Icy"));
    chartThemeComboBox->addItem(QStringLiteral("Qt"));
    connect(chartThemeComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(changeChartTheme(int)));
    layout->addWidget(chartThemeComboBox, row++, 1, Qt::AlignLeft);

    layout->addWidget(new QLabel(QStringLiteral("Axis X:")), row, 0, Qt::AlignLeft);
    QComboBox *axisXComboBox = new QComboBox();
    axisXComboBox->addItem(QStringLiteral("BarCategory"));
    axisXComboBox->addItem(QStringLiteral("DateTime"));
    axisXComboBox->addItem(QStringLiteral("Value"));
    connect(axisXComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(changeAxisX(int)));
    layout->addWidget(axisXComboBox, row++, 1, Qt::AlignLeft);

    return layout;
}

QGridLayout *MainWidget::createModelMapperControlsLayout()
{
    QGridLayout *layout = new QGridLayout();
    int row = 0;

    layout->addWidget(new QLabel(QStringLiteral("First series:")), row, 0, Qt::AlignLeft);

    QPushButton *attachModelMapperButton = new QPushButton(QStringLiteral("Attach model mapper"));
    connect(attachModelMapperButton, SIGNAL(clicked(bool)), this, SLOT(attachModelMapper()));
    layout->addWidget(attachModelMapperButton, row++, 1, Qt::AlignLeft);

    QPushButton *detachModelMappeButton = new QPushButton(QStringLiteral("Detach model mapper"));
    connect(detachModelMappeButton, SIGNAL(clicked(bool)), this, SLOT(detachModelMapper()));
    layout->addWidget(detachModelMappeButton, row++, 1, Qt::AlignLeft);

    QTableView *tableView = new QTableView();
    tableView->setMinimumSize(320, 480);
    tableView->setMaximumSize(320, 480);
    tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    tableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    Q_ASSERT_X(m_hModelMapper->model(), Q_FUNC_INFO, "Model is not initialized");
    tableView->setModel(m_hModelMapper->model());
    layout->addWidget(tableView, row++, 0, 1, 2, Qt::AlignLeft);

    layout->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding), row++, 0);

    return layout;
}

qreal MainWidget::randomValue(int min, int max) const
{
    if (min > max)
        qSwap(min, max);
    return QRandomGenerator::global()->bounded(min, max);
}

QCandlestickSet *MainWidget::randomSet(qreal timestamp)
{
    QCandlestickSet *set = new QCandlestickSet(timestamp);
    set->setOpen(randomValue(4, 11));
    set->setHigh(randomValue(12, 15));
    set->setLow(randomValue(0, 3));
    set->setClose(randomValue(4, 11));

    return set;
}

void MainWidget::updateAxes()
{
    if (m_chart->axes().isEmpty())
        m_chart->createDefaultAxes();

    QCandlestickSeries *series;
    if (!m_chart->series().isEmpty())
        series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
    else
        series = nullptr;

    m_axisX = m_chart->axes(Qt::Horizontal).first();
    if (series && !series->sets().isEmpty()) {
        if (m_axisX->type() == QAbstractAxis::AxisTypeBarCategory) {
            QBarCategoryAxis *axisX = qobject_cast<QBarCategoryAxis *>(m_axisX);
            QStringList categories;
            for (int i = 0; i < series->sets().count(); ++i)
                categories.append(QString::number(i));
            axisX->setCategories(categories);
        } else { // QAbstractAxis::AxisTypeDateTime || QAbstractAxis::AxisTypeValue
            qreal msInMonth = 31.0 * 24.0 * 60.0 * 60.0 * 1000.0;
            qreal min = series->sets().first()->timestamp() - msInMonth;
            qreal max = series->sets().last()->timestamp() + msInMonth;
            QDateTime minDateTime = QDateTime::fromMSecsSinceEpoch(min);
            QDateTime maxDateTime = QDateTime::fromMSecsSinceEpoch(max);

            if (m_axisX->type() == QAbstractAxis::AxisTypeDateTime)
                m_axisX->setRange(minDateTime, maxDateTime);
            else
                m_axisX->setRange(min, max);
        }
    }

    m_axisY = m_chart->axes(Qt::Vertical).first();
    m_axisY->setMax(15);
    m_axisY->setMin(0);
}

void MainWidget::addSeries()
{
    if (m_chart->series().count() > 9) {
        qDebug() << "Maximum series count is 10";
        return;
    }

    QCandlestickSeries *series = new QCandlestickSeries();
    series->setName(QStringLiteral("S%1").arg(m_chart->series().count() + 1));
    series->setMaximumColumnWidth(m_maximumColumnWidth);
    series->setMinimumColumnWidth(m_minimumColumnWidth);
    series->setBodyOutlineVisible(m_bodyOutlineVisible);
    series->setBodyWidth(m_bodyWidth);
    series->setCapsVisible(m_capsVisible);
    series->setCapsWidth(m_capsWidth);

    if (m_chart->series().isEmpty()) {
        if (m_customIncreasingColor)
            series->setIncreasingColor(QColor(Qt::green));
        if (m_customDecreasingColor)
            series->setDecreasingColor(QColor(Qt::red));

        for (int month = 1; month <= 12; ++month) {
            QDateTime dateTime;
            dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), month, 1));
            dateTime.setTime(QTime(12, 34, 56, 789));

            QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
            series->append(set);
        }
    } else {
        QCandlestickSeries *s = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
        for (int i = 0; i < s->sets().count(); ++i) {
            QCandlestickSet *set = randomSet(s->sets().at(i)->timestamp());
            series->append(set);
        }
    }

    m_chart->addSeries(series);

    updateAxes();
    if (!series->attachedAxes().contains(m_axisX))
        series->attachAxis(m_axisX);
    if (!series->attachedAxes().contains(m_axisY))
        series->attachAxis(m_axisY);
}

void MainWidget::removeSeries()
{
    if (m_chart->series().isEmpty()) {
        qDebug() << "Create a series first";
        return;
    }

    if (m_chart->series().count() == 1)
        detachModelMapper();

    QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().last());
    m_chart->removeSeries(series);
    delete series;
    series = nullptr;
}

void MainWidget::removeAllSeries()
{
    if (m_chart->series().isEmpty()) {
        qDebug() << "Create a series first";
        return;
    }

    detachModelMapper();

    m_chart->removeAllSeries();
}

void MainWidget::addSet()
{
    if (m_chart->series().isEmpty()) {
        qDebug() << "Create a series first";
        return;
    }

    foreach (QAbstractSeries *s, m_chart->series()) {
        QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);

        QDateTime dateTime;
        if (series->count()) {
            dateTime.setMSecsSinceEpoch(series->sets().last()->timestamp());
            dateTime = dateTime.addMonths(1);
        } else {
            dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), 1, 1));
            dateTime.setTime(QTime(12, 34, 56, 789));
        }

        QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
        series->append(set);
    }

    updateAxes();
}

void MainWidget::insertSet()
{
    if (m_chart->series().isEmpty()) {
        qDebug() << "Create a series first";
        return;
    }

    foreach (QAbstractSeries *s, m_chart->series()) {
        QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);

        QDateTime dateTime;
        if (series->count()) {
            dateTime.setMSecsSinceEpoch(series->sets().first()->timestamp());
            dateTime = dateTime.addMonths(-1);
        } else {
            dateTime.setDate(QDate(QDateTime::currentDateTime().date().year(), 1, 1));
            dateTime.setTime(QTime(12, 34, 56, 789));
        }

        QCandlestickSet *set = randomSet(dateTime.toMSecsSinceEpoch());
        series->insert(0, set);
    }

    updateAxes();
}

void MainWidget::removeSet()
{
    if (m_chart->series().isEmpty()) {
        qDebug() << "Create a series first";
        return;
    }

    foreach (QAbstractSeries *s, m_chart->series()) {
        QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
        if (series->sets().isEmpty())
            qDebug() << "Create a set first";
        else
            series->remove(series->sets().last());
    }

    updateAxes();
}

void MainWidget::removeAllSets()
{
    if (m_chart->series().isEmpty()) {
        qDebug() << "Create a series first";
        return;
    }

    foreach (QAbstractSeries *s, m_chart->series()) {
        QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
        if (series->sets().isEmpty())
            qDebug() << "Create a set first";
        else
            series->clear();
    }

    updateAxes();
}

void MainWidget::changeMaximumColumnWidth(double width)
{
    m_maximumColumnWidth = width;
    foreach (QAbstractSeries *s, m_chart->series()) {
        QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
        series->setMaximumColumnWidth(m_maximumColumnWidth);
    }
}

void MainWidget::changeMinimumColumnWidth(double width)
{
    m_minimumColumnWidth = width;
    foreach (QAbstractSeries *s, m_chart->series()) {
        QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
        series->setMinimumColumnWidth(m_minimumColumnWidth);
    }
}

void MainWidget::bodyOutlineVisibleToggled(bool visible)
{
    m_bodyOutlineVisible = visible;
    foreach (QAbstractSeries *s, m_chart->series()) {
        QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
        series->setBodyOutlineVisible(m_bodyOutlineVisible);
    }
}

void MainWidget::capsVisibleToggled(bool visible)
{
    m_capsVisible = visible;
    foreach (QAbstractSeries *s, m_chart->series()) {
        QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
        series->setCapsVisible(m_capsVisible);
    }
}

void MainWidget::changeBodyWidth(double width)
{
    m_bodyWidth = width;
    foreach (QAbstractSeries *s, m_chart->series()) {
        QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
        series->setBodyWidth(m_bodyWidth);
    }
}

void MainWidget::changeCapsWidth(double width)
{
    m_capsWidth = width;
    foreach (QAbstractSeries *s, m_chart->series()) {
        QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(s);
        series->setCapsWidth(m_capsWidth);
    }
}

void MainWidget::customIncreasingColorToggled(bool custom)
{
    m_customIncreasingColor = custom;

    if (m_chart->series().isEmpty())
        return;

    QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
    if (series) {
        QColor color = m_customIncreasingColor ? QColor(Qt::green) : QColor();
        series->setIncreasingColor(color);
    }
}

void MainWidget::customDecreasingColorToggled(bool custom)
{
    m_customDecreasingColor = custom;

    if (m_chart->series().isEmpty())
        return;

    QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
    if (series) {
        QColor color = m_customDecreasingColor ? QColor(Qt::red) : QColor();
        series->setDecreasingColor(color);
    }
}

void MainWidget::antialiasingToggled(bool enabled)
{
    m_chartView->setRenderHint(QPainter::Antialiasing, enabled);
}

void MainWidget::animationToggled(bool enabled)
{
    if (enabled)
        m_chart->setAnimationOptions(QChart::SeriesAnimations);
    else
        m_chart->setAnimationOptions(QChart::NoAnimation);
}

void MainWidget::legendToggled(bool visible)
{
    m_chart->legend()->setVisible(visible);
    if (visible)
        m_chart->legend()->setAlignment(Qt::AlignBottom);
}

void MainWidget::titleToggled(bool visible)
{
    if (visible)
        m_chart->setTitle(QStringLiteral("Candlestick Chart"));
    else
        m_chart->setTitle(QString());
}

void MainWidget::changeChartTheme(int themeIndex)
{
    if (themeIndex < QChart::ChartThemeLight || themeIndex > QChart::ChartThemeQt) {
        qDebug() << "Invalid chart theme index:" << themeIndex;
        return;
    }

    m_chart->setTheme((QChart::ChartTheme)(themeIndex));
}

void MainWidget::changeAxisX(int axisXIndex)
{
    if (m_axisX) {
        m_chart->removeAxis(m_axisX);
        delete m_axisX;
    }

    switch (axisXIndex) {
    case 0:
        m_axisX = new QBarCategoryAxis();
        break;
    case 1:
        m_axisX = new QDateTimeAxis();
        break;
    case 2:
        m_axisX = new QValueAxis();
        break;
    default:
        qDebug() << "Invalid axis x index:" << axisXIndex;
        return;
    }

    m_chart->addAxis(m_axisX, Qt::AlignBottom);

    updateAxes();

    foreach (QAbstractSeries *series, m_chart->series())
        series->attachAxis(m_axisX);
}

void MainWidget::attachModelMapper()
{
    if (m_hModelMapper->series()) {
        qDebug() << "Model mapper is already attached";
        return;
    }

    if (m_chart->series().isEmpty())
        addSeries();

    QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_chart->series().at(0));
    Q_ASSERT(series);
    series->setName(QStringLiteral("SWMM")); // Series With Model Mapper

    CustomTableModel *model = qobject_cast<CustomTableModel *>(m_hModelMapper->model());
    foreach (QCandlestickSet *set, series->sets())
        model->addRow(set);

    m_hModelMapper->setFirstSetRow(0);
    m_hModelMapper->setLastSetRow(model->rowCount() - 1);
    m_hModelMapper->setSeries(series);
}

void MainWidget::detachModelMapper()
{
    if (!m_hModelMapper->series())
        return;

    QCandlestickSeries *series = qobject_cast<QCandlestickSeries *>(m_hModelMapper->series());
    Q_ASSERT(series);
    series->setName(QStringLiteral("S1"));

    m_hModelMapper->setSeries(nullptr);
    m_hModelMapper->setFirstSetRow(-1);
    m_hModelMapper->setLastSetRow(-1);

    CustomTableModel *model = qobject_cast<CustomTableModel *>(m_hModelMapper->model());
    model->clearRows();
}
