/****************************************************************************
**
** 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 "qquickanchors_p_p.h"

#include "qquickitem_p.h"

#include <qqmlinfo.h>

QT_BEGIN_NAMESPACE

static Q_ALWAYS_INLINE QQuickItem *readParentItem(const QQuickItem *item)
{
    return QQuickItemPrivate::get(item)->parentItem;
}

static Q_ALWAYS_INLINE qreal readX(const QQuickItem *item)
{
    return QQuickItemPrivate::get(item)->x;
}

static Q_ALWAYS_INLINE qreal readY(const QQuickItem *item)
{
    return QQuickItemPrivate::get(item)->y;
}

static Q_ALWAYS_INLINE qreal readWidth(const QQuickItem *item)
{
    return QQuickItemPrivate::get(item)->width;
}

static Q_ALWAYS_INLINE qreal readHeight(const QQuickItem *item)
{
    return QQuickItemPrivate::get(item)->height;
}

static Q_ALWAYS_INLINE qreal readBaselineOffset(const QQuickItem *item)
{
    return QQuickItemPrivate::get(item)->baselineOffset;
}

//TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)?
//TODO: support non-parent, non-sibling (need to find lowest common ancestor)

static inline qreal hcenter(const QQuickItem *item)
{
    qreal width = readWidth(item);
    if (QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors) {
        if (!QQuickAnchorsPrivate::get(anchors)->centerAligned)
            return width / 2;
    }
    int iw = width;
    if (iw % 2)
        return (width + 1) / 2;
    else
        return width / 2;
}

static inline qreal vcenter(const QQuickItem *item)
{
    qreal height = readHeight(item);
    if (QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors) {
        if (!QQuickAnchorsPrivate::get(anchors)->centerAligned)
            return height / 2;
    }
    int ih = height;
    if (ih % 2)
        return (height + 1) / 2;
    else
        return height / 2;
}

//local position
static inline qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
{
    qreal ret = 0.0;
    switch (anchorLine) {
    case QQuickAnchors::LeftAnchor:
        ret = readX(item);
        break;
    case QQuickAnchors::RightAnchor:
        ret = readX(item) + readWidth(item);
        break;
    case QQuickAnchors::TopAnchor:
        ret = readY(item);
        break;
    case QQuickAnchors::BottomAnchor:
        ret = readY(item) + readHeight(item);
        break;
    case QQuickAnchors::HCenterAnchor:
        ret = readX(item) + hcenter(item);
        break;
    case QQuickAnchors::VCenterAnchor:
        ret = readY(item) + vcenter(item);
        break;
    case QQuickAnchors::BaselineAnchor:
        ret = readY(item) + readBaselineOffset(item);
        break;
    default:
        break;
    }

    return ret;
}

//position when origin is 0,0
static inline qreal adjustedPosition(QQuickItem *item, QQuickAnchors::Anchor anchorLine)
{
    qreal ret = 0.0;
    switch (anchorLine) {
    case QQuickAnchors::LeftAnchor:
        ret = 0.0;
        break;
    case QQuickAnchors::RightAnchor:
        ret = readWidth(item);
        break;
    case QQuickAnchors::TopAnchor:
        ret = 0.0;
        break;
    case QQuickAnchors::BottomAnchor:
        ret = readHeight(item);
        break;
    case QQuickAnchors::HCenterAnchor:
        ret = hcenter(item);
        break;
    case QQuickAnchors::VCenterAnchor:
        ret = vcenter(item);
        break;
    case QQuickAnchors::BaselineAnchor:
        ret = readBaselineOffset(item);
        break;
    default:
        break;
    }

    return ret;
}

QQuickAnchors::QQuickAnchors(QQuickItem *item, QObject *parent)
: QObject(*new QQuickAnchorsPrivate(item), parent)
{
}

QQuickAnchors::~QQuickAnchors()
{
    Q_D(QQuickAnchors);
    d->inDestructor = true;
    d->remDepend(d->fill);
    d->remDepend(d->centerIn);
    d->remDepend(d->leftAnchorItem);
    d->remDepend(d->rightAnchorItem);
    d->remDepend(d->topAnchorItem);
    d->remDepend(d->bottomAnchorItem);
    d->remDepend(d->vCenterAnchorItem);
    d->remDepend(d->hCenterAnchorItem);
    d->remDepend(d->baselineAnchorItem);
}

void QQuickAnchorsPrivate::fillChanged()
{
    Q_Q(QQuickAnchors);
    if (!fill || !isItemComplete())
        return;

    if (updatingFill < 2) {
        ++updatingFill;

        qreal horizontalMargin = q->mirrored() ? rightMargin : leftMargin;

        if (fill == readParentItem(item)) {                         //child-parent
            setItemPos(QPointF(horizontalMargin, topMargin));
        } else if (readParentItem(fill) == readParentItem(item)) {   //siblings
            setItemPos(QPointF(readX(fill)+horizontalMargin, readY(fill) + topMargin));
        }
        setItemSize(QSizeF(readWidth(fill) - leftMargin - rightMargin,
                           readHeight(fill) - topMargin - bottomMargin));

        --updatingFill;
    } else {
        // ### Make this certain :)
        qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on fill.");
    }

}

void QQuickAnchorsPrivate::centerInChanged()
{
    Q_Q(QQuickAnchors);
    if (!centerIn || fill || !isItemComplete())
        return;

    if (updatingCenterIn < 2) {
        ++updatingCenterIn;

        qreal effectiveHCenterOffset = q->mirrored() ? -hCenterOffset : hCenterOffset;
        if (centerIn == readParentItem(item)) {
            QPointF p(hcenter(readParentItem(item)) - hcenter(item) + effectiveHCenterOffset,
                      vcenter(readParentItem(item)) - vcenter(item) + vCenterOffset);
            setItemPos(p);

        } else if (readParentItem(centerIn) == readParentItem(item)) {
            QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + effectiveHCenterOffset,
                      centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset);
            setItemPos(p);
        }

        --updatingCenterIn;
    } else {
        // ### Make this certain :)
        qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on centerIn.");
    }
}

void QQuickAnchorsPrivate::clearItem(QQuickItem *item)
{
    if (!item)
        return;
    if (fill == item)
        fill = nullptr;
    if (centerIn == item)
        centerIn = nullptr;
    if (leftAnchorItem == item) {
        leftAnchorItem = nullptr;
        usedAnchors &= ~QQuickAnchors::LeftAnchor;
    }
    if (rightAnchorItem == item) {
        rightAnchorItem = nullptr;
        usedAnchors &= ~QQuickAnchors::RightAnchor;
    }
    if (topAnchorItem == item) {
        topAnchorItem = nullptr;
        usedAnchors &= ~QQuickAnchors::TopAnchor;
    }
    if (bottomAnchorItem == item) {
        bottomAnchorItem = nullptr;
        usedAnchors &= ~QQuickAnchors::BottomAnchor;
    }
    if (vCenterAnchorItem == item) {
        vCenterAnchorItem = nullptr;
        usedAnchors &= ~QQuickAnchors::VCenterAnchor;
    }
    if (hCenterAnchorItem == item) {
        hCenterAnchorItem = nullptr;
        usedAnchors &= ~QQuickAnchors::HCenterAnchor;
    }
    if (baselineAnchorItem == item) {
        baselineAnchorItem = nullptr;
        usedAnchors &= ~QQuickAnchors::BaselineAnchor;
    }
}

QQuickGeometryChange QQuickAnchorsPrivate::calculateDependency(QQuickItem *controlItem) const
{
    QQuickGeometryChange dependency;

    if (!controlItem || inDestructor)
        return dependency;

    if (fill == controlItem) {
        if (controlItem == readParentItem(item))
            dependency.setSizeChange(true);
        else    //sibling
            dependency.setAllChanged(true);
        return dependency;  //exit early
    }

    if (centerIn == controlItem) {
        if (controlItem == readParentItem(item))
            dependency.setSizeChange(true);
        else    //sibling
            dependency.setAllChanged(true);
        return dependency;  //exit early
    }

    if ((usedAnchors & QQuickAnchors::LeftAnchor && leftAnchorItem == controlItem) ||
        (usedAnchors & QQuickAnchors::RightAnchor && rightAnchorItem == controlItem) ||
        (usedAnchors & QQuickAnchors::HCenterAnchor && hCenterAnchorItem == controlItem)) {
        if (controlItem == readParentItem(item))
            dependency.setWidthChange(true);
        else    //sibling
            dependency.setHorizontalChange(true);
    }

    if ((usedAnchors & QQuickAnchors::TopAnchor && topAnchorItem == controlItem) ||
        (usedAnchors & QQuickAnchors::BottomAnchor && bottomAnchorItem == controlItem) ||
        (usedAnchors & QQuickAnchors::VCenterAnchor && vCenterAnchorItem == controlItem) ||
        (usedAnchors & QQuickAnchors::BaselineAnchor && baselineAnchorItem == controlItem)) {
        if (controlItem == readParentItem(item))
            dependency.setHeightChange(true);
        else    //sibling
            dependency.setVerticalChange(true);
    }

    return dependency;
}

void QQuickAnchorsPrivate::addDepend(QQuickItem *item)
{
    if (!item || !componentComplete)
        return;

    QQuickItemPrivate *p = QQuickItemPrivate::get(item);
    p->updateOrAddGeometryChangeListener(this, calculateDependency(item));
}

void QQuickAnchorsPrivate::remDepend(QQuickItem *item)
{
    if (!item || !componentComplete)
        return;

    QQuickItemPrivate *p = QQuickItemPrivate::get(item);
    p->updateOrRemoveGeometryChangeListener(this, calculateDependency(item));
}

bool QQuickAnchors::mirrored()
{
    Q_D(QQuickAnchors);
    return QQuickItemPrivate::get(d->item)->effectiveLayoutMirror;
}

bool QQuickAnchors::alignWhenCentered() const
{
    Q_D(const QQuickAnchors);
    return d->centerAligned;
}

void QQuickAnchors::setAlignWhenCentered(bool aligned)
{
    Q_D(QQuickAnchors);
    if (aligned == d->centerAligned)
        return;
    d->centerAligned = aligned;
    emit centerAlignedChanged();
    if (d->centerIn) {
        d->centerInChanged();
    } else {
        if (d->usedAnchors & QQuickAnchors::VCenterAnchor)
            d->updateVerticalAnchors();
        else if (d->usedAnchors & QQuickAnchors::HCenterAnchor)
            d->updateHorizontalAnchors();
    }
}

bool QQuickAnchorsPrivate::isItemComplete() const
{
    return componentComplete;
}

void QQuickAnchors::classBegin()
{
    Q_D(QQuickAnchors);
    d->componentComplete = false;
}

void QQuickAnchors::componentComplete()
{
    Q_D(QQuickAnchors);
    d->componentComplete = true;
}

void QQuickAnchorsPrivate::setItemHeight(qreal v)
{
    updatingMe = true;
    item->setHeight(v);
    updatingMe = false;
}

void QQuickAnchorsPrivate::setItemWidth(qreal v)
{
    updatingMe = true;
    item->setWidth(v);
    updatingMe = false;
}

void QQuickAnchorsPrivate::setItemX(qreal v)
{
    updatingMe = true;
    item->setX(v);
    updatingMe = false;
}

void QQuickAnchorsPrivate::setItemY(qreal v)
{
    updatingMe = true;
    item->setY(v);
    updatingMe = false;
}

void QQuickAnchorsPrivate::setItemPos(const QPointF &v)
{
    updatingMe = true;
    item->setPosition(v);
    updatingMe = false;
}

void QQuickAnchorsPrivate::setItemSize(const QSizeF &v)
{
    updatingMe = true;
    item->setSize(v);
    updatingMe = false;
}

void QQuickAnchorsPrivate::updateMe()
{
    if (updatingMe) {
        updatingMe = false;
        return;
    }

    update();
}

void QQuickAnchorsPrivate::updateOnComplete()
{
    //optimization to only set initial dependencies once, at completion time
    QQuickItem *dependencies[9];
    dependencies[0] = fill;
    dependencies[1] = centerIn;
    dependencies[2] = leftAnchorItem;
    dependencies[3] = rightAnchorItem;
    dependencies[4] = hCenterAnchorItem;
    dependencies[5] = topAnchorItem;
    dependencies[6] = bottomAnchorItem;
    dependencies[7] = vCenterAnchorItem;
    dependencies[8] = baselineAnchorItem;

    std::sort(dependencies, dependencies + 9);

    QQuickItem *lastDependency = nullptr;
    for (int i = 0; i < 9; ++i) {
        QQuickItem *dependency = dependencies[i];
        if (lastDependency != dependency) {
            addDepend(dependency);
            lastDependency = dependency;
        }
    }

    update();
}


void QQuickAnchorsPrivate::update()
{
    if (!isItemComplete())
        return;

    if (fill) {
        fillChanged();
    } else if (centerIn) {
        centerInChanged();
    } else {
        if (usedAnchors & QQuickAnchors::Horizontal_Mask)
            updateHorizontalAnchors();
        if (usedAnchors & QQuickAnchors::Vertical_Mask)
            updateVerticalAnchors();
    }
}

void QQuickAnchorsPrivate::itemGeometryChanged(QQuickItem *, QQuickGeometryChange change, const QRectF &)
{
    if (!isItemComplete())
        return;

    if (fill) {
        fillChanged();
    } else if (centerIn) {
        centerInChanged();
    } else {
        if ((usedAnchors & QQuickAnchors::Horizontal_Mask) && change.horizontalChange())
            updateHorizontalAnchors();
        if ((usedAnchors & QQuickAnchors::Vertical_Mask) && change.verticalChange())
            updateVerticalAnchors();
    }
}

QQuickItem *QQuickAnchors::fill() const
{
    Q_D(const QQuickAnchors);
    return d->fill;
}

void QQuickAnchors::setFill(QQuickItem *f)
{
    Q_D(QQuickAnchors);
    if (d->fill == f)
        return;

    if (!f) {
        QQuickItem *oldFill = d->fill;
        d->fill = f;
        d->remDepend(oldFill);
        emit fillChanged();
        return;
    }
    if (f != readParentItem(d->item) && readParentItem(f) != readParentItem(d->item)){
        qmlWarning(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
        return;
    }
    QQuickItem *oldFill = d->fill;
    d->fill = f;
    d->remDepend(oldFill);
    d->addDepend(d->fill);
    emit fillChanged();
    d->fillChanged();
}

void QQuickAnchors::resetFill()
{
    setFill(nullptr);
}

QQuickItem *QQuickAnchors::centerIn() const
{
    Q_D(const QQuickAnchors);
    return d->centerIn;
}

void QQuickAnchors::setCenterIn(QQuickItem* c)
{
    Q_D(QQuickAnchors);
    if (d->centerIn == c)
        return;

    if (!c) {
        QQuickItem *oldCI = d->centerIn;
        d->centerIn = c;
        d->remDepend(oldCI);
        emit centerInChanged();
        return;
    }
    if (c != readParentItem(d->item) && readParentItem(c) != readParentItem(d->item)){
        qmlWarning(d->item) << tr("Cannot anchor to an item that isn't a parent or sibling.");
        return;
    }
    QQuickItem *oldCI = d->centerIn;
    d->centerIn = c;
    d->remDepend(oldCI);
    d->addDepend(d->centerIn);
    emit centerInChanged();
    d->centerInChanged();
}

void QQuickAnchors::resetCenterIn()
{
    setCenterIn(nullptr);
}

bool QQuickAnchorsPrivate::calcStretch(QQuickItem *edge1Item,
                                       QQuickAnchors::Anchor edge1Line,
                                       QQuickItem *edge2Item,
                                       QQuickAnchors::Anchor edge2Line,
                                       qreal offset1,
                                       qreal offset2,
                                       QQuickAnchors::Anchor line,
                                       qreal &stretch) const
{
    bool edge1IsParent = (edge1Item == readParentItem(item));
    bool edge2IsParent = (edge2Item == readParentItem(item));
    bool edge1IsSibling = (readParentItem(edge1Item) == readParentItem(item));
    bool edge2IsSibling = (readParentItem(edge2Item) == readParentItem(item));

    bool invalid = false;
    if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) {
        stretch = (position(edge2Item, edge2Line) + offset2)
                    - (position(edge1Item, edge1Line) + offset1);
    } else if (edge2IsParent && edge1IsSibling) {
        stretch = (position(edge2Item, edge2Line) + offset2)
                    - (position(readParentItem(item), line)
                    + position(edge1Item, edge1Line) + offset1);
    } else if (edge2IsSibling && edge1IsParent) {
        stretch = (position(readParentItem(item), line) + position(edge2Item, edge2Line) + offset2)
                    - (position(edge1Item, edge1Line) + offset1);
    } else
        invalid = true;

    return invalid;
}

void QQuickAnchorsPrivate::updateVerticalAnchors()
{
    if (fill || centerIn || !isItemComplete())
        return;

    if (Q_UNLIKELY(updatingVerticalAnchor > 1)) {
        // ### Make this certain :)
        qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on vertical anchor.");
        return;
    }

    ++updatingVerticalAnchor;
    if (usedAnchors & QQuickAnchors::TopAnchor) {
        //Handle stretching
        bool invalid = true;
        qreal height = 0.0;
        if (usedAnchors & QQuickAnchors::BottomAnchor) {
            invalid = calcStretch(topAnchorItem, topAnchorLine,
                                  bottomAnchorItem, bottomAnchorLine,
                                  topMargin, -bottomMargin, QQuickAnchors::TopAnchor, height);
        } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
            invalid = calcStretch(topAnchorItem, topAnchorLine,
                                  vCenterAnchorItem, vCenterAnchorLine,
                                  topMargin, vCenterOffset, QQuickAnchors::TopAnchor, height);
            height *= 2;
        }
        if (!invalid)
            setItemHeight(height);

        //Handle top
        if (topAnchorItem == readParentItem(item)) {
            setItemY(adjustedPosition(topAnchorItem, topAnchorLine) + topMargin);
        } else if (readParentItem(topAnchorItem) == readParentItem(item)) {
            setItemY(position(topAnchorItem, topAnchorLine) + topMargin);
        }
    } else if (usedAnchors & QQuickAnchors::BottomAnchor) {
        //Handle stretching (top + bottom case is handled above)
        if (usedAnchors & QQuickAnchors::VCenterAnchor) {
            qreal height = 0.0;
            bool invalid = calcStretch(vCenterAnchorItem, vCenterAnchorLine,
                                       bottomAnchorItem, bottomAnchorLine,
                                       vCenterOffset, -bottomMargin, QQuickAnchors::TopAnchor,
                                       height);
            if (!invalid)
                setItemHeight(height*2);
        }

        //Handle bottom
        if (bottomAnchorItem == readParentItem(item)) {
            setItemY(adjustedPosition(bottomAnchorItem, bottomAnchorLine) - readHeight(item) - bottomMargin);
        } else if (readParentItem(bottomAnchorItem) == readParentItem(item)) {
            setItemY(position(bottomAnchorItem, bottomAnchorLine) - readHeight(item) - bottomMargin);
        }
    } else if (usedAnchors & QQuickAnchors::VCenterAnchor) {
        //(stetching handled above)

        //Handle vCenter
        if (vCenterAnchorItem == readParentItem(item)) {
            setItemY(adjustedPosition(vCenterAnchorItem, vCenterAnchorLine)
                     - vcenter(item) + vCenterOffset);
        } else if (readParentItem(vCenterAnchorItem) == readParentItem(item)) {
            setItemY(position(vCenterAnchorItem, vCenterAnchorLine) - vcenter(item) + vCenterOffset);
        }
    } else if (usedAnchors & QQuickAnchors::BaselineAnchor) {
        //Handle baseline
        if (baselineAnchorItem == readParentItem(item)) {
            setItemY(adjustedPosition(baselineAnchorItem, baselineAnchorLine)
                     - readBaselineOffset(item) + baselineOffset);
        } else if (readParentItem(baselineAnchorItem) == readParentItem(item)) {
            setItemY(position(baselineAnchorItem, baselineAnchorLine)
                     - readBaselineOffset(item) + baselineOffset);
        }
    }
    --updatingVerticalAnchor;
}

static inline QQuickAnchors::Anchor reverseAnchorLine(QQuickAnchors::Anchor anchorLine)
{
    if (anchorLine == QQuickAnchors::LeftAnchor) {
        return QQuickAnchors::RightAnchor;
    } else if (anchorLine == QQuickAnchors::RightAnchor) {
        return QQuickAnchors::LeftAnchor;
    } else {
        return anchorLine;
    }
}

void QQuickAnchorsPrivate::updateHorizontalAnchors()
{
    Q_Q(QQuickAnchors);
    if (fill || centerIn || !isItemComplete())
        return;

    if (updatingHorizontalAnchor < 3) {
        ++updatingHorizontalAnchor;
        qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset;
        QQuickItem *effectiveLeftItem, *effectiveRightItem, *effectiveHorizontalCenterItem;
        QQuickAnchors::Anchor effectiveLeftLine, effectiveRightLine, effectiveHorizontalCenterLine;
        QQuickAnchors::Anchor effectiveLeftAnchor, effectiveRightAnchor;
        if (q->mirrored()) {
            effectiveLeftAnchor = QQuickAnchors::RightAnchor;
            effectiveRightAnchor = QQuickAnchors::LeftAnchor;
            effectiveLeftItem = rightAnchorItem;
            effectiveLeftLine = reverseAnchorLine(rightAnchorLine);
            effectiveRightItem = leftAnchorItem;
            effectiveRightLine = reverseAnchorLine(leftAnchorLine);
            effectiveHorizontalCenterItem = hCenterAnchorItem;
            effectiveHorizontalCenterLine = reverseAnchorLine(hCenterAnchorLine);
            effectiveLeftMargin = rightMargin;
            effectiveRightMargin = leftMargin;
            effectiveHorizontalCenterOffset = -hCenterOffset;
        } else {
            effectiveLeftAnchor = QQuickAnchors::LeftAnchor;
            effectiveRightAnchor = QQuickAnchors::RightAnchor;
            effectiveLeftItem = leftAnchorItem;
            effectiveLeftLine = leftAnchorLine;
            effectiveRightItem = rightAnchorItem;
            effectiveRightLine = rightAnchorLine;
            effectiveHorizontalCenterItem = hCenterAnchorItem;
            effectiveHorizontalCenterLine = hCenterAnchorLine;
            effectiveLeftMargin = leftMargin;
            effectiveRightMargin = rightMargin;
            effectiveHorizontalCenterOffset = hCenterOffset;
        }

        if (usedAnchors & effectiveLeftAnchor) {
            //Handle stretching
            bool invalid = true;
            qreal width = 0.0;
            if (usedAnchors & effectiveRightAnchor) {
                invalid = calcStretch(effectiveLeftItem, effectiveLeftLine,
                                      effectiveRightItem, effectiveRightLine,
                                      effectiveLeftMargin, -effectiveRightMargin,
                                      QQuickAnchors::LeftAnchor, width);
            } else if (usedAnchors & QQuickAnchors::HCenterAnchor) {
                invalid = calcStretch(effectiveLeftItem, effectiveLeftLine,
                                      effectiveHorizontalCenterItem, effectiveHorizontalCenterLine,
                                      effectiveLeftMargin, effectiveHorizontalCenterOffset,
                                      QQuickAnchors::LeftAnchor, width);
                width *= 2;
            }
            if (!invalid)
                setItemWidth(width);

            //Handle left
            if (effectiveLeftItem == readParentItem(item)) {
                setItemX(adjustedPosition(effectiveLeftItem, effectiveLeftLine) + effectiveLeftMargin);
            } else if (readParentItem(effectiveLeftItem) == readParentItem(item)) {
                setItemX(position(effectiveLeftItem, effectiveLeftLine) + effectiveLeftMargin);
            }
        } else if (usedAnchors & effectiveRightAnchor) {
            //Handle stretching (left + right case is handled in updateLeftAnchor)
            if (usedAnchors & QQuickAnchors::HCenterAnchor) {
                qreal width = 0.0;
                bool invalid = calcStretch(effectiveHorizontalCenterItem,
                                           effectiveHorizontalCenterLine,
                                           effectiveRightItem,  effectiveRightLine,
                                           effectiveHorizontalCenterOffset, -effectiveRightMargin,
                                           QQuickAnchors::LeftAnchor, width);
                if (!invalid)
                    setItemWidth(width*2);
            }

            //Handle right
            if (effectiveRightItem == readParentItem(item)) {
                setItemX(adjustedPosition(effectiveRightItem, effectiveRightLine)
                         - readWidth(item) - effectiveRightMargin);
            } else if (readParentItem(effectiveRightItem) == readParentItem(item)) {
                setItemX(position(effectiveRightItem, effectiveRightLine)
                         - readWidth(item) - effectiveRightMargin);
            }
        } else if (usedAnchors & QQuickAnchors::HCenterAnchor) {
            //Handle hCenter
            if (effectiveHorizontalCenterItem == readParentItem(item)) {
                setItemX(adjustedPosition(effectiveHorizontalCenterItem, effectiveHorizontalCenterLine) - hcenter(item) + effectiveHorizontalCenterOffset);
            } else if (readParentItem(effectiveHorizontalCenterItem) == readParentItem(item)) {
                setItemX(position(effectiveHorizontalCenterItem, effectiveHorizontalCenterLine) - hcenter(item) + effectiveHorizontalCenterOffset);
            }
        }
        --updatingHorizontalAnchor;
    } else {
        // ### Make this certain :)
        qmlWarning(item) << QQuickAnchors::tr("Possible anchor loop detected on horizontal anchor.");
    }
}

QQuickAnchorLine QQuickAnchors::top() const
{
    Q_D(const QQuickAnchors);
    return QQuickAnchorLine(d->topAnchorItem, d->topAnchorLine);
}

void QQuickAnchors::setTop(const QQuickAnchorLine &edge)
{
    Q_D(QQuickAnchors);
    if (!d->checkVAnchorValid(edge) ||
            (d->topAnchorItem == edge.item && d->topAnchorLine == edge.anchorLine))
        return;

    d->usedAnchors |= TopAnchor;

    if (!d->checkVValid()) {
        d->usedAnchors &= ~TopAnchor;
        return;
    }

    QQuickItem *oldTop = d->topAnchorItem;
    d->topAnchorItem = edge.item;
    d->topAnchorLine = edge.anchorLine;
    d->remDepend(oldTop);
    d->addDepend(d->topAnchorItem);
    emit topChanged();
    d->updateVerticalAnchors();
}

void QQuickAnchors::resetTop()
{
    Q_D(QQuickAnchors);
    d->usedAnchors &= ~TopAnchor;
    d->remDepend(d->topAnchorItem);
    d->topAnchorItem = nullptr;
    d->topAnchorLine = QQuickAnchors::InvalidAnchor;
    emit topChanged();
    d->updateVerticalAnchors();
}

QQuickAnchorLine QQuickAnchors::bottom() const
{
    Q_D(const QQuickAnchors);
    return QQuickAnchorLine(d->bottomAnchorItem, d->bottomAnchorLine);
}

void QQuickAnchors::setBottom(const QQuickAnchorLine &edge)
{
    Q_D(QQuickAnchors);
    if (!d->checkVAnchorValid(edge) ||
            (d->bottomAnchorItem == edge.item && d->bottomAnchorLine == edge.anchorLine))
        return;

    d->usedAnchors |= BottomAnchor;

    if (!d->checkVValid()) {
        d->usedAnchors &= ~BottomAnchor;
        return;
    }

    QQuickItem *oldBottom = d->bottomAnchorItem;
    d->bottomAnchorItem = edge.item;
    d->bottomAnchorLine = edge.anchorLine;
    d->remDepend(oldBottom);
    d->addDepend(d->bottomAnchorItem);
    emit bottomChanged();
    d->updateVerticalAnchors();
}

void QQuickAnchors::resetBottom()
{
    Q_D(QQuickAnchors);
    d->usedAnchors &= ~BottomAnchor;
    d->remDepend(d->bottomAnchorItem);
    d->bottomAnchorItem = nullptr;
    d->bottomAnchorLine = QQuickAnchors::InvalidAnchor;
    emit bottomChanged();
    d->updateVerticalAnchors();
}

QQuickAnchorLine QQuickAnchors::verticalCenter() const
{
    Q_D(const QQuickAnchors);
    return QQuickAnchorLine(d->vCenterAnchorItem, d->vCenterAnchorLine);
}

void QQuickAnchors::setVerticalCenter(const QQuickAnchorLine &edge)
{
    Q_D(QQuickAnchors);
    if (!d->checkVAnchorValid(edge) ||
            (d->vCenterAnchorItem == edge.item && d->vCenterAnchorLine == edge.anchorLine))
        return;

    d->usedAnchors |= VCenterAnchor;

    if (!d->checkVValid()) {
        d->usedAnchors &= ~VCenterAnchor;
        return;
    }

    QQuickItem *oldVCenter = d->vCenterAnchorItem;
    d->vCenterAnchorItem = edge.item;
    d->vCenterAnchorLine = edge.anchorLine;
    d->remDepend(oldVCenter);
    d->addDepend(d->vCenterAnchorItem);
    emit verticalCenterChanged();
    d->updateVerticalAnchors();
}

void QQuickAnchors::resetVerticalCenter()
{
    Q_D(QQuickAnchors);
    d->usedAnchors &= ~VCenterAnchor;
    d->remDepend(d->vCenterAnchorItem);
    d->vCenterAnchorItem = nullptr;
    d->vCenterAnchorLine = QQuickAnchors::InvalidAnchor;
    emit verticalCenterChanged();
    d->updateVerticalAnchors();
}

QQuickAnchorLine QQuickAnchors::baseline() const
{
    Q_D(const QQuickAnchors);
    return QQuickAnchorLine(d->baselineAnchorItem, d->baselineAnchorLine);
}

void QQuickAnchors::setBaseline(const QQuickAnchorLine &edge)
{
    Q_D(QQuickAnchors);
    if (!d->checkVAnchorValid(edge) ||
            (d->baselineAnchorItem == edge.item && d->baselineAnchorLine == edge.anchorLine))
        return;

    d->usedAnchors |= BaselineAnchor;

    if (!d->checkVValid()) {
        d->usedAnchors &= ~BaselineAnchor;
        return;
    }

    QQuickItem *oldBaseline = d->baselineAnchorItem;
    d->baselineAnchorItem = edge.item;
    d->baselineAnchorLine = edge.anchorLine;
    d->remDepend(oldBaseline);
    d->addDepend(d->baselineAnchorItem);
    emit baselineChanged();
    d->updateVerticalAnchors();
}

void QQuickAnchors::resetBaseline()
{
    Q_D(QQuickAnchors);
    d->usedAnchors &= ~BaselineAnchor;
    d->remDepend(d->baselineAnchorItem);
    d->baselineAnchorItem = nullptr;
    d->baselineAnchorLine = QQuickAnchors::InvalidAnchor;
    emit baselineChanged();
    d->updateVerticalAnchors();
}

QQuickAnchorLine QQuickAnchors::left() const
{
    Q_D(const QQuickAnchors);
    return QQuickAnchorLine(d->leftAnchorItem, d->leftAnchorLine);
}

void QQuickAnchors::setLeft(const QQuickAnchorLine &edge)
{
    Q_D(QQuickAnchors);
    if (!d->checkHAnchorValid(edge) ||
            (d->leftAnchorItem == edge.item && d->leftAnchorLine == edge.anchorLine))
        return;

    d->usedAnchors |= LeftAnchor;

    if (!d->checkHValid()) {
        d->usedAnchors &= ~LeftAnchor;
        return;
    }

    QQuickItem *oldLeft = d->leftAnchorItem;
    d->leftAnchorItem = edge.item;
    d->leftAnchorLine = edge.anchorLine;
    d->remDepend(oldLeft);
    d->addDepend(d->leftAnchorItem);
    emit leftChanged();
    d->updateHorizontalAnchors();
}

void QQuickAnchors::resetLeft()
{
    Q_D(QQuickAnchors);
    d->usedAnchors &= ~LeftAnchor;
    d->remDepend(d->leftAnchorItem);
    d->leftAnchorItem = nullptr;
    d->leftAnchorLine = QQuickAnchors::InvalidAnchor;
    emit leftChanged();
    d->updateHorizontalAnchors();
}

QQuickAnchorLine QQuickAnchors::right() const
{
    Q_D(const QQuickAnchors);
    return QQuickAnchorLine(d->rightAnchorItem, d->rightAnchorLine);
}

void QQuickAnchors::setRight(const QQuickAnchorLine &edge)
{
    Q_D(QQuickAnchors);
    if (!d->checkHAnchorValid(edge) ||
            (d->rightAnchorItem == edge.item && d->rightAnchorLine == edge.anchorLine))
        return;

    d->usedAnchors |= RightAnchor;

    if (!d->checkHValid()) {
        d->usedAnchors &= ~RightAnchor;
        return;
    }

    QQuickItem *oldRight = d->rightAnchorItem;
    d->rightAnchorItem = edge.item;
    d->rightAnchorLine = edge.anchorLine;
    d->remDepend(oldRight);
    d->addDepend(d->rightAnchorItem);
    emit rightChanged();
    d->updateHorizontalAnchors();
}

void QQuickAnchors::resetRight()
{
    Q_D(QQuickAnchors);
    d->usedAnchors &= ~RightAnchor;
    d->remDepend(d->rightAnchorItem);
    d->rightAnchorItem = nullptr;
    d->rightAnchorLine = QQuickAnchors::InvalidAnchor;
    emit rightChanged();
    d->updateHorizontalAnchors();
}

QQuickAnchorLine QQuickAnchors::horizontalCenter() const
{
    Q_D(const QQuickAnchors);
    return QQuickAnchorLine(d->hCenterAnchorItem, d->hCenterAnchorLine);
}

void QQuickAnchors::setHorizontalCenter(const QQuickAnchorLine &edge)
{
    Q_D(QQuickAnchors);
    if (!d->checkHAnchorValid(edge) ||
            (d->hCenterAnchorItem == edge.item && d->hCenterAnchorLine == edge.anchorLine))
        return;

    d->usedAnchors |= HCenterAnchor;

    if (!d->checkHValid()) {
        d->usedAnchors &= ~HCenterAnchor;
        return;
    }

    QQuickItem *oldHCenter = d->hCenterAnchorItem;
    d->hCenterAnchorItem = edge.item;
    d->hCenterAnchorLine = edge.anchorLine;
    d->remDepend(oldHCenter);
    d->addDepend(d->hCenterAnchorItem);
    emit horizontalCenterChanged();
    d->updateHorizontalAnchors();
}

void QQuickAnchors::resetHorizontalCenter()
{
    Q_D(QQuickAnchors);
    d->usedAnchors &= ~HCenterAnchor;
    d->remDepend(d->hCenterAnchorItem);
    d->hCenterAnchorItem = nullptr;
    d->hCenterAnchorLine = QQuickAnchors::InvalidAnchor;
    emit horizontalCenterChanged();
    d->updateHorizontalAnchors();
}

qreal QQuickAnchors::leftMargin() const
{
    Q_D(const QQuickAnchors);
    return d->leftMargin;
}

void QQuickAnchors::setLeftMargin(qreal offset)
{
    Q_D(QQuickAnchors);
    d->leftMarginExplicit = true;
    if (d->leftMargin == offset)
        return;
    d->leftMargin = offset;
    if (d->fill)
        d->fillChanged();
    else
        d->updateHorizontalAnchors();
    emit leftMarginChanged();
}

void QQuickAnchors::resetLeftMargin()
{
    Q_D(QQuickAnchors);
    d->leftMarginExplicit = false;
    if (d->leftMargin == d->margins)
        return;
    d->leftMargin = d->margins;
    if (d->fill)
        d->fillChanged();
    else
        d->updateHorizontalAnchors();
    emit leftMarginChanged();
}

qreal QQuickAnchors::rightMargin() const
{
    Q_D(const QQuickAnchors);
    return d->rightMargin;
}

void QQuickAnchors::setRightMargin(qreal offset)
{
    Q_D(QQuickAnchors);
    d->rightMarginExplicit = true;
    if (d->rightMargin == offset)
        return;
    d->rightMargin = offset;
    if (d->fill)
        d->fillChanged();
    else
        d->updateHorizontalAnchors();
    emit rightMarginChanged();
}

void QQuickAnchors::resetRightMargin()
{
    Q_D(QQuickAnchors);
    d->rightMarginExplicit = false;
    if (d->rightMargin == d->margins)
        return;
    d->rightMargin = d->margins;
    if (d->fill)
        d->fillChanged();
    else
        d->updateHorizontalAnchors();
    emit rightMarginChanged();
}

qreal QQuickAnchors::margins() const
{
    Q_D(const QQuickAnchors);
    return d->margins;
}

void QQuickAnchors::setMargins(qreal offset)
{
    Q_D(QQuickAnchors);
    if (d->margins == offset)
        return;
    d->margins = offset;

    bool updateHorizontal = false;
    bool updateVertical = false;

    if (!d->rightMarginExplicit && d->rightMargin != offset) {
        d->rightMargin = offset;
        updateHorizontal = true;
        emit rightMarginChanged();
    }
    if (!d->leftMarginExplicit && d->leftMargin != offset) {
        d->leftMargin = offset;
        updateHorizontal = true;
        emit leftMarginChanged();
    }
    if (!d->topMarginExplicit && d->topMargin != offset) {
        d->topMargin = offset;
        updateVertical = true;
        emit topMarginChanged();
    }
    if (!d->bottomMarginExplicit && d->bottomMargin != offset) {
        d->bottomMargin = offset;
        updateVertical = true;
        emit bottomMarginChanged();
    }

    if (d->fill) {
        if (updateHorizontal || updateVertical)
            d->fillChanged();
    } else {
        if (updateHorizontal)
            d->updateHorizontalAnchors();
        if (updateVertical)
            d->updateVerticalAnchors();
    }

    emit marginsChanged();
}

qreal QQuickAnchors::horizontalCenterOffset() const
{
    Q_D(const QQuickAnchors);
    return d->hCenterOffset;
}

void QQuickAnchors::setHorizontalCenterOffset(qreal offset)
{
    Q_D(QQuickAnchors);
    if (d->hCenterOffset == offset)
        return;
    d->hCenterOffset = offset;
    if (d->centerIn)
        d->centerInChanged();
    else
        d->updateHorizontalAnchors();
    emit horizontalCenterOffsetChanged();
}

qreal QQuickAnchors::topMargin() const
{
    Q_D(const QQuickAnchors);
    return d->topMargin;
}

void QQuickAnchors::setTopMargin(qreal offset)
{
    Q_D(QQuickAnchors);
    d->topMarginExplicit = true;
    if (d->topMargin == offset)
        return;
    d->topMargin = offset;
    if (d->fill)
        d->fillChanged();
    else
        d->updateVerticalAnchors();
    emit topMarginChanged();
}

void QQuickAnchors::resetTopMargin()
{
    Q_D(QQuickAnchors);
    d->topMarginExplicit = false;
    if (d->topMargin == d->margins)
        return;
    d->topMargin = d->margins;
    if (d->fill)
        d->fillChanged();
    else
        d->updateVerticalAnchors();
    emit topMarginChanged();
}

qreal QQuickAnchors::bottomMargin() const
{
    Q_D(const QQuickAnchors);
    return d->bottomMargin;
}

void QQuickAnchors::setBottomMargin(qreal offset)
{
    Q_D(QQuickAnchors);
    d->bottomMarginExplicit = true;
    if (d->bottomMargin == offset)
        return;
    d->bottomMargin = offset;
    if (d->fill)
        d->fillChanged();
    else
        d->updateVerticalAnchors();
    emit bottomMarginChanged();
}

void QQuickAnchors::resetBottomMargin()
{
    Q_D(QQuickAnchors);
    d->bottomMarginExplicit = false;
    if (d->bottomMargin == d->margins)
        return;
    d->bottomMargin = d->margins;
    if (d->fill)
        d->fillChanged();
    else
        d->updateVerticalAnchors();
    emit bottomMarginChanged();
}

qreal QQuickAnchors::verticalCenterOffset() const
{
    Q_D(const QQuickAnchors);
    return d->vCenterOffset;
}

void QQuickAnchors::setVerticalCenterOffset(qreal offset)
{
    Q_D(QQuickAnchors);
    if (d->vCenterOffset == offset)
        return;
    d->vCenterOffset = offset;
    if (d->centerIn)
        d->centerInChanged();
    else
        d->updateVerticalAnchors();
    emit verticalCenterOffsetChanged();
}

qreal QQuickAnchors::baselineOffset() const
{
    Q_D(const QQuickAnchors);
    return d->baselineOffset;
}

void QQuickAnchors::setBaselineOffset(qreal offset)
{
    Q_D(QQuickAnchors);
    if (d->baselineOffset == offset)
        return;
    d->baselineOffset = offset;
    d->updateVerticalAnchors();
    emit baselineOffsetChanged();
}

QQuickAnchors::Anchors QQuickAnchors::usedAnchors() const
{
    Q_D(const QQuickAnchors);
    return static_cast<QQuickAnchors::Anchors>(d->usedAnchors);
}

Qt::Orientations QQuickAnchors::activeDirections() const
{
    Q_D(const QQuickAnchors);
    if (d->fill || d->centerIn)
        return Qt::Horizontal | Qt::Vertical;
    Qt::Orientations o;
    if (d->usedAnchors & QQuickAnchors::Horizontal_Mask)
        o |= Qt::Horizontal;
    if (d->usedAnchors & QQuickAnchors::Vertical_Mask)
        o |= Qt::Vertical;
    return o;
}

bool QQuickAnchorsPrivate::checkHValid() const
{
    if (usedAnchors & QQuickAnchors::LeftAnchor &&
        usedAnchors & QQuickAnchors::RightAnchor &&
        usedAnchors & QQuickAnchors::HCenterAnchor) {
        qmlWarning(item) << QQuickAnchors::tr("Cannot specify left, right, and horizontalCenter anchors at the same time.");
        return false;
    }

    return true;
}

bool QQuickAnchorsPrivate::checkHAnchorValid(QQuickAnchorLine anchor) const
{
    if (!anchor.item) {
        qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to a null item.");
        return false;
    } else if (anchor.anchorLine & QQuickAnchors::Vertical_Mask) {
        qmlWarning(item) << QQuickAnchors::tr("Cannot anchor a horizontal edge to a vertical edge.");
        return false;
    } else if (anchor.item != readParentItem(item)
               && readParentItem(anchor.item) != readParentItem(item)) {
        qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
        return false;
    } else if (anchor.item == item) {
        qmlWarning(item) << QQuickAnchors::tr("Cannot anchor item to self.");
        return false;
    }

    return true;
}

bool QQuickAnchorsPrivate::checkVValid() const
{
    if (usedAnchors & QQuickAnchors::TopAnchor &&
        usedAnchors & QQuickAnchors::BottomAnchor &&
        usedAnchors & QQuickAnchors::VCenterAnchor) {
        qmlWarning(item) << QQuickAnchors::tr("Cannot specify top, bottom, and verticalCenter anchors at the same time.");
        return false;
    } else if (usedAnchors & QQuickAnchors::BaselineAnchor &&
               (usedAnchors & QQuickAnchors::TopAnchor ||
                usedAnchors & QQuickAnchors::BottomAnchor ||
                usedAnchors & QQuickAnchors::VCenterAnchor)) {
        qmlWarning(item) << QQuickAnchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or verticalCenter anchors.");
        return false;
    }

    return true;
}

bool QQuickAnchorsPrivate::checkVAnchorValid(QQuickAnchorLine anchor) const
{
    if (!anchor.item) {
        qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to a null item.");
        return false;
    } else if (anchor.anchorLine & QQuickAnchors::Horizontal_Mask) {
        qmlWarning(item) << QQuickAnchors::tr("Cannot anchor a vertical edge to a horizontal edge.");
        return false;
    } else if (anchor.item != readParentItem(item)
               && readParentItem(anchor.item) != readParentItem(item)) {
        qmlWarning(item) << QQuickAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
        return false;
    } else if (anchor.item == item){
        qmlWarning(item) << QQuickAnchors::tr("Cannot anchor item to self.");
        return false;
    }

    return true;
}

QT_END_NAMESPACE

#include <moc_qquickanchors_p.cpp>

