/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** 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 Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or 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.GPL2 and 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-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qtgradientstopsmodel.h"
#include <QtGui/QColor>

QT_BEGIN_NAMESPACE

class QtGradientStopPrivate
{
public:
    qreal m_position;
    QColor m_color;
    QtGradientStopsModel *m_model;
};

qreal QtGradientStop::position() const
{
    return d_ptr->m_position;
}

QColor QtGradientStop::color() const
{
    return d_ptr->m_color;
}

QtGradientStopsModel *QtGradientStop::gradientModel() const
{
    return d_ptr->m_model;
}

void QtGradientStop::setColor(const QColor &color)
{
    d_ptr->m_color = color;
}

void QtGradientStop::setPosition(qreal position)
{
    d_ptr->m_position = position;
}

QtGradientStop::QtGradientStop(QtGradientStopsModel *model)
    : d_ptr(new QtGradientStopPrivate())
{
    d_ptr->m_position = 0;
    d_ptr->m_color = Qt::white;
    d_ptr->m_model = model;
}

QtGradientStop::~QtGradientStop()
{
}

class QtGradientStopsModelPrivate
{
    QtGradientStopsModel *q_ptr;
    Q_DECLARE_PUBLIC(QtGradientStopsModel)
public:
    QMap<qreal, QtGradientStop *> m_posToStop;
    QMap<QtGradientStop *, qreal> m_stopToPos;
    QMap<QtGradientStop *, bool> m_selection;
    QtGradientStop *m_current;
};



QtGradientStopsModel::QtGradientStopsModel(QObject *parent)
    : QObject(parent), d_ptr(new QtGradientStopsModelPrivate)
{
    d_ptr->q_ptr = this;
    d_ptr->m_current = 0;
}

QtGradientStopsModel::~QtGradientStopsModel()
{
    clear();
}

QtGradientStopsModel::PositionStopMap QtGradientStopsModel::stops() const
{
    return d_ptr->m_posToStop;
}

QtGradientStop *QtGradientStopsModel::at(qreal pos) const
{
    if (d_ptr->m_posToStop.contains(pos))
        return d_ptr->m_posToStop[pos];
    return 0;
}

QColor QtGradientStopsModel::color(qreal pos) const
{
    PositionStopMap gradStops = stops();
    if (gradStops.isEmpty())
        return QColor::fromRgbF(pos, pos, pos, 1.0);
    if (gradStops.contains(pos))
        return gradStops[pos]->color();

    gradStops[pos] = 0;
    PositionStopMap::ConstIterator itStop = gradStops.constFind(pos);
    if (itStop == gradStops.constBegin()) {
        ++itStop;
        return itStop.value()->color();
    }
    if (itStop == --gradStops.constEnd()) {
        --itStop;
        return itStop.value()->color();
    }
    PositionStopMap::ConstIterator itPrev = itStop;
    PositionStopMap::ConstIterator itNext = itStop;
    --itPrev;
    ++itNext;

    double prevX = itPrev.key();
    double nextX = itNext.key();

    double coefX = (pos - prevX) / (nextX - prevX);
    QColor prevCol = itPrev.value()->color();
    QColor nextCol = itNext.value()->color();

    QColor newColor;
    newColor.setRgbF((nextCol.redF()   - prevCol.redF()  ) * coefX + prevCol.redF(),
                     (nextCol.greenF() - prevCol.greenF()) * coefX + prevCol.greenF(),
                     (nextCol.blueF()  - prevCol.blueF() ) * coefX + prevCol.blueF(),
                     (nextCol.alphaF() - prevCol.alphaF()) * coefX + prevCol.alphaF());
    return newColor;
}

QList<QtGradientStop *> QtGradientStopsModel::selectedStops() const
{
    return d_ptr->m_selection.keys();
}

QtGradientStop *QtGradientStopsModel::currentStop() const
{
    return d_ptr->m_current;
}

bool QtGradientStopsModel::isSelected(QtGradientStop *stop) const
{
    if (d_ptr->m_selection.contains(stop))
        return true;
    return false;
}

QtGradientStop *QtGradientStopsModel::addStop(qreal pos, const QColor &color)
{
    qreal newPos = pos;
    if (pos < 0.0)
        newPos = 0.0;
    if (pos > 1.0)
        newPos = 1.0;
    if (d_ptr->m_posToStop.contains(newPos))
        return 0;
    QtGradientStop *stop = new QtGradientStop();
    stop->setPosition(newPos);
    stop->setColor(color);

    d_ptr->m_posToStop[newPos] = stop;
    d_ptr->m_stopToPos[stop] = newPos;

    emit stopAdded(stop);

    return stop;
}

void QtGradientStopsModel::removeStop(QtGradientStop *stop)
{
    if (!d_ptr->m_stopToPos.contains(stop))
        return;
    if (currentStop() == stop)
        setCurrentStop(0);
    selectStop(stop, false);

    emit stopRemoved(stop);

    qreal pos = d_ptr->m_stopToPos[stop];
    d_ptr->m_stopToPos.remove(stop);
    d_ptr->m_posToStop.remove(pos);
    delete stop;
}

void QtGradientStopsModel::moveStop(QtGradientStop *stop, qreal newPos)
{
    if (!d_ptr->m_stopToPos.contains(stop))
        return;
    if (d_ptr->m_posToStop.contains(newPos))
        return;

    if (newPos > 1.0)
        newPos = 1.0;
    else if (newPos < 0.0)
        newPos = 0.0;

    emit stopMoved(stop, newPos);

    const qreal oldPos = stop->position();
    stop->setPosition(newPos);
    d_ptr->m_stopToPos[stop] = newPos;
    d_ptr->m_posToStop.remove(oldPos);
    d_ptr->m_posToStop[newPos] = stop;
}

void QtGradientStopsModel::swapStops(QtGradientStop *stop1, QtGradientStop *stop2)
{
    if (stop1 == stop2)
        return;
    if (!d_ptr->m_stopToPos.contains(stop1))
        return;
    if (!d_ptr->m_stopToPos.contains(stop2))
        return;

    emit stopsSwapped(stop1, stop2);

    const qreal pos1 = stop1->position();
    const qreal pos2 = stop2->position();
    stop1->setPosition(pos2);
    stop2->setPosition(pos1);
    d_ptr->m_stopToPos[stop1] = pos2;
    d_ptr->m_stopToPos[stop2] = pos1;
    d_ptr->m_posToStop[pos1] = stop2;
    d_ptr->m_posToStop[pos2] = stop1;
}

void QtGradientStopsModel::changeStop(QtGradientStop *stop, const QColor &newColor)
{
    if (!d_ptr->m_stopToPos.contains(stop))
        return;
    if (stop->color() == newColor)
        return;

    emit stopChanged(stop, newColor);

    stop->setColor(newColor);
}

void QtGradientStopsModel::selectStop(QtGradientStop *stop, bool select)
{
    if (!d_ptr->m_stopToPos.contains(stop))
        return;
    bool selected = d_ptr->m_selection.contains(stop);
    if (select == selected)
        return;

    emit stopSelected(stop, select);

    if (select)
        d_ptr->m_selection[stop] = true;
    else
        d_ptr->m_selection.remove(stop);
}

void QtGradientStopsModel::setCurrentStop(QtGradientStop *stop)
{
    if (stop && !d_ptr->m_stopToPos.contains(stop))
        return;
    if (stop == currentStop())
        return;

    emit currentStopChanged(stop);

    d_ptr->m_current = stop;
}

QtGradientStop *QtGradientStopsModel::firstSelected() const
{
    PositionStopMap stopList = stops();
    PositionStopMap::ConstIterator itStop = stopList.constBegin();
    while (itStop != stopList.constEnd()) {
        QtGradientStop *stop = itStop.value();
        if (isSelected(stop))
            return stop;
        ++itStop;
    };
    return 0;
}

QtGradientStop *QtGradientStopsModel::lastSelected() const
{
    PositionStopMap stopList = stops();
    PositionStopMap::ConstIterator itStop = stopList.constEnd();
    while (itStop != stopList.constBegin()) {
        --itStop;

        QtGradientStop *stop = itStop.value();
        if (isSelected(stop))
            return stop;
    };
    return 0;
}

QtGradientStopsModel *QtGradientStopsModel::clone() const
{
    QtGradientStopsModel *model = new QtGradientStopsModel();

    QMap<qreal, QtGradientStop *> stopsToClone = stops();
    for (auto it = stopsToClone.cbegin(), end = stopsToClone.cend(); it != end; ++it)
        model->addStop(it.key(), it.value()->color());
    // clone selection and current also
    return model;
}

void QtGradientStopsModel::moveStops(double newPosition)
{
    QtGradientStop *current = currentStop();
    if (!current)
        return;

    double newPos = newPosition;

    if (newPos > 1)
        newPos = 1;
    else if (newPos < 0)
        newPos = 0;

    if (newPos == current->position())
        return;

    double offset = newPos - current->position();

    QtGradientStop *first = firstSelected();
    QtGradientStop *last = lastSelected();

    if (first && last) { // multiselection
        double maxOffset = 1.0 - last->position();
        double minOffset = -first->position();

        if (offset > maxOffset)
            offset = maxOffset;
        else if (offset < minOffset)
            offset = minOffset;

    }

    if (offset == 0)
        return;

    bool forward = (offset > 0) ? false : true;

    PositionStopMap stopList;

    const auto selected = selectedStops();
    for (QtGradientStop *stop : selected)
        stopList[stop->position()] = stop;
    stopList[current->position()] = current;

    PositionStopMap::ConstIterator itStop = forward ? stopList.constBegin() : stopList.constEnd();
    while (itStop != (forward ? stopList.constEnd() : stopList.constBegin())) {
        if (!forward)
            --itStop;
        QtGradientStop *stop = itStop.value();
            double pos = stop->position() + offset;
            if (pos > 1)
                pos = 1;
            if (pos < 0)
                pos = 0;

            if (current == stop)
                pos = newPos;

            QtGradientStop *oldStop = at(pos);
            if (oldStop && !stopList.values().contains(oldStop))
                removeStop(oldStop);
            moveStop(stop, pos);

        if (forward)
            ++itStop;
    }
}

void QtGradientStopsModel::clear()
{
    const auto stopsList = stops().values();
    for (QtGradientStop *stop : stopsList)
        removeStop(stop);
}

void QtGradientStopsModel::clearSelection()
{
    const auto stopsList = selectedStops();
    for (QtGradientStop *stop : stopsList)
        selectStop(stop, false);
}

namespace {
    template <typename BidirectionalIterator>
    std::reverse_iterator<BidirectionalIterator> rev(BidirectionalIterator it)
    { return std::reverse_iterator<BidirectionalIterator>(it); }
}

void QtGradientStopsModel::flipAll()
{
    QMap<qreal, QtGradientStop *> stopsMap = stops();
    QMap<QtGradientStop *, bool> swappedList;
    for (auto itStop = rev(stopsMap.keyValueEnd()), end = rev(stopsMap.keyValueBegin()); itStop != end; ++itStop) {
        QtGradientStop *stop = (*itStop).second;
        if (swappedList.contains(stop))
            continue;
        const double newPos = 1.0 - (*itStop).first;
        if (stopsMap.contains(newPos)) {
            QtGradientStop *swapped = stopsMap.value(newPos);
            swappedList[swapped] = true;
            swapStops(stop, swapped);
        } else {
            moveStop(stop, newPos);
        }
    }
}

void QtGradientStopsModel::selectAll()
{
    const auto stopsMap = stops();
    for (auto it = stopsMap.cbegin(), end = stopsMap.cend(); it != end; ++it)
        selectStop(it.value(), true);
}

void QtGradientStopsModel::deleteStops()
{
    const auto selected = selectedStops();
    for (QtGradientStop *stop : selected)
        removeStop(stop);
    QtGradientStop *current = currentStop();
    if (current)
        removeStop(current);
}

QT_END_NAMESPACE
