/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module 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 "qquickdroparea_p.h"
#include "qquickdrag_p.h"
#include "qquickitem_p.h"

#include <private/qv4arraybuffer_p.h>

#include <QtCore/qregularexpression.h>

QT_BEGIN_NAMESPACE

QQuickDropAreaDrag::QQuickDropAreaDrag(QQuickDropAreaPrivate *d, QObject *parent)
    : QObject(parent)
    , d(d)
{
}

QQuickDropAreaDrag::~QQuickDropAreaDrag()
{
}

class QQuickDropAreaPrivate : public QQuickItemPrivate
{
    Q_DECLARE_PUBLIC(QQuickDropArea)

public:
    QQuickDropAreaPrivate();
    ~QQuickDropAreaPrivate();

    bool hasMatchingKey(const QStringList &keys) const;

    QStringList getKeys(const QMimeData *mimeData) const;

    QStringList keys;
    QRegularExpression keyRegExp;
    QPointF dragPosition;
    QQuickDropAreaDrag *drag;
    QPointer<QObject> source;
    bool containsDrag;
};

QQuickDropAreaPrivate::QQuickDropAreaPrivate()
    : drag(nullptr)
    , containsDrag(false)
{
}

QQuickDropAreaPrivate::~QQuickDropAreaPrivate()
{
    delete drag;
}

/*!
    \qmltype DropArea
    \instantiates QQuickDropArea
    \inqmlmodule QtQuick
    \ingroup qtquick-input
    \brief For specifying drag and drop handling in an area.

    A DropArea is an invisible item which receives events when other items are
    dragged over it.

    The \l Drag attached property can be used to notify the DropArea when an Item is
    dragged over it.

    The \l keys property can be used to filter drag events which don't include
    a matching key.

    The \l drag.source property is communicated to the source of a drag event as
    the recipient of a drop on the drag target.

    \sa {Qt Quick Examples - Drag and Drop}, {Qt Quick Examples - externaldraganddrop}
*/

QQuickDropArea::QQuickDropArea(QQuickItem *parent)
    : QQuickItem(*new QQuickDropAreaPrivate, parent)
{
    setFlags(ItemAcceptsDrops);
}

QQuickDropArea::~QQuickDropArea()
{
}

/*!
    \qmlproperty bool QtQuick::DropArea::containsDrag

    This property identifies whether the DropArea currently contains any
    dragged items.
*/

bool QQuickDropArea::containsDrag() const
{
    Q_D(const QQuickDropArea);
    return d->containsDrag;
}

/*!
    \qmlproperty stringlist QtQuick::DropArea::keys

    This property holds a list of drag keys a DropArea will accept.

    If no keys are listed the DropArea will accept events from any drag source,
    otherwise the drag source must have at least one compatible key.

    \sa QtQuick::Drag::keys
*/

QStringList QQuickDropArea::keys() const
{
    Q_D(const QQuickDropArea);
    return d->keys;
}

void QQuickDropArea::setKeys(const QStringList &keys)
{
    Q_D(QQuickDropArea);
    if (d->keys != keys) {
        d->keys = keys;

        if (keys.isEmpty()) {
            d->keyRegExp = QRegularExpression();
        } else {
            QString pattern = QLatin1Char('(') + QRegularExpression::escape(keys.first());
            for (int i = 1; i < keys.count(); ++i)
                pattern += QLatin1Char('|') + QRegularExpression::escape(keys.at(i));
            pattern += QLatin1Char(')');
            d->keyRegExp = QRegularExpression(
                    QRegularExpression::anchoredPattern(pattern.replace(QLatin1String("\\*"),
                                                                        QLatin1String(".+"))));
        }
        emit keysChanged();
    }
}

QQuickDropAreaDrag *QQuickDropArea::drag()
{
    Q_D(QQuickDropArea);
    if (!d->drag)
        d->drag = new QQuickDropAreaDrag(d);
    return d->drag;
}

/*!
    \qmlproperty Object QtQuick::DropArea::drag.source

    This property holds the source of a drag.
*/

QObject *QQuickDropAreaDrag::source() const
{
    return d->source;
}

/*!
    \qmlpropertygroup QtQuick::DropArea::drag
    \qmlproperty qreal QtQuick::DropArea::drag.x
    \qmlproperty qreal QtQuick::DropArea::drag.y

    These properties hold the coordinates of the last drag event.
*/

qreal QQuickDropAreaDrag::x() const
{
    return d->dragPosition.x();
}

qreal QQuickDropAreaDrag::y() const
{
    return d->dragPosition.y();
}

/*!
    \qmlsignal QtQuick::DropArea::positionChanged(DragEvent drag)

    This signal is emitted when the position of a \a drag has changed.

    The corresponding handler is \c onPositionChanged.
*/

void QQuickDropArea::dragMoveEvent(QDragMoveEvent *event)
{
    Q_D(QQuickDropArea);
    if (!d->containsDrag)
        return;

    d->dragPosition = event->pos();
    if (d->drag)
        emit d->drag->positionChanged();

    event->accept();
    QQuickDropEvent dragTargetEvent(d, event);
    emit positionChanged(&dragTargetEvent);
}

bool QQuickDropAreaPrivate::hasMatchingKey(const QStringList &keys) const
{
    if (keyRegExp.pattern().isEmpty())
        return true;

    for (const QString &key : keys) {
        if (key.contains(keyRegExp))
            return true;
    }
    return false;
}

QStringList QQuickDropAreaPrivate::getKeys(const QMimeData *mimeData) const
{
    if (const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(mimeData))
        return dragMime->keys();
    return mimeData->formats();
}

/*!
    \qmlsignal QtQuick::DropArea::entered(DragEvent drag)

    This signal is emitted when a \a drag enters the bounds of a DropArea.

    The corresponding handler is \c onEntered.
*/

void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event)
{
    Q_D(QQuickDropArea);
    const QMimeData *mimeData = event->mimeData();
    if (!d->effectiveEnable || d->containsDrag || !mimeData || !d->hasMatchingKey(d->getKeys(mimeData)))
        return;

    d->dragPosition = event->pos();

    event->accept();

    QQuickDropEvent dragTargetEvent(d, event);
    emit entered(&dragTargetEvent);
    if (!event->isAccepted())
        return;

    d->containsDrag = true;
    if (QQuickDragMimeData *dragMime = qobject_cast<QQuickDragMimeData *>(const_cast<QMimeData *>(mimeData)))
        d->source = dragMime->source();
    else
        d->source = event->source();
    d->dragPosition = event->pos();
    if (d->drag) {
        emit d->drag->positionChanged();
        emit d->drag->sourceChanged();
    }
    emit containsDragChanged();
}

/*!
    \qmlsignal QtQuick::DropArea::exited()

    This signal is emitted when a drag exits the bounds of a DropArea.

    The corresponding handler is \c onExited.
*/

void QQuickDropArea::dragLeaveEvent(QDragLeaveEvent *)
{
    Q_D(QQuickDropArea);
    if (!d->containsDrag)
        return;

    emit exited();

    d->containsDrag = false;
    d->source = nullptr;
    emit containsDragChanged();
    if (d->drag)
        emit d->drag->sourceChanged();
}

/*!
    \qmlsignal QtQuick::DropArea::dropped(DragEvent drop)

    This signal is emitted when a \a drop event occurs within the bounds of
    a DropArea.

    The corresponding handler is \c onDropped.
*/

void QQuickDropArea::dropEvent(QDropEvent *event)
{
    Q_D(QQuickDropArea);
    if (!d->containsDrag)
        return;

    QQuickDropEvent dragTargetEvent(d, event);
    emit dropped(&dragTargetEvent);

    d->containsDrag = false;
    d->source = nullptr;
    emit containsDragChanged();
    if (d->drag)
        emit d->drag->sourceChanged();
}

/*!
    \qmltype DragEvent
    \instantiates QQuickDropEvent
    \inqmlmodule QtQuick
    \ingroup qtquick-input-events
    \brief Provides information about a drag event.

    The position of the drag event can be obtained from the \l x and \l y
    properties, and the \l keys property identifies the drag keys of the event
    \l {drag.source}{source}.

    The existence of specific drag types can be determined using the \l hasColor,
    \l hasHtml, \l hasText, and \l hasUrls properties.

    The list of all supplied formats can be determined using the \l formats property.

    Specific drag types can be obtained using the \l colorData, \l html, \l text,
    and \l urls properties.

    A string version of any available mimeType can be obtained using \l getDataAsString.
*/

/*!
    \qmlproperty real QtQuick::DragEvent::x

    This property holds the x coordinate of a drag event.
*/

/*!
    \qmlproperty real QtQuick::DragEvent::y

    This property holds the y coordinate of a drag event.
*/

/*!
    \qmlproperty Object QtQuick::DragEvent::drag.source

    This property holds the source of a drag event.
*/

/*!
    \qmlproperty stringlist QtQuick::DragEvent::keys

    This property holds a list of keys identifying the data type or source of a
    drag event.
*/

/*!
    \qmlproperty enumeration QtQuick::DragEvent::action

    This property holds the action that the \l {drag.source}{source} is to perform on an accepted drop.

    The drop action may be one of:

    \list
    \li Qt.CopyAction Copy the data to the target.
    \li Qt.MoveAction Move the data from the source to the target.
    \li Qt.LinkAction Create a link from the source to the target.
    \li Qt.IgnoreAction Ignore the action (do nothing with the data).
    \endlist
*/

/*!
    \qmlproperty flags QtQuick::DragEvent::supportedActions

    This property holds the set of \l {action}{actions} supported by the
    drag source.
*/

/*!
    \qmlproperty flags QtQuick::DragEvent::proposedAction
    \since 5.2

    This property holds the set of \l {action}{actions} proposed by the
    drag source.
*/

/*!
    \qmlproperty bool QtQuick::DragEvent::accepted

    This property holds whether the drag event was accepted by a handler.

    The default value is true.
*/

/*!
    \qmlmethod QtQuick::DragEvent::accept()
    \qmlmethod QtQuick::DragEvent::accept(enumeration action)

    Accepts the drag event.

    If an \a action is specified it will overwrite the value of the \l action property.
*/

/*!
    \qmlmethod QtQuick::DragEvent::acceptProposedAction()
    \since 5.2

    Accepts the drag event with the \l proposedAction.
*/

/*!
    \qmlproperty bool QtQuick::DragEvent::hasColor
    \since 5.2

    This property holds whether the drag event contains a color item.
*/

/*!
    \qmlproperty bool QtQuick::DragEvent::hasHtml
    \since 5.2

    This property holds whether the drag event contains a html item.
*/

/*!
    \qmlproperty bool QtQuick::DragEvent::hasText
    \since 5.2

    This property holds whether the drag event contains a text item.
*/

/*!
    \qmlproperty bool QtQuick::DragEvent::hasUrls
    \since 5.2

    This property holds whether the drag event contains one or more url items.
*/

/*!
    \qmlproperty color QtQuick::DragEvent::colorData
    \since 5.2

    This property holds color data, if any.
*/

/*!
    \qmlproperty string QtQuick::DragEvent::html
    \since 5.2

    This property holds html data, if any.
*/

/*!
    \qmlproperty string QtQuick::DragEvent::text
    \since 5.2

    This property holds text data, if any.
*/

/*!
    \qmlproperty urllist QtQuick::DragEvent::urls
    \since 5.2

    This property holds a list of urls, if any.
*/

/*!
    \qmlproperty stringlist QtQuick::DragEvent::formats
    \since 5.2

    This property holds a list of mime type formats contained in the drag data.
*/

/*!
    \qmlmethod string QtQuick::DragEvent::getDataAsString(string format)
    \since 5.2

    Returns the data for the given \a format converted to a string. \a format should be one contained in the \l formats property.
*/

/*!
    \qmlmethod string QtQuick::DragEvent::getDataAsArrayBuffer(string format)
    \since 5.5

    Returns the data for the given \a format into an ArrayBuffer, which can
    easily be translated into a QByteArray. \a format should be one contained in the \l formats property.
*/

QObject *QQuickDropEvent::source() const
{
    if (const QQuickDragMimeData *dragMime = qobject_cast<const QQuickDragMimeData *>(event->mimeData()))
        return dragMime->source();
    else
        return event->source();
}

QStringList QQuickDropEvent::keys() const
{
    return d->getKeys(event->mimeData());
}

bool QQuickDropEvent::hasColor() const
{
    return event->mimeData()->hasColor();
}

bool QQuickDropEvent::hasHtml() const
{
    return event->mimeData()->hasHtml();
}

bool QQuickDropEvent::hasText() const
{
    return event->mimeData()->hasText();
}

bool QQuickDropEvent::hasUrls() const
{
    return event->mimeData()->hasUrls();
}

QVariant QQuickDropEvent::colorData() const
{
    return event->mimeData()->colorData();
}

QString QQuickDropEvent::html() const
{
    return event->mimeData()->html();
}

QString QQuickDropEvent::text() const
{
    return event->mimeData()->text();
}

QList<QUrl> QQuickDropEvent::urls() const
{
    return event->mimeData()->urls();
}

QStringList QQuickDropEvent::formats() const
{
    return event->mimeData()->formats();
}

void QQuickDropEvent::getDataAsString(QQmlV4Function *args)
{
    if (args->length() != 0) {
        QV4::ExecutionEngine *v4 = args->v4engine();
        QV4::Scope scope(v4);
        QV4::ScopedValue v(scope, (*args)[0]);
        QString format = v->toQString();
        QString rv = QString::fromUtf8(event->mimeData()->data(format));
        args->setReturnValue(v4->newString(rv)->asReturnedValue());
    }
}

void QQuickDropEvent::getDataAsArrayBuffer(QQmlV4Function *args)
{
    if (args->length() != 0) {
        QV4::ExecutionEngine *v4 = args->v4engine();
        QV4::Scope scope(v4);
        QV4::ScopedValue v(scope, (*args)[0]);
        const QString format = v->toQString();
        args->setReturnValue(v4->newArrayBuffer(event->mimeData()->data(format))->asReturnedValue());
    }
}

void QQuickDropEvent::acceptProposedAction(QQmlV4Function *)
{
    event->acceptProposedAction();
}

void QQuickDropEvent::accept(QQmlV4Function *args)
{
    Qt::DropAction action = event->dropAction();

    if (args->length() >= 1) {
        QV4::Scope scope(args->v4engine());
        QV4::ScopedValue v(scope, (*args)[0]);
        if (v->isInt32())
            action = Qt::DropAction(v->integerValue());
    }

    // get action from arguments.
    event->setDropAction(action);
    event->accept();
}


QT_END_NAMESPACE

#include "moc_qquickdroparea_p.cpp"
