/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickoverlay_p.h"
#include "qquickpopuppositioner_p_p.h"
#include "qquickpopupanchors_p.h"
#include "qquickpopupitem_p_p.h"
#include "qquickpopup_p_p.h"

#include <QtQml/qqmlinfo.h>
#include <QtQuick/private/qquickitem_p.h>

QT_BEGIN_NAMESPACE

static const QQuickItemPrivate::ChangeTypes AncestorChangeTypes = QQuickItemPrivate::Geometry
                                                                  | QQuickItemPrivate::Parent
                                                                  | QQuickItemPrivate::Children;

static const QQuickItemPrivate::ChangeTypes ItemChangeTypes = QQuickItemPrivate::Geometry
                                                             | QQuickItemPrivate::Parent;

QQuickPopupPositioner::QQuickPopupPositioner(QQuickPopup *popup)
    : m_popup(popup)
{
}

QQuickPopupPositioner::~QQuickPopupPositioner()
{
    if (m_parentItem) {
        QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes);
        removeAncestorListeners(m_parentItem->parentItem());
    }
}

QQuickPopup *QQuickPopupPositioner::popup() const
{
    return m_popup;
}

QQuickItem *QQuickPopupPositioner::parentItem() const
{
    return m_parentItem;
}

void QQuickPopupPositioner::setParentItem(QQuickItem *parent)
{
    if (m_parentItem == parent)
        return;

    if (m_parentItem) {
        QQuickItemPrivate::get(m_parentItem)->removeItemChangeListener(this, ItemChangeTypes);
        removeAncestorListeners(m_parentItem->parentItem());
    }

    m_parentItem = parent;

    if (!parent)
        return;

    QQuickItemPrivate::get(parent)->addItemChangeListener(this, ItemChangeTypes);
    addAncestorListeners(parent->parentItem());
    // Store the scale property so the end result of any transition that could effect the scale
    // does not influence the top left of the final popup, so it doesn't appear to flip from one
    // position to another as a result
    m_popupScale = m_popup->popupItem()->scale();
    if (m_popup->popupItem()->isVisible())
        QQuickPopupPrivate::get(m_popup)->reposition();
}

void QQuickPopupPositioner::reposition()
{
    QQuickItem *popupItem = m_popup->popupItem();
    if (!popupItem->isVisible())
        return;

    if (m_positioning) {
        popupItem->polish();
        return;
    }

    const qreal w = popupItem->width() * m_popupScale;
    const qreal h = popupItem->height() * m_popupScale;
    const qreal iw = popupItem->implicitWidth() * m_popupScale;
    const qreal ih = popupItem->implicitHeight() * m_popupScale;

    bool widthAdjusted = false;
    bool heightAdjusted = false;
    QQuickPopupPrivate *p = QQuickPopupPrivate::get(m_popup);

    const QQuickItem *centerInParent = p->anchors ? p->getAnchors()->centerIn() : nullptr;
    const QQuickOverlay *centerInOverlay = qobject_cast<const QQuickOverlay*>(centerInParent);
    QRectF rect(!centerInParent ? p->allowHorizontalMove ? p->x : popupItem->x() : 0,
                !centerInParent ? p->allowVerticalMove ? p->y : popupItem->y() : 0,
                !p->hasWidth && iw > 0 ? iw : w,
                !p->hasHeight && ih > 0 ? ih : h);
    if (m_parentItem) {
        // m_parentItem is the parent that the popup should open in,
        // and popupItem()->parentItem() is the overlay, so the mapToItem() calls below
        // effectively map the rect to scene coordinates.
        if (centerInParent) {
            if (centerInParent != parentItem() && !centerInOverlay) {
                qmlWarning(m_popup) << "Popup can only be centered within its immediate parent or Overlay.overlay";
                return;
            }

            if (centerInOverlay) {
                rect.moveCenter(QPointF(qRound(centerInOverlay->width() / 2.0), qRound(centerInOverlay->height() / 2.0)));
            } else {
                const QPointF parentItemCenter = QPointF(qRound(m_parentItem->width() / 2), qRound(m_parentItem->height() / 2));
                rect.moveCenter(m_parentItem->mapToItem(popupItem->parentItem(), parentItemCenter));
            }
        } else {
            rect.moveTopLeft(m_parentItem->mapToItem(popupItem->parentItem(), rect.topLeft()));
        }

        if (p->window) {
            const QMarginsF margins = p->getMargins();
            QRectF bounds(qMax<qreal>(0.0, margins.left()),
                          qMax<qreal>(0.0, margins.top()),
                          p->window->width() - qMax<qreal>(0.0, margins.left()) - qMax<qreal>(0.0, margins.right()),
                          p->window->height() - qMax<qreal>(0.0, margins.top()) - qMax<qreal>(0.0, margins.bottom()));
            if (p->window->contentOrientation() == Qt::LandscapeOrientation || p->window->contentOrientation() == Qt::InvertedLandscapeOrientation)
                bounds = bounds.transposed();

            // if the popup doesn't fit horizontally inside the window, try flipping it around (left <-> right)
            if (p->allowHorizontalFlip && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
                const QRectF flipped(m_parentItem->mapToScene(QPointF(m_parentItem->width() - p->x - rect.width(), p->y)), rect.size());
                if (flipped.intersected(bounds).width() > rect.intersected(bounds).width())
                    rect.moveLeft(flipped.left());
            }

            // if the popup doesn't fit vertically inside the window, try flipping it around (above <-> below)
            if (p->allowVerticalFlip && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
                const QRectF flipped(m_parentItem->mapToScene(QPointF(p->x, m_parentItem->height() - p->y - rect.height())), rect.size());
                if (flipped.intersected(bounds).height() > rect.intersected(bounds).height())
                    rect.moveTop(flipped.top());
            }

            // push inside the margins if specified
            if (p->allowVerticalMove) {
                if (margins.top() >= 0 && rect.top() < bounds.top())
                    rect.moveTop(margins.top());
                if (margins.bottom() >= 0 && rect.bottom() > bounds.bottom())
                    rect.moveBottom(bounds.bottom());
            }
            if (p->allowHorizontalMove) {
                if (margins.left() >= 0 && rect.left() < bounds.left())
                    rect.moveLeft(margins.left());
                if (margins.right() >= 0 && rect.right() > bounds.right())
                    rect.moveRight(bounds.right());
            }

            if (iw > 0 && (rect.left() < bounds.left() || rect.right() > bounds.right())) {
                // neither the flipped or pushed geometry fits inside the window, choose
                // whichever side (left vs. right) fits larger part of the popup
                if (p->allowHorizontalMove && p->allowHorizontalFlip) {
                    if (rect.left() < bounds.left() && bounds.left() + rect.width() <= bounds.right())
                        rect.moveLeft(bounds.left());
                    else if (rect.right() > bounds.right() && bounds.right() - rect.width() >= bounds.left())
                        rect.moveRight(bounds.right());
                }

                // as a last resort, adjust the width to fit the window
                if (p->allowHorizontalResize) {
                    if (rect.left() < bounds.left()) {
                        rect.setLeft(bounds.left());
                        widthAdjusted = true;
                    }
                    if (rect.right() > bounds.right()) {
                        rect.setRight(bounds.right());
                        widthAdjusted = true;
                    }
                }
            } else if (iw > 0 && rect.left() >= bounds.left() && rect.right() <= bounds.right()
                       && iw != w) {
                // restore original width
                rect.setWidth(iw);
                widthAdjusted = true;
            }

            if (ih > 0 && (rect.top() < bounds.top() || rect.bottom() > bounds.bottom())) {
                // neither the flipped or pushed geometry fits inside the window, choose
                // whichever side (above vs. below) fits larger part of the popup
                if (p->allowVerticalMove && p->allowVerticalFlip) {
                    if (rect.top() < bounds.top() && bounds.top() + rect.height() <= bounds.bottom())
                        rect.moveTop(bounds.top());
                    else if (rect.bottom() > bounds.bottom() && bounds.bottom() - rect.height() >= bounds.top())
                        rect.moveBottom(bounds.bottom());
                }

                // as a last resort, adjust the height to fit the window
                if (p->allowVerticalResize) {
                    if (rect.top() < bounds.top()) {
                        rect.setTop(bounds.top());
                        heightAdjusted = true;
                    }
                    if (rect.bottom() > bounds.bottom()) {
                        rect.setBottom(bounds.bottom());
                        heightAdjusted = true;
                    }
                }
            } else if (ih > 0 && rect.top() >= bounds.top() && rect.bottom() <= bounds.bottom()
                       && ih != h) {
                // restore original height
                rect.setHeight(ih);
                heightAdjusted = true;
            }
        }
    }

    m_positioning = true;

    popupItem->setPosition(rect.topLeft());

    // If the popup was assigned a parent, rect will be in scene coordinates,
    // so we need to map its top left back to item coordinates.
    // However, if centering within the overlay, the coordinates will be relative
    // to the window, so we don't need to do anything.
    const QPointF effectivePos = m_parentItem && !centerInOverlay ? m_parentItem->mapFromScene(rect.topLeft()) : rect.topLeft();
    if (!qFuzzyCompare(p->effectiveX, effectivePos.x())) {
        p->effectiveX = effectivePos.x();
        emit m_popup->xChanged();
    }
    if (!qFuzzyCompare(p->effectiveY, effectivePos.y())) {
        p->effectiveY = effectivePos.y();
        emit m_popup->yChanged();
    }

    if (!p->hasWidth && widthAdjusted && rect.width() > 0)
        popupItem->setWidth(rect.width() / m_popupScale);
    if (!p->hasHeight && heightAdjusted && rect.height() > 0)
        popupItem->setHeight(rect.height() / m_popupScale);
    m_positioning = false;
}

void QQuickPopupPositioner::itemGeometryChanged(QQuickItem *, QQuickGeometryChange, const QRectF &)
{
    if (m_parentItem && m_popup->popupItem()->isVisible())
        QQuickPopupPrivate::get(m_popup)->reposition();
}

void QQuickPopupPositioner::itemParentChanged(QQuickItem *, QQuickItem *parent)
{
    addAncestorListeners(parent);
}

void QQuickPopupPositioner::itemChildRemoved(QQuickItem *item, QQuickItem *child)
{
    if (child == m_parentItem || child->isAncestorOf(m_parentItem))
        removeAncestorListeners(item);
}

void QQuickPopupPositioner::removeAncestorListeners(QQuickItem *item)
{
    if (item == m_parentItem)
        return;

    QQuickItem *p = item;
    while (p) {
        QQuickItemPrivate::get(p)->removeItemChangeListener(this, AncestorChangeTypes);
        p = p->parentItem();
    }
}

void QQuickPopupPositioner::addAncestorListeners(QQuickItem *item)
{
    if (item == m_parentItem)
        return;

    QQuickItem *p = item;
    while (p) {
        QQuickItemPrivate::get(p)->updateOrAddItemChangeListener(this, AncestorChangeTypes);
        p = p->parentItem();
    }
}

QT_END_NAMESPACE
