/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 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 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "private/qdeclarativeanchors_p_p.h"

#include "qdeclarativeitem.h"
#include "private/qdeclarativeitem_p.h"

#include <qdeclarativeinfo.h>

#include <QDebug>

QT_BEGIN_NAMESPACE

//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 qreal hcenter(QGraphicsItem *i)
{
    QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i);

    qreal width = item->width();
    int iw = width;
    if (iw % 2)
        return (width + 1) / 2;
    else
        return width / 2;
}

static qreal vcenter(QGraphicsItem *i)
{
    QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i);

    qreal height = item->height();
    int ih = height;
    if (ih % 2)
        return (height + 1) / 2;
    else
        return height / 2;
}

//### const item?
//local position
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
{
    qreal ret = 0.0;
    QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(item);
    switch(anchorLine) {
    case QDeclarativeAnchorLine::Left:
        ret = item->x();
        break;
    case QDeclarativeAnchorLine::Right:
        ret = item->x() + d->width();
        break;
    case QDeclarativeAnchorLine::Top:
        ret = item->y();
        break;
    case QDeclarativeAnchorLine::Bottom:
        ret = item->y() + d->height();
        break;
    case QDeclarativeAnchorLine::HCenter:
        ret = item->x() + hcenter(item);
        break;
    case QDeclarativeAnchorLine::VCenter:
        ret = item->y() + vcenter(item);
        break;
    case QDeclarativeAnchorLine::Baseline:
        if (d->isDeclarativeItem)
            ret = item->y() + static_cast<QDeclarativeItem*>(item)->baselineOffset();
        break;
    default:
        break;
    }

    return ret;
}

//position when origin is 0,0
static qreal adjustedPosition(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
{
    qreal ret = 0.0;
    QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(item);
    switch(anchorLine) {
    case QDeclarativeAnchorLine::Left:
        ret = 0.0;
        break;
    case QDeclarativeAnchorLine::Right:
        ret = d->width();
        break;
    case QDeclarativeAnchorLine::Top:
        ret = 0.0;
        break;
    case QDeclarativeAnchorLine::Bottom:
        ret = d->height();
        break;
    case QDeclarativeAnchorLine::HCenter:
        ret = hcenter(item);
        break;
    case QDeclarativeAnchorLine::VCenter:
        ret = vcenter(item);
        break;
    case QDeclarativeAnchorLine::Baseline:
        if (d->isDeclarativeItem)
            ret = static_cast<QDeclarativeItem*>(item)->baselineOffset();
        break;
    default:
        break;
    }

    return ret;
}

QDeclarativeAnchors::QDeclarativeAnchors(QObject *parent)
  : QObject(*new QDeclarativeAnchorsPrivate(0), parent)
{
    qFatal("QDeclarativeAnchors::QDeclarativeAnchors(QObject*) called");
}

QDeclarativeAnchors::QDeclarativeAnchors(QGraphicsObject *item, QObject *parent)
  : QObject(*new QDeclarativeAnchorsPrivate(item), parent)
{
}

QDeclarativeAnchors::~QDeclarativeAnchors()
{
    Q_D(QDeclarativeAnchors);
    d->remDepend(d->fill);
    d->remDepend(d->centerIn);
    d->remDepend(d->left.item);
    d->remDepend(d->right.item);
    d->remDepend(d->top.item);
    d->remDepend(d->bottom.item);
    d->remDepend(d->vCenter.item);
    d->remDepend(d->hCenter.item);
    d->remDepend(d->baseline.item);
}

void QDeclarativeAnchorsPrivate::fillChanged()
{
    Q_Q(QDeclarativeAnchors);
    if (!fill || !isItemComplete())
        return;

    if (updatingFill < 2) {
        ++updatingFill;

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

        if (fill == item->parentItem()) {                         //child-parent
            setItemPos(QPointF(horizontalMargin, topMargin));
        } else if (fill->parentItem() == item->parentItem()) {   //siblings
            setItemPos(QPointF(fill->x()+horizontalMargin, fill->y()+topMargin));
        }
        QGraphicsItemPrivate *fillPrivate = QGraphicsItemPrivate::get(fill);
        setItemSize(QSizeF(fillPrivate->width()-leftMargin-rightMargin, fillPrivate->height()-topMargin-bottomMargin));

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

}

void QDeclarativeAnchorsPrivate::centerInChanged()
{
    Q_Q(QDeclarativeAnchors);
    if (!centerIn || fill || !isItemComplete())
        return;

    if (updatingCenterIn < 2) {
        ++updatingCenterIn;

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

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

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

void QDeclarativeAnchorsPrivate::clearItem(QGraphicsObject *item)
{
    if (!item)
        return;
    if (fill == item)
        fill = 0;
    if (centerIn == item)
        centerIn = 0;
    if (left.item == item) {
        left.item = 0;
        usedAnchors &= ~QDeclarativeAnchors::LeftAnchor;
    }
    if (right.item == item) {
        right.item = 0;
        usedAnchors &= ~QDeclarativeAnchors::RightAnchor;
    }
    if (top.item == item) {
        top.item = 0;
        usedAnchors &= ~QDeclarativeAnchors::TopAnchor;
    }
    if (bottom.item == item) {
        bottom.item = 0;
        usedAnchors &= ~QDeclarativeAnchors::BottomAnchor;
    }
    if (vCenter.item == item) {
        vCenter.item = 0;
        usedAnchors &= ~QDeclarativeAnchors::VCenterAnchor;
    }
    if (hCenter.item == item) {
        hCenter.item = 0;
        usedAnchors &= ~QDeclarativeAnchors::HCenterAnchor;
    }
    if (baseline.item == item) {
        baseline.item = 0;
        usedAnchors &= ~QDeclarativeAnchors::BaselineAnchor;
    }
}

void QDeclarativeAnchorsPrivate::addDepend(QGraphicsObject *item)
{
    if (!item)
        return;
    QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(item);
    if (itemPrivate->isDeclarativeItem) {
        QDeclarativeItemPrivate *p =
            static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(item));
        p->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
    } else if(itemPrivate->isWidget) {
        Q_Q(QDeclarativeAnchors);
        QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
        QObject::connect(widget, SIGNAL(destroyed(QObject*)), q, SLOT(_q_widgetDestroyed(QObject*)));
        QObject::connect(widget, SIGNAL(geometryChanged()), q, SLOT(_q_widgetGeometryChanged()));
    }
}

void QDeclarativeAnchorsPrivate::remDepend(QGraphicsObject *item)
{
    if (!item)
        return;
    QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(item);
    if (itemPrivate->isDeclarativeItem) {
        QDeclarativeItemPrivate *p =
            static_cast<QDeclarativeItemPrivate *>(itemPrivate);
        p->removeItemChangeListener(this, QDeclarativeItemPrivate::Geometry);
    } else if(itemPrivate->isWidget) {
        Q_Q(QDeclarativeAnchors);
        QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
        QObject::disconnect(widget, SIGNAL(destroyed(QObject*)), q, SLOT(_q_widgetDestroyed(QObject*)));
        QObject::disconnect(widget, SIGNAL(geometryChanged()), q, SLOT(_q_widgetGeometryChanged()));
    }
}

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

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

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

bool QDeclarativeAnchors::mirrored()
{
    Q_D(QDeclarativeAnchors);
    QGraphicsItemPrivate * itemPrivate = QGraphicsItemPrivate::get(d->item);
    return itemPrivate->isDeclarativeItem ? static_cast<QDeclarativeItemPrivate *>(itemPrivate)->effectiveLayoutMirror : false;
}

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

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

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

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

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

void QDeclarativeAnchorsPrivate::setItemSize(const QSizeF &v)
{
    updatingMe = true;
    if(QGraphicsItemPrivate::get(item)->isWidget)
        static_cast<QGraphicsWidget *>(item)->resize(v);
    else if (QGraphicsItemPrivate::get(item)->isDeclarativeItem)
        static_cast<QDeclarativeItem *>(item)->setSize(v);
    updatingMe = false;
}

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

    fillChanged();
    centerInChanged();
    updateHorizontalAnchors();
    updateVerticalAnchors();
}

void QDeclarativeAnchorsPrivate::updateOnComplete()
{
    fillChanged();
    centerInChanged();
    updateHorizontalAnchors();
    updateVerticalAnchors();
}

void QDeclarativeAnchorsPrivate::_q_widgetDestroyed(QObject *obj)
{
    clearItem(qobject_cast<QGraphicsObject*>(obj));
}

void QDeclarativeAnchorsPrivate::_q_widgetGeometryChanged()
{
    fillChanged();
    centerInChanged();
    updateHorizontalAnchors();
    updateVerticalAnchors();
}

void QDeclarativeAnchorsPrivate::itemGeometryChanged(QDeclarativeItem *, const QRectF &newG, const QRectF &oldG)
{
    fillChanged();
    centerInChanged();
    if (newG.x() != oldG.x() || newG.width() != oldG.width())
        updateHorizontalAnchors();
    if (newG.y() != oldG.y() || newG.height() != oldG.height())
        updateVerticalAnchors();
}

QGraphicsObject *QDeclarativeAnchors::fill() const
{
    Q_D(const QDeclarativeAnchors);
    return d->fill;
}

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

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

void QDeclarativeAnchors::resetFill()
{
    setFill(0);
}

QGraphicsObject *QDeclarativeAnchors::centerIn() const
{
    Q_D(const QDeclarativeAnchors);
    return d->centerIn;
}

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

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

    d->remDepend(d->centerIn);
    d->centerIn = c;
    d->addDepend(d->centerIn);
    emit centerInChanged();
    d->centerInChanged();
}

void QDeclarativeAnchors::resetCenterIn()
{
    setCenterIn(0);
}

bool QDeclarativeAnchorsPrivate::calcStretch(const QDeclarativeAnchorLine &edge1,
                                    const QDeclarativeAnchorLine &edge2,
                                    qreal offset1,
                                    qreal offset2,
                                    QDeclarativeAnchorLine::AnchorLine line,
                                    qreal &stretch)
{
    bool edge1IsParent = (edge1.item == item->parentItem());
    bool edge2IsParent = (edge2.item == item->parentItem());
    bool edge1IsSibling = (edge1.item->parentItem() == item->parentItem());
    bool edge2IsSibling = (edge2.item->parentItem() == item->parentItem());

    bool invalid = false;
    if ((edge2IsParent && edge1IsParent) || (edge2IsSibling && edge1IsSibling)) {
        stretch = (position(edge2.item, edge2.anchorLine) + offset2)
                    - (position(edge1.item, edge1.anchorLine) + offset1);
    } else if (edge2IsParent && edge1IsSibling) {
        stretch = (position(edge2.item, edge2.anchorLine) + offset2)
                    - (position(item->parentObject(), line)
                    + position(edge1.item, edge1.anchorLine) + offset1);
    } else if (edge2IsSibling && edge1IsParent) {
        stretch = (position(item->parentObject(), line) + position(edge2.item, edge2.anchorLine) + offset2)
                    - (position(edge1.item, edge1.anchorLine) + offset1);
    } else
        invalid = true;

    return invalid;
}

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

    if (updatingVerticalAnchor < 2) {
        ++updatingVerticalAnchor;
        QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item);
        if (usedAnchors & QDeclarativeAnchors::TopAnchor) {
            //Handle stretching
            bool invalid = true;
            qreal height = 0.0;
            if (usedAnchors & QDeclarativeAnchors::BottomAnchor) {
                invalid = calcStretch(top, bottom, topMargin, -bottomMargin, QDeclarativeAnchorLine::Top, height);
            } else if (usedAnchors & QDeclarativeAnchors::VCenterAnchor) {
                invalid = calcStretch(top, vCenter, topMargin, vCenterOffset, QDeclarativeAnchorLine::Top, height);
                height *= 2;
            }
            if (!invalid)
                setItemHeight(height);

            //Handle top
            if (top.item == item->parentItem()) {
                setItemY(adjustedPosition(top.item, top.anchorLine) + topMargin);
            } else if (top.item->parentItem() == item->parentItem()) {
                setItemY(position(top.item, top.anchorLine) + topMargin);
            }
        } else if (usedAnchors & QDeclarativeAnchors::BottomAnchor) {
            //Handle stretching (top + bottom case is handled above)
            if (usedAnchors & QDeclarativeAnchors::VCenterAnchor) {
                qreal height = 0.0;
                bool invalid = calcStretch(vCenter, bottom, vCenterOffset, -bottomMargin,
                                              QDeclarativeAnchorLine::Top, height);
                if (!invalid)
                    setItemHeight(height*2);
            }

            //Handle bottom
            if (bottom.item == item->parentItem()) {
                setItemY(adjustedPosition(bottom.item, bottom.anchorLine) - itemPrivate->height() - bottomMargin);
            } else if (bottom.item->parentItem() == item->parentItem()) {
                setItemY(position(bottom.item, bottom.anchorLine) - itemPrivate->height() - bottomMargin);
            }
        } else if (usedAnchors & QDeclarativeAnchors::VCenterAnchor) {
            //(stetching handled above)

            //Handle vCenter
            if (vCenter.item == item->parentItem()) {
                setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine)
                              - vcenter(item) + vCenterOffset);
            } else if (vCenter.item->parentItem() == item->parentItem()) {
                setItemY(position(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset);
            }
        } else if (usedAnchors & QDeclarativeAnchors::BaselineAnchor) {
            //Handle baseline
            if (baseline.item == item->parentItem()) {
                if (itemPrivate->isDeclarativeItem)
                    setItemY(adjustedPosition(baseline.item, baseline.anchorLine)
                        - static_cast<QDeclarativeItem *>(item)->baselineOffset() + baselineOffset);
            } else if (baseline.item->parentItem() == item->parentItem()) {
                if (itemPrivate->isDeclarativeItem)
                    setItemY(position(baseline.item, baseline.anchorLine)
                        - static_cast<QDeclarativeItem *>(item)->baselineOffset() + baselineOffset);
            }
        }
        --updatingVerticalAnchor;
    } else {
        // ### Make this certain :)
        qmlInfo(item) << QDeclarativeAnchors::tr("Possible anchor loop detected on vertical anchor.");
    }
}

inline QDeclarativeAnchorLine::AnchorLine reverseAnchorLine(QDeclarativeAnchorLine::AnchorLine anchorLine) {
    if (anchorLine == QDeclarativeAnchorLine::Left) {
        return QDeclarativeAnchorLine::Right;
    } else if (anchorLine == QDeclarativeAnchorLine::Right) {
        return QDeclarativeAnchorLine::Left;
    } else {
        return anchorLine;
    }
}

void QDeclarativeAnchorsPrivate::updateHorizontalAnchors()
{
    Q_Q(QDeclarativeAnchors);
    if (fill || centerIn || !isItemComplete())
        return;

    if (updatingHorizontalAnchor < 3) {
        ++updatingHorizontalAnchor;
        qreal effectiveRightMargin, effectiveLeftMargin, effectiveHorizontalCenterOffset;
        QDeclarativeAnchorLine effectiveLeft, effectiveRight, effectiveHorizontalCenter;
        QDeclarativeAnchors::Anchor effectiveLeftAnchor, effectiveRightAnchor;
        if (q->mirrored()) {
            effectiveLeftAnchor = QDeclarativeAnchors::RightAnchor;
            effectiveRightAnchor = QDeclarativeAnchors::LeftAnchor;
            effectiveLeft.item = right.item;
            effectiveLeft.anchorLine = reverseAnchorLine(right.anchorLine);
            effectiveRight.item = left.item;
            effectiveRight.anchorLine = reverseAnchorLine(left.anchorLine);
            effectiveHorizontalCenter.item = hCenter.item;
            effectiveHorizontalCenter.anchorLine = reverseAnchorLine(hCenter.anchorLine);
            effectiveLeftMargin = rightMargin;
            effectiveRightMargin = leftMargin;
            effectiveHorizontalCenterOffset = -hCenterOffset;
        } else {
            effectiveLeftAnchor = QDeclarativeAnchors::LeftAnchor;
            effectiveRightAnchor = QDeclarativeAnchors::RightAnchor;
            effectiveLeft = left;
            effectiveRight = right;
            effectiveHorizontalCenter = hCenter;
            effectiveLeftMargin = leftMargin;
            effectiveRightMargin = rightMargin;
            effectiveHorizontalCenterOffset = hCenterOffset;
        }

        QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item);
        if (usedAnchors & effectiveLeftAnchor) {
            //Handle stretching
            bool invalid = true;
            qreal width = 0.0;
            if (usedAnchors & effectiveRightAnchor) {
                invalid = calcStretch(effectiveLeft, effectiveRight, effectiveLeftMargin, -effectiveRightMargin, QDeclarativeAnchorLine::Left, width);
            } else if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) {
                invalid = calcStretch(effectiveLeft, effectiveHorizontalCenter, effectiveLeftMargin, effectiveHorizontalCenterOffset, QDeclarativeAnchorLine::Left, width);
                width *= 2;
            }
            if (!invalid)
                setItemWidth(width);

            //Handle left
            if (effectiveLeft.item == item->parentItem()) {
                setItemX(adjustedPosition(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin);
            } else if (effectiveLeft.item->parentItem() == item->parentItem()) {
                setItemX(position(effectiveLeft.item, effectiveLeft.anchorLine) + effectiveLeftMargin);
            }
        } else if (usedAnchors & effectiveRightAnchor) {
            //Handle stretching (left + right case is handled in updateLeftAnchor)
            if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) {
                qreal width = 0.0;
                bool invalid = calcStretch(effectiveHorizontalCenter, effectiveRight, effectiveHorizontalCenterOffset, -effectiveRightMargin,
                                              QDeclarativeAnchorLine::Left, width);
                if (!invalid)
                    setItemWidth(width*2);
            }

            //Handle right
            if (effectiveRight.item == item->parentItem()) {
                setItemX(adjustedPosition(effectiveRight.item, effectiveRight.anchorLine) - itemPrivate->width() - effectiveRightMargin);
            } else if (effectiveRight.item->parentItem() == item->parentItem()) {
                setItemX(position(effectiveRight.item, effectiveRight.anchorLine) - itemPrivate->width() - effectiveRightMargin);
            }
        } else if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) {
            //Handle hCenter
            if (effectiveHorizontalCenter.item == item->parentItem()) {
                setItemX(adjustedPosition(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset);
            } else if (effectiveHorizontalCenter.item->parentItem() == item->parentItem()) {
                setItemX(position(effectiveHorizontalCenter.item, effectiveHorizontalCenter.anchorLine) - hcenter(item) + effectiveHorizontalCenterOffset);
            }
        }
        --updatingHorizontalAnchor;
    } else {
        // ### Make this certain :)
        qmlInfo(item) << QDeclarativeAnchors::tr("Possible anchor loop detected on horizontal anchor.");
    }
}

QDeclarativeAnchorLine QDeclarativeAnchors::top() const
{
    Q_D(const QDeclarativeAnchors);
    return d->top;
}

void QDeclarativeAnchors::setTop(const QDeclarativeAnchorLine &edge)
{
    Q_D(QDeclarativeAnchors);
    if (!d->checkVAnchorValid(edge) || d->top == edge)
        return;

    d->usedAnchors |= TopAnchor;

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

    d->remDepend(d->top.item);
    d->top = edge;
    d->addDepend(d->top.item);
    emit topChanged();
    d->updateVerticalAnchors();
}

void QDeclarativeAnchors::resetTop()
{
    Q_D(QDeclarativeAnchors);
    d->usedAnchors &= ~TopAnchor;
    d->remDepend(d->top.item);
    d->top = QDeclarativeAnchorLine();
    emit topChanged();
    d->updateVerticalAnchors();
}

QDeclarativeAnchorLine QDeclarativeAnchors::bottom() const
{
    Q_D(const QDeclarativeAnchors);
    return d->bottom;
}

void QDeclarativeAnchors::setBottom(const QDeclarativeAnchorLine &edge)
{
    Q_D(QDeclarativeAnchors);
    if (!d->checkVAnchorValid(edge) || d->bottom == edge)
        return;

    d->usedAnchors |= BottomAnchor;

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

    d->remDepend(d->bottom.item);
    d->bottom = edge;
    d->addDepend(d->bottom.item);
    emit bottomChanged();
    d->updateVerticalAnchors();
}

void QDeclarativeAnchors::resetBottom()
{
    Q_D(QDeclarativeAnchors);
    d->usedAnchors &= ~BottomAnchor;
    d->remDepend(d->bottom.item);
    d->bottom = QDeclarativeAnchorLine();
    emit bottomChanged();
    d->updateVerticalAnchors();
}

QDeclarativeAnchorLine QDeclarativeAnchors::verticalCenter() const
{
    Q_D(const QDeclarativeAnchors);
    return d->vCenter;
}

void QDeclarativeAnchors::setVerticalCenter(const QDeclarativeAnchorLine &edge)
{
    Q_D(QDeclarativeAnchors);
    if (!d->checkVAnchorValid(edge) || d->vCenter == edge)
        return;

    d->usedAnchors |= VCenterAnchor;

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

    d->remDepend(d->vCenter.item);
    d->vCenter = edge;
    d->addDepend(d->vCenter.item);
    emit verticalCenterChanged();
    d->updateVerticalAnchors();
}

void QDeclarativeAnchors::resetVerticalCenter()
{
    Q_D(QDeclarativeAnchors);
    d->usedAnchors &= ~VCenterAnchor;
    d->remDepend(d->vCenter.item);
    d->vCenter = QDeclarativeAnchorLine();
    emit verticalCenterChanged();
    d->updateVerticalAnchors();
}

QDeclarativeAnchorLine QDeclarativeAnchors::baseline() const
{
    Q_D(const QDeclarativeAnchors);
    return d->baseline;
}

void QDeclarativeAnchors::setBaseline(const QDeclarativeAnchorLine &edge)
{
    Q_D(QDeclarativeAnchors);
    if (!d->checkVAnchorValid(edge) || d->baseline == edge)
        return;

    d->usedAnchors |= BaselineAnchor;

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

    d->remDepend(d->baseline.item);
    d->baseline = edge;
    d->addDepend(d->baseline.item);
    emit baselineChanged();
    d->updateVerticalAnchors();
}

void QDeclarativeAnchors::resetBaseline()
{
    Q_D(QDeclarativeAnchors);
    d->usedAnchors &= ~BaselineAnchor;
    d->remDepend(d->baseline.item);
    d->baseline = QDeclarativeAnchorLine();
    emit baselineChanged();
    d->updateVerticalAnchors();
}

QDeclarativeAnchorLine QDeclarativeAnchors::left() const
{
    Q_D(const QDeclarativeAnchors);
    return d->left;
}

void QDeclarativeAnchors::setLeft(const QDeclarativeAnchorLine &edge)
{
    Q_D(QDeclarativeAnchors);
    if (!d->checkHAnchorValid(edge) || d->left == edge)
        return;

    d->usedAnchors |= LeftAnchor;

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

    d->remDepend(d->left.item);
    d->left = edge;
    d->addDepend(d->left.item);
    emit leftChanged();
    d->updateHorizontalAnchors();
}

void QDeclarativeAnchors::resetLeft()
{
    Q_D(QDeclarativeAnchors);
    d->usedAnchors &= ~LeftAnchor;
    d->remDepend(d->left.item);
    d->left = QDeclarativeAnchorLine();
    emit leftChanged();
    d->updateHorizontalAnchors();
}

QDeclarativeAnchorLine QDeclarativeAnchors::right() const
{
    Q_D(const QDeclarativeAnchors);
    return d->right;
}

void QDeclarativeAnchors::setRight(const QDeclarativeAnchorLine &edge)
{
    Q_D(QDeclarativeAnchors);
    if (!d->checkHAnchorValid(edge) || d->right == edge)
        return;

    d->usedAnchors |= RightAnchor;

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

    d->remDepend(d->right.item);
    d->right = edge;
    d->addDepend(d->right.item);
    emit rightChanged();
    d->updateHorizontalAnchors();
}

void QDeclarativeAnchors::resetRight()
{
    Q_D(QDeclarativeAnchors);
    d->usedAnchors &= ~RightAnchor;
    d->remDepend(d->right.item);
    d->right = QDeclarativeAnchorLine();
    emit rightChanged();
    d->updateHorizontalAnchors();
}

QDeclarativeAnchorLine QDeclarativeAnchors::horizontalCenter() const
{
    Q_D(const QDeclarativeAnchors);
    return d->hCenter;
}

void QDeclarativeAnchors::setHorizontalCenter(const QDeclarativeAnchorLine &edge)
{
    Q_D(QDeclarativeAnchors);
    if (!d->checkHAnchorValid(edge) || d->hCenter == edge)
        return;

    d->usedAnchors |= HCenterAnchor;

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

    d->remDepend(d->hCenter.item);
    d->hCenter = edge;
    d->addDepend(d->hCenter.item);
    emit horizontalCenterChanged();
    d->updateHorizontalAnchors();
}

void QDeclarativeAnchors::resetHorizontalCenter()
{
    Q_D(QDeclarativeAnchors);
    d->usedAnchors &= ~HCenterAnchor;
    d->remDepend(d->hCenter.item);
    d->hCenter = QDeclarativeAnchorLine();
    emit horizontalCenterChanged();
    d->updateHorizontalAnchors();
}

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

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

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

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

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

void QDeclarativeAnchors::setMargins(qreal offset)
{
    Q_D(QDeclarativeAnchors);
    if (d->margins == offset)
        return;
    //###Is it significantly faster to set them directly so we can call fillChanged only once?
    if(!d->rightMargin || d->rightMargin == d->margins)
        setRightMargin(offset);
    if(!d->leftMargin || d->leftMargin == d->margins)
        setLeftMargin(offset);
    if(!d->topMargin || d->topMargin == d->margins)
        setTopMargin(offset);
    if(!d->bottomMargin || d->bottomMargin == d->margins)
        setBottomMargin(offset);
    d->margins = offset;
    emit marginsChanged();

}

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

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

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

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

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

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

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

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

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

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

QDeclarativeAnchors::Anchors QDeclarativeAnchors::usedAnchors() const
{
    Q_D(const QDeclarativeAnchors);
    return d->usedAnchors;
}

bool QDeclarativeAnchorsPrivate::checkHValid() const
{
    if (usedAnchors & QDeclarativeAnchors::LeftAnchor &&
        usedAnchors & QDeclarativeAnchors::RightAnchor &&
        usedAnchors & QDeclarativeAnchors::HCenterAnchor) {
        qmlInfo(item) << QDeclarativeAnchors::tr("Cannot specify left, right, and hcenter anchors.");
        return false;
    }

    return true;
}

bool QDeclarativeAnchorsPrivate::checkHAnchorValid(QDeclarativeAnchorLine anchor) const
{
    if (!anchor.item) {
        qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor to a null item.");
        return false;
    } else if (anchor.anchorLine & QDeclarativeAnchorLine::Vertical_Mask) {
        qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor a horizontal edge to a vertical edge.");
        return false;
    } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){
        qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
        return false;
    } else if (anchor.item == item) {
        qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor item to self.");
        return false;
    }

    return true;
}

bool QDeclarativeAnchorsPrivate::checkVValid() const
{
    if (usedAnchors & QDeclarativeAnchors::TopAnchor &&
        usedAnchors & QDeclarativeAnchors::BottomAnchor &&
        usedAnchors & QDeclarativeAnchors::VCenterAnchor) {
        qmlInfo(item) << QDeclarativeAnchors::tr("Cannot specify top, bottom, and vcenter anchors.");
        return false;
    } else if (usedAnchors & QDeclarativeAnchors::BaselineAnchor &&
               (usedAnchors & QDeclarativeAnchors::TopAnchor ||
                usedAnchors & QDeclarativeAnchors::BottomAnchor ||
                usedAnchors & QDeclarativeAnchors::VCenterAnchor)) {
        qmlInfo(item) << QDeclarativeAnchors::tr("Baseline anchor cannot be used in conjunction with top, bottom, or vcenter anchors.");
        return false;
    }

    return true;
}

bool QDeclarativeAnchorsPrivate::checkVAnchorValid(QDeclarativeAnchorLine anchor) const
{
    if (!anchor.item) {
        qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor to a null item.");
        return false;
    } else if (anchor.anchorLine & QDeclarativeAnchorLine::Horizontal_Mask) {
        qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor a vertical edge to a horizontal edge.");
        return false;
    } else if (anchor.item != item->parentItem() && anchor.item->parentItem() != item->parentItem()){
        qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor to an item that isn't a parent or sibling.");
        return false;
    } else if (anchor.item == item){
        qmlInfo(item) << QDeclarativeAnchors::tr("Cannot anchor item to self.");
        return false;
    }

    return true;
}

QT_END_NAMESPACE

#include <moc_qdeclarativeanchors_p.cpp>

