/****************************************************************************
**
** 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/QCandlestickSeries>
#include <QtCharts/QCandlestickSet>
#include <private/candlestickchartitem_p.h>
#include <private/candlestick_p.h>
#include <private/candlestickdata_p.h>
#include <private/qcandlestickseries_p.h>
#include <private/candlestickanimation_p.h>

QT_CHARTS_BEGIN_NAMESPACE

CandlestickChartItem::CandlestickChartItem(QCandlestickSeries *series, QGraphicsItem *item)
    : ChartItem(series->d_func(), item),
      m_series(series),
      m_seriesIndex(0),
      m_seriesCount(0),
      m_timePeriod(0.0),
      m_animation(nullptr)
{
    setAcceptedMouseButtons({});
    connect(series, SIGNAL(candlestickSetsAdded(QList<QCandlestickSet *>)),
            this, SLOT(handleCandlestickSetsAdd(QList<QCandlestickSet *>)));
    connect(series, SIGNAL(candlestickSetsRemoved(QList<QCandlestickSet *>)),
            this, SLOT(handleCandlestickSetsRemove(QList<QCandlestickSet *>)));

    connect(series->d_func(), SIGNAL(updated()), this, SLOT(handleCandlesticksUpdated()));
    connect(series->d_func(), SIGNAL(updatedLayout()), this, SLOT(handleLayoutUpdated()));
    connect(series->d_func(), SIGNAL(updatedCandlesticks()),
            this, SLOT(handleCandlesticksUpdated()));

    setZValue(ChartPresenter::CandlestickSeriesZValue);

    handleCandlestickSetsAdd(m_series->sets());
}

CandlestickChartItem::~CandlestickChartItem()
{
}

void CandlestickChartItem::setAnimation(CandlestickAnimation *animation)
{
    m_animation = animation;

    if (m_animation) {
        foreach (Candlestick *item, m_candlesticks.values())
            m_animation->addCandlestick(item);

        handleDomainUpdated();
    }
}

QRectF CandlestickChartItem::boundingRect() const
{
    return m_boundingRect;
}

void CandlestickChartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                                 QWidget *widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}

void CandlestickChartItem::handleDomainUpdated()
{
    if ((domain()->size().width() <= 0) || (domain()->size().height() <= 0))
        return;

    // Set bounding rectangle to same as domain size. Add one pixel at the top (-1.0) and the bottom
    // as 0.0 would snip a bit off from the wick at the grid line.
    m_boundingRect.setRect(0.0, -1.0, domain()->size().width(), domain()->size().height() + 1.0);

    foreach (Candlestick *item, m_candlesticks.values()) {
        item->updateGeometry(domain());

        if (m_animation)
            presenter()->startAnimation(m_animation->candlestickAnimation(item));
    }
}

void CandlestickChartItem::handleLayoutUpdated()
{
    bool timestampChanged = false;
    foreach (QCandlestickSet *set, m_candlesticks.keys()) {
        qreal oldTimestamp = m_candlesticks.value(set)->m_data.m_timestamp;
        qreal newTimestamp = set->timestamp();
        if (Q_UNLIKELY(oldTimestamp != newTimestamp)) {
            removeTimestamp(oldTimestamp);
            addTimestamp(newTimestamp);
            timestampChanged = true;
        }
    }
    if (timestampChanged)
        updateTimePeriod();

    foreach (Candlestick *item, m_candlesticks.values()) {
        if (m_animation)
            m_animation->setAnimationStart(item);

        item->setTimePeriod(m_timePeriod);
        item->setMaximumColumnWidth(m_series->maximumColumnWidth());
        item->setMinimumColumnWidth(m_series->minimumColumnWidth());
        item->setBodyWidth(m_series->bodyWidth());
        item->setCapsWidth(m_series->capsWidth());

        bool dirty = updateCandlestickGeometry(item, item->m_data.m_index);
        if (dirty && m_animation)
            presenter()->startAnimation(m_animation->candlestickChangeAnimation(item));
        else
            item->updateGeometry(domain());
    }
}

void CandlestickChartItem::handleCandlesticksUpdated()
{
    foreach (QCandlestickSet *set, m_candlesticks.keys())
        updateCandlestickAppearance(m_candlesticks.value(set), set);
}

void CandlestickChartItem::handleCandlestickSeriesChange()
{
    int seriesIndex = 0;
    int seriesCount = 0;

    int index = 0;
    foreach (QAbstractSeries *series, m_series->chart()->series()) {
        if (series->type() == QAbstractSeries::SeriesTypeCandlestick) {
            if (m_series == static_cast<QCandlestickSeries *>(series))
                seriesIndex = index;
            index++;
        }
    }
    seriesCount = index;

    bool changed;
    if ((m_seriesIndex != seriesIndex) || (m_seriesCount != seriesCount))
        changed = true;
    else
        changed = false;

    if (changed) {
        m_seriesIndex = seriesIndex;
        m_seriesCount = seriesCount;
        handleDataStructureChanged();
    }
}

void CandlestickChartItem::handleCandlestickSetsAdd(const QList<QCandlestickSet *> &sets)
{
    foreach (QCandlestickSet *set, sets) {
        Candlestick *item = m_candlesticks.value(set, 0);
        if (item) {
            qWarning() << "There is already a candlestick for this set in the hash";
            continue;
        }

        item = new Candlestick(set, domain(), this);
        m_candlesticks.insert(set, item);
        addTimestamp(set->timestamp());

        connect(item, SIGNAL(clicked(QCandlestickSet *)),
                m_series, SIGNAL(clicked(QCandlestickSet *)));
        connect(item, SIGNAL(hovered(bool, QCandlestickSet *)),
                m_series, SIGNAL(hovered(bool, QCandlestickSet *)));
        connect(item, SIGNAL(pressed(QCandlestickSet *)),
                m_series, SIGNAL(pressed(QCandlestickSet *)));
        connect(item, SIGNAL(released(QCandlestickSet *)),
                m_series, SIGNAL(released(QCandlestickSet *)));
        connect(item, SIGNAL(doubleClicked(QCandlestickSet *)),
                m_series, SIGNAL(doubleClicked(QCandlestickSet *)));
        connect(item, SIGNAL(clicked(QCandlestickSet *)), set, SIGNAL(clicked()));
        connect(item, SIGNAL(hovered(bool, QCandlestickSet *)), set, SIGNAL(hovered(bool)));
        connect(item, SIGNAL(pressed(QCandlestickSet *)), set, SIGNAL(pressed()));
        connect(item, SIGNAL(released(QCandlestickSet *)), set, SIGNAL(released()));
        connect(item, SIGNAL(doubleClicked(QCandlestickSet *)), set, SIGNAL(doubleClicked()));
    }

    handleDataStructureChanged();
}

void CandlestickChartItem::handleCandlestickSetsRemove(const QList<QCandlestickSet *> &sets)
{
    foreach (QCandlestickSet *set, sets) {
        Candlestick *item = m_candlesticks.value(set);

        m_candlesticks.remove(set);
        removeTimestamp(set->timestamp());

        if (m_animation) {
            ChartAnimation *animation = m_animation->candlestickAnimation(item);
            if (animation) {
                animation->stop();
                delete animation;
            }
        }

        delete item;
    }

    handleDataStructureChanged();
}

void CandlestickChartItem::handleDataStructureChanged()
{
    updateTimePeriod();

    for (int i = 0; i < m_series->count(); ++i) {
        QCandlestickSet *set = m_series->sets().at(i);
        Candlestick *item = m_candlesticks.value(set);

        updateCandlestickGeometry(item, i);
        updateCandlestickAppearance(item, set);

        item->updateGeometry(domain());

        if (m_animation)
            m_animation->addCandlestick(item);
    }

    handleDomainUpdated();
}

bool CandlestickChartItem::updateCandlestickGeometry(Candlestick *item, int index)
{
    bool changed = false;

    QCandlestickSet *set = m_series->sets().at(index);
    CandlestickData &data = item->m_data;

    if ((data.m_open != set->open())
        || (data.m_high != set->high())
        || (data.m_low != set->low())
        || (data.m_close != set->close())) {
        changed = true;
    }

    data.m_timestamp = set->timestamp();
    data.m_open = set->open();
    data.m_high = set->high();
    data.m_low = set->low();
    data.m_close = set->close();
    data.m_index = index;

    data.m_maxX = domain()->maxX();
    data.m_minX = domain()->minX();
    data.m_maxY = domain()->maxY();
    data.m_minY = domain()->minY();

    data.m_series = m_series;
    data.m_seriesIndex = m_seriesIndex;
    data.m_seriesCount = m_seriesCount;

    return changed;
}

void CandlestickChartItem::updateCandlestickAppearance(Candlestick *item, QCandlestickSet *set)
{
    item->setTimePeriod(m_timePeriod);
    item->setMaximumColumnWidth(m_series->maximumColumnWidth());
    item->setMinimumColumnWidth(m_series->minimumColumnWidth());
    item->setBodyWidth(m_series->bodyWidth());
    item->setBodyOutlineVisible(m_series->bodyOutlineVisible());
    item->setCapsWidth(m_series->capsWidth());
    item->setCapsVisible(m_series->capsVisible());
    item->setIncreasingColor(m_series->increasingColor());
    item->setDecreasingColor(m_series->decreasingColor());

    // Set the decorative issues for the candlestick so that
    // the brush and pen already defined for the set are kept.
    if (set->brush() == Qt::NoBrush)
        item->setBrush(m_series->brush());
    else
        item->setBrush(set->brush());

    if (set->pen() == Qt::NoPen)
        item->setPen(m_series->pen());
    else
        item->setPen(set->pen());
}

void CandlestickChartItem::addTimestamp(qreal timestamp)
{
    int index = 0;
    for (int i = m_timestamps.count() - 1; i >= 0; --i) {
        if (timestamp > m_timestamps.at(i)) {
            index = i + 1;
            break;
        }
    }
    m_timestamps.insert(index, timestamp);
}

void CandlestickChartItem::removeTimestamp(qreal timestamp)
{
    m_timestamps.removeOne(timestamp);
}

void CandlestickChartItem::updateTimePeriod()
{
    if (m_timestamps.count() == 0) {
        m_timePeriod = 0;
        return;
    }

    if (m_timestamps.count() == 1) {
        m_timePeriod = qAbs(domain()->maxX() - domain()->minX());
        return;
    }

    qreal timePeriod = qAbs(m_timestamps.at(1) - m_timestamps.at(0));
    for (int i = 1; i < m_timestamps.count(); ++i) {
        timePeriod = qMin(timePeriod, qAbs(m_timestamps.at(i) - m_timestamps.at(i - 1)));
    }
    m_timePeriod = timePeriod;
}

QT_CHARTS_END_NAMESPACE

#include "moc_candlestickchartitem_p.cpp"
