/****************************************************************************
**
** 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 <private/legendlayout_p.h>
#include <private/chartpresenter_p.h>
#include <private/qlegend_p.h>
#include <private/abstractchartlayout_p.h>

#include <private/qlegendmarker_p.h>
#include <private/legendmarkeritem_p.h>
#include <QtCharts/QLegendMarker>

QT_CHARTS_BEGIN_NAMESPACE

LegendLayout::LegendLayout(QLegend *legend)
    : m_legend(legend),
      m_offsetX(0),
      m_offsetY(0)
{

}

LegendLayout::~LegendLayout()
{

}

void LegendLayout::setOffset(qreal x, qreal y)
{
    bool scrollHorizontal = true;
    switch (m_legend->alignment()) {
    case Qt::AlignTop:
    case Qt::AlignBottom:
        scrollHorizontal = true;
        break;
    case Qt::AlignLeft:
    case Qt::AlignRight:
        scrollHorizontal = false;
        break;
    }

    // If detached, the scrolling direction is vertical instead of horizontal and vice versa.
    if (!m_legend->isAttachedToChart())
        scrollHorizontal = !scrollHorizontal;

    QRectF boundingRect = geometry();
    qreal left, top, right, bottom;
    getContentsMargins(&left, &top, &right, &bottom);
    boundingRect.adjust(left, top, -right, -bottom);

    // Limit offset between m_minOffset and m_maxOffset
    if (scrollHorizontal) {
        if (m_width <= boundingRect.width())
            return;

        if (x != m_offsetX) {
            m_offsetX = qBound(m_minOffsetX, x, m_maxOffsetX);
            m_legend->d_ptr->items()->setPos(-m_offsetX, boundingRect.top());
        }
    } else {
        if (m_height <= boundingRect.height())
            return;

        if (y != m_offsetY) {
            m_offsetY = qBound(m_minOffsetY, y, m_maxOffsetY);
            m_legend->d_ptr->items()->setPos(boundingRect.left(), -m_offsetY);
        }
    }
}

QPointF LegendLayout::offset() const
{
    return QPointF(m_offsetX, m_offsetY);
}

void LegendLayout::invalidate()
{
    QGraphicsLayout::invalidate();
    if (m_legend->isAttachedToChart())
        m_legend->d_ptr->m_presenter->layout()->invalidate();
}

void LegendLayout::setGeometry(const QRectF &rect)
{
    m_legend->d_ptr->items()->setVisible(m_legend->isVisible());

    QGraphicsLayout::setGeometry(rect);

    if (m_legend->isAttachedToChart())
        setAttachedGeometry(rect);
    else
        setDettachedGeometry(rect);
}

void LegendLayout::setAttachedGeometry(const QRectF &rect)
{
    if (!rect.isValid())
        return;

    qreal oldOffsetX = m_offsetX;
    qreal oldOffsetY = m_offsetY;
    m_offsetX = 0;
    m_offsetY = 0;

    QSizeF size(0, 0);

    if (m_legend->d_ptr->markers().isEmpty()) {
        return;
    }

    m_width = 0;
    m_height = 0;

    qreal left, top, right, bottom;
    getContentsMargins(&left, &top, &right, &bottom);

    QRectF geometry = rect.adjusted(left, top, -right, -bottom);

    switch(m_legend->alignment()) {
    case Qt::AlignTop:
    case Qt::AlignBottom: {
            // Calculate the space required for items and add them to a sorted list.
            qreal markerItemsWidth = 0;
            qreal itemMargins = 0;
            QList<LegendWidthStruct *> legendWidthList;
            foreach (QLegendMarker *marker, m_legend->d_ptr->markers()) {
                LegendMarkerItem *item = marker->d_ptr->item();
                if (item->isVisible()) {
                    QSizeF dummySize;
                    qreal itemWidth = item->sizeHint(Qt::PreferredSize, dummySize).width();
                    LegendWidthStruct *structItem = new LegendWidthStruct;
                    structItem->item = item;
                    structItem->width = itemWidth;
                    legendWidthList.append(structItem);
                    markerItemsWidth += itemWidth;
                    itemMargins += marker->d_ptr->item()->m_margin;
                }
            }
            std::sort(legendWidthList.begin(), legendWidthList.end(), widthLongerThan);

            // If the items would occupy more space than is available, start truncating them
            // from the longest one.
            qreal availableGeometry = geometry.width() - right - left * 2 - itemMargins;
            if (markerItemsWidth >= availableGeometry && legendWidthList.count() > 0) {
                bool truncated(false);
                int count = legendWidthList.count();
                for (int i = 1; i < count; i++) {
                    int truncateIndex = i - 1;

                    while (legendWidthList.at(truncateIndex)->width >= legendWidthList.at(i)->width
                           && !truncated) {
                        legendWidthList.at(truncateIndex)->width--;
                        markerItemsWidth--;
                        if (i > 1) {
                            // Truncate the items that are before the truncated one in the list.
                            for (int j = truncateIndex - 1; j >= 0; j--) {
                                if (legendWidthList.at(truncateIndex)->width
                                        < legendWidthList.at(j)->width) {
                                    legendWidthList.at(j)->width--;
                                    markerItemsWidth--;
                                }
                            }
                        }
                        if (markerItemsWidth < availableGeometry)
                            truncated = true;
                    }
                    // Truncate the last item if needed.
                    if (i == count - 1) {
                        if (legendWidthList.at(count - 1)->width
                                > legendWidthList.at(truncateIndex)->width) {
                            legendWidthList.at(count - 1)->width--;
                            markerItemsWidth--;
                        }
                    }

                    if (truncated)
                        break;
                }
                // Items are of same width and all of them need to be truncated
                // or there is just one item that is truncated.
                while (markerItemsWidth >= availableGeometry) {
                    for (int i = 0; i < count; i++) {
                        legendWidthList.at(i)->width--;
                        markerItemsWidth--;
                    }
                }
            }

            QPointF point(0,0);

            int markerCount = m_legend->d_ptr->markers().count();
            for (int i = 0; i < markerCount; i++) {
                QLegendMarker *marker;
                if (m_legend->d_ptr->m_reverseMarkers)
                    marker = m_legend->d_ptr->markers().at(markerCount - 1 - i);
                else
                    marker = m_legend->d_ptr->markers().at(i);
                LegendMarkerItem *item = marker->d_ptr->item();
                if (item->isVisible()) {
                    QRectF itemRect = geometry;
                    qreal availableWidth = 0;
                    for (int i = 0; i < legendWidthList.size(); ++i) {
                        if (legendWidthList.at(i)->item == item) {
                            availableWidth = legendWidthList.at(i)->width;
                            break;
                        }
                    }
                    itemRect.setWidth(availableWidth);
                    item->setGeometry(itemRect);
                    item->setPos(point.x(),geometry.height()/2 - item->boundingRect().height()/2);
                    const QRectF &rect = item->boundingRect();
                    size = size.expandedTo(rect.size());
                    qreal w = rect.width();
                    m_width = m_width + w - item->m_margin;
                    point.setX(point.x() + w);
                }
            }
            // Delete structs from the container
            qDeleteAll(legendWidthList);

            // Round to full pixel via QPoint to avoid one pixel clipping on the edge in some cases
            if (m_width < geometry.width()) {
                m_legend->d_ptr->items()->setPos(QPoint(geometry.width() / 2 - m_width / 2,
                                                        geometry.top()));
            } else {
                m_legend->d_ptr->items()->setPos(geometry.topLeft().toPoint());
            }
            m_height = size.height();
        }
        break;
    case Qt::AlignLeft:
    case Qt::AlignRight: {
            QPointF point(0,0);
            int markerCount = m_legend->d_ptr->markers().count();
            for (int i = 0; i < markerCount; i++) {
                QLegendMarker *marker;
                if (m_legend->d_ptr->m_reverseMarkers)
                    marker = m_legend->d_ptr->markers().at(markerCount - 1 - i);
                else
                    marker = m_legend->d_ptr->markers().at(i);
                LegendMarkerItem *item = marker->d_ptr->item();
                if (item->isVisible()) {
                    item->setGeometry(geometry);
                    item->setPos(point);
                    const QRectF &rect = item->boundingRect();
                    qreal h = rect.height();
                    size = size.expandedTo(rect.size());
                    m_height+=h;
                    point.setY(point.y() + h);
                }
            }

            // Round to full pixel via QPoint to avoid one pixel clipping on the edge in some cases
            if (m_height < geometry.height()) {
                m_legend->d_ptr->items()->setPos(QPoint(geometry.left(),
                                                        geometry.height() / 2 - m_height / 2));
            } else {
                m_legend->d_ptr->items()->setPos(geometry.topLeft().toPoint());
            }
            m_width = size.width();
            break;
            }
        }

    m_minOffsetX = -left;
    m_minOffsetY = - top;
    m_maxOffsetX = m_width - geometry.width() - right;
    m_maxOffsetY = m_height - geometry.height() - bottom;

    setOffset(oldOffsetX, oldOffsetY);
}

void LegendLayout::setDettachedGeometry(const QRectF &rect)
{
    if (!rect.isValid())
        return;

    // Detached layout is different.
    // In detached mode legend may have multiple rows and columns, so layout calculations
    // differ a log from attached mode.
    // Also the scrolling logic is bit different.

    qreal oldOffsetX = m_offsetX;
    qreal oldOffsetY = m_offsetY;
    m_offsetX = 0;
    m_offsetY = 0;

    qreal left, top, right, bottom;
    getContentsMargins(&left, &top, &right, &bottom);
    QRectF geometry = rect.adjusted(left, top, -right, -bottom);

    QList<QLegendMarker *> markers = m_legend->d_ptr->markers();

    if (markers.isEmpty())
        return;

    switch (m_legend->alignment()) {
    case Qt::AlignTop: {
        QPointF point(0, 0);
        m_width = 0;
        m_height = 0;
        for (int i = 0; i < markers.count(); i++) {
            LegendMarkerItem *item = markers.at(i)->d_ptr->item();
            if (item->isVisible()) {
                item->setGeometry(geometry);
                item->setPos(point.x(),point.y());
                const QRectF &boundingRect = item->boundingRect();
                qreal w = boundingRect.width();
                qreal h = boundingRect.height();
                m_width = qMax(m_width,w);
                m_height = qMax(m_height,h);
                point.setX(point.x() + w);
                if (point.x() + w > geometry.left() + geometry.width() - right) {
                    // Next item would go off rect.
                    point.setX(0);
                    point.setY(point.y() + h);
                    if (i+1 < markers.count()) {
                        m_height += h;
                    }
                }
            }
        }
        m_legend->d_ptr->items()->setPos(geometry.topLeft());

        m_minOffsetX = -left;
        m_minOffsetY = -top;
        m_maxOffsetX = m_width - geometry.width() - right;
        m_maxOffsetY = m_height - geometry.height() - bottom;
    }
    break;
    case Qt::AlignBottom: {
        QPointF point(0, geometry.height());
        m_width = 0;
        m_height = 0;
        for (int i = 0; i < markers.count(); i++) {
            LegendMarkerItem *item = markers.at(i)->d_ptr->item();
            if (item->isVisible()) {
                item->setGeometry(geometry);
                const QRectF &boundingRect = item->boundingRect();
                qreal w = boundingRect.width();
                qreal h = boundingRect.height();
                m_width = qMax(m_width,w);
                m_height = qMax(m_height,h);
                item->setPos(point.x(),point.y() - h);
                point.setX(point.x() + w);
                if (point.x() + w > geometry.left() + geometry.width() - right) {
                    // Next item would go off rect.
                    point.setX(0);
                    point.setY(point.y() - h);
                    if (i+1 < markers.count()) {
                        m_height += h;
                    }
                }
            }
        }
        m_legend->d_ptr->items()->setPos(geometry.topLeft());

        m_minOffsetX = -left;
        m_minOffsetY = -m_height + geometry.height() - top;
        m_maxOffsetX = m_width - geometry.width() - right;
        m_maxOffsetY = -bottom;
    }
    break;
    case Qt::AlignLeft: {
        QPointF point(0, 0);
        m_width = 0;
        m_height = 0;
        qreal maxWidth = 0;
        for (int i = 0; i < markers.count(); i++) {
            LegendMarkerItem *item = markers.at(i)->d_ptr->item();
            if (item->isVisible()) {
                item->setGeometry(geometry);
                const QRectF &boundingRect = item->boundingRect();
                qreal w = boundingRect.width();
                qreal h = boundingRect.height();
                m_height = qMax(m_height,h);
                maxWidth = qMax(maxWidth,w);
                item->setPos(point.x(),point.y());
                point.setY(point.y() + h);
                if (point.y() + h > geometry.bottom() - bottom) {
                    // Next item would go off rect.
                    point.setX(point.x() + maxWidth);
                    point.setY(0);
                    if (i+1 < markers.count()) {
                        m_width += maxWidth;
                        maxWidth = 0;
                    }
                }
            }
        }
        m_width += maxWidth;
        m_legend->d_ptr->items()->setPos(geometry.topLeft());

        m_minOffsetX = -left;
        m_minOffsetY = -top;
        m_maxOffsetX = m_width - geometry.width() - right;
        m_maxOffsetY = m_height - geometry.height() - bottom;
    }
    break;
    case Qt::AlignRight: {
        QPointF point(geometry.width(), 0);
        m_width = 0;
        m_height = 0;
        qreal maxWidth = 0;
        for (int i = 0; i < markers.count(); i++) {
            LegendMarkerItem *item = markers.at(i)->d_ptr->item();
            if (item->isVisible()) {
                item->setGeometry(geometry);
                const QRectF &boundingRect = item->boundingRect();
                qreal w = boundingRect.width();
                qreal h = boundingRect.height();
                m_height = qMax(m_height,h);
                maxWidth = qMax(maxWidth,w);
                item->setPos(point.x() - w,point.y());
                point.setY(point.y() + h);
                if (point.y() + h > geometry.bottom()-bottom) {
                    // Next item would go off rect.
                    point.setX(point.x() - maxWidth);
                    point.setY(0);
                    if (i+1 < markers.count()) {
                        m_width += maxWidth;
                        maxWidth = 0;
                    }
                }
            }
        }
        m_width += maxWidth;
        m_legend->d_ptr->items()->setPos(geometry.topLeft());

        m_minOffsetX = - m_width + geometry.width() - left;
        m_minOffsetY = -top;
        m_maxOffsetX = - right;
        m_maxOffsetY = m_height - geometry.height() - bottom;
    }
    break;
    default:
        break;
    }

    setOffset(oldOffsetX, oldOffsetY);
}

QSizeF LegendLayout::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
{
    QSizeF size(0, 0);
    qreal left, top, right, bottom;
    getContentsMargins(&left, &top, &right, &bottom);

    if(constraint.isValid()) {
        foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
            LegendMarkerItem *item = marker->d_ptr->item();
            size = size.expandedTo(item->effectiveSizeHint(which));
        }
        size = size.boundedTo(constraint);
    }
    else if (constraint.width() >= 0) {
        qreal width = 0;
        qreal height = 0;
        foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
            LegendMarkerItem *item = marker->d_ptr->item();
            width+=item->effectiveSizeHint(which).width();
            height=qMax(height,item->effectiveSizeHint(which).height());
        }

        size = QSizeF(qMin(constraint.width(),width), height);
    }
    else if (constraint.height() >= 0) {
        qreal width = 0;
        qreal height = 0;
        foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
            LegendMarkerItem *item = marker->d_ptr->item();
            width=qMax(width,item->effectiveSizeHint(which).width());
            height+=height,item->effectiveSizeHint(which).height();
        }
        size = QSizeF(width,qMin(constraint.height(),height));
    }
    else {
        foreach(QLegendMarker *marker, m_legend->d_ptr->markers()) {
            LegendMarkerItem *item = marker->d_ptr->item();
            size = size.expandedTo(item->effectiveSizeHint(which));
        }
    }
    size += QSize(left + right, top + bottom);
    return size;
}

bool LegendLayout::widthLongerThan(const LegendWidthStruct *item1,
                                   const LegendWidthStruct *item2)
{
    return item1->width > item2->width;
}

QT_CHARTS_END_NAMESPACE
