/****************************************************************************
**
** 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 Qt Designer 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 "qdesigner_widgetitem_p.h"
#include "qdesigner_widget_p.h"
#include "widgetfactory_p.h"

#include <QtDesigner/QDesignerFormWindowInterface>
#include <QtDesigner/QExtensionManager>
#include <QtDesigner/QDesignerFormEditorInterface>
#include <QtDesigner/QDesignerContainerExtension>
#include <QtDesigner/QDesignerWidgetDataBaseInterface>

#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QGridLayout>
#include <QtGui/QFormLayout>
#include <QtGui/QApplication>

#include <QtCore/QTextStream>
#include <QtCore/QDebug>
#include <private/qlayout_p.h>

QT_BEGIN_NAMESPACE

enum { DebugWidgetItem = 0 };
enum { MinimumLength = 10 };

// Widget item creation function to be registered as factory method with
// QLayoutPrivate
static QWidgetItem *createDesignerWidgetItem(const QLayout *layout, QWidget *widget)
{
    Qt::Orientations orientations;
    if (qdesigner_internal::QDesignerWidgetItem::check(layout, widget, &orientations)) {
        if (DebugWidgetItem)
            qDebug() << "QDesignerWidgetItem: Creating on " << layout << widget << orientations;
        return new qdesigner_internal::QDesignerWidgetItem(layout, widget, orientations);
    }
    if (DebugWidgetItem)
        qDebug() << "QDesignerWidgetItem: Noncontainer: " << layout << widget;

    return 0;
}

static QString sizePolicyToString(const QSizePolicy &p)
{
    QString rc; {
        QTextStream str(&rc);
        str << "Control=" << p.controlType() << " expdirs=" << p.expandingDirections()
            << " hasHeightForWidth=" << p.hasHeightForWidth()
            << " H: Policy=" << p.horizontalPolicy()
            << " stretch=" << p.horizontalStretch()
            << " V: Policy=" << p.verticalPolicy()
            << " stretch=" << p.verticalStretch();
    }
    return rc;
}

// Find the layout the item is contained in, recursing over
// child layouts
static const QLayout *findLayoutOfItem(const QLayout *haystack, const QLayoutItem *needle)
{
    const int count = haystack->count();
    for (int i = 0; i < count; i++) {
        QLayoutItem *item = haystack->itemAt(i);
        if (item == needle)
            return haystack;
        if (QLayout *childLayout =  item->layout())
            if (const QLayout *containing = findLayoutOfItem(childLayout, needle))
                return containing;
    }
    return 0;
}


namespace qdesigner_internal {

// ------------------ QDesignerWidgetItem
QDesignerWidgetItem::QDesignerWidgetItem(const QLayout *containingLayout, QWidget *w, Qt::Orientations o) :
    QWidgetItemV2(w),
    m_orientations(o),
    m_nonLaidOutMinSize(w->minimumSizeHint()),
    m_nonLaidOutSizeHint(w->sizeHint()),
    m_cachedContainingLayout(containingLayout)
{
    // Initialize the minimum size to prevent nonlaid-out frames/widgets
    // from being slammed to zero
    const QSize minimumSize = w->minimumSize();
    if (!minimumSize.isEmpty())
        m_nonLaidOutMinSize = minimumSize;
    expand(&m_nonLaidOutMinSize);
    expand(&m_nonLaidOutSizeHint);
    w->installEventFilter(this);
    connect(containingLayout, SIGNAL(destroyed()), this, SLOT(layoutChanged()));
    if (DebugWidgetItem )
        qDebug() << "QDesignerWidgetItem"  << w <<  sizePolicyToString(w->sizePolicy()) << m_nonLaidOutMinSize << m_nonLaidOutSizeHint;
}

void QDesignerWidgetItem::expand(QSize *s) const
{
    // Expand the size if its too small
    if (m_orientations & Qt::Horizontal && s->width() <= 0)
        s->setWidth(MinimumLength);
    if (m_orientations & Qt::Vertical && s->height() <= 0)
        s->setHeight(MinimumLength);
}

QSize QDesignerWidgetItem::minimumSize() const
{
    // Just track the size in case we are laid-out or stretched.
    const QSize baseMinSize = QWidgetItemV2::minimumSize();
    QWidget * w = constWidget();
    if (w->layout() || subjectToStretch(containingLayout(), w)) {
        m_nonLaidOutMinSize = baseMinSize;
        return baseMinSize;
    }
    // Nonlaid out: Maintain last laid-out size
    const QSize rc = baseMinSize.expandedTo(m_nonLaidOutMinSize);
    if (DebugWidgetItem > 1)
         qDebug() << "minimumSize" << constWidget() <<  baseMinSize << rc;
    return rc;
}

QSize QDesignerWidgetItem::sizeHint()    const
{
    // Just track the size in case we are laid-out or stretched.
    const QSize baseSizeHint = QWidgetItemV2::sizeHint();
    QWidget * w = constWidget();
    if (w->layout() || subjectToStretch(containingLayout(), w)) {
        m_nonLaidOutSizeHint = baseSizeHint;
        return baseSizeHint;
    }
    // Nonlaid out: Maintain last laid-out size
    const QSize rc = baseSizeHint.expandedTo(m_nonLaidOutSizeHint);
    if (DebugWidgetItem > 1)
        qDebug() << "sizeHint" << constWidget() << baseSizeHint << rc;
    return rc;
}

bool QDesignerWidgetItem::subjectToStretch(const QLayout *layout, QWidget *w)
{
    if (!layout)
        return false;
    // Are we under some stretch factor?
    if (const QBoxLayout *bl = qobject_cast<const QBoxLayout *>(layout)) {
        const int index = bl->indexOf(w);
        Q_ASSERT(index != -1);
        return bl->stretch(index) != 0;
    }
    if (const QGridLayout *cgl = qobject_cast<const QGridLayout *>(layout)) {
        QGridLayout *gl = const_cast<QGridLayout *>(cgl);
        const int index = cgl->indexOf(w);
        Q_ASSERT(index != -1);
        int row, column, rowSpan, columnSpan;
        gl->getItemPosition (index, &row, &column, &rowSpan, &columnSpan);
        const int rend = row + rowSpan;
        const int cend = column + columnSpan;
        for (int r = row; r < rend; r++)
            if (cgl->rowStretch(r) != 0)
                return true;
        for (int c = column; c < cend; c++)
            if (cgl->columnStretch(c) != 0)
                return true;
    }
    return false;
}

/* Return the orientations mask for a layout, specifying
 * in which directions squeezing should be prevented. */
static Qt::Orientations layoutOrientation(const QLayout *layout)
{
    if (const QBoxLayout *bl = qobject_cast<const QBoxLayout *>(layout)) {
        const QBoxLayout::Direction direction = bl->direction();
        return direction == QBoxLayout::LeftToRight || direction == QBoxLayout::RightToLeft ? Qt::Horizontal : Qt::Vertical;
    }
    if (qobject_cast<const QFormLayout*>(layout))
        return  Qt::Vertical;
    return Qt::Horizontal|Qt::Vertical;
}

// Check for a non-container extension container
bool  QDesignerWidgetItem::isContainer(const QDesignerFormEditorInterface *core, QWidget *w)
{
    if (!WidgetFactory::isFormEditorObject(w))
        return false;
    const QDesignerWidgetDataBaseInterface *wdb = core->widgetDataBase();
    const int widx = wdb->indexOfObject(w);
    if (widx == -1 || !wdb->item(widx)->isContainer())
        return false;
    if (qt_extension<QDesignerContainerExtension*>(core->extensionManager(), w))
        return false;
    return true;
}

bool QDesignerWidgetItem::check(const QLayout *layout, QWidget *w, Qt::Orientations *ptrToOrientations)
{
    // Check for form-editor non-containerextension-containers (QFrame, etc)
    // within laid-out form editor widgets. No check for managed() here as we
    // want container pages and widgets in the process of being morphed as
    // well. Avoid nested layouts (as the effective stretch cannot be easily
    // computed and may mess things up). Won't work for Q3 Group boxes.
    if (ptrToOrientations)
        *ptrToOrientations = 0;

    const QObject *layoutParent = layout->parent();
    if (!layoutParent || !layoutParent->isWidgetType() || !WidgetFactory::isFormEditorObject(layoutParent))
        return false;

    QDesignerFormWindowInterface *fw = QDesignerFormWindowInterface::findFormWindow(w);
    if (!fw || !isContainer(fw->core(), w))
        return false;

    // If it is a box, restrict to its orientation
    if (ptrToOrientations)
        *ptrToOrientations = layoutOrientation(layout);

    return true;
}

QSize QDesignerWidgetItem::nonLaidOutMinSize() const
{
    return m_nonLaidOutMinSize;
}

void QDesignerWidgetItem::setNonLaidOutMinSize(const QSize &s)
{
    if (DebugWidgetItem > 1)
        qDebug() << "setNonLaidOutMinSize" << constWidget() << s;
    m_nonLaidOutMinSize = s;
}

QSize QDesignerWidgetItem::nonLaidOutSizeHint() const
{
    return m_nonLaidOutSizeHint;
}

void QDesignerWidgetItem::setNonLaidOutSizeHint(const QSize &s)
{
    if (DebugWidgetItem > 1)
        qDebug() << "setNonLaidOutSizeHint" << constWidget() << s;
    m_nonLaidOutSizeHint = s;
}

void QDesignerWidgetItem::install()
{
    QLayoutPrivate::widgetItemFactoryMethod = createDesignerWidgetItem;
}

void QDesignerWidgetItem::deinstall()
{
    QLayoutPrivate::widgetItemFactoryMethod = 0;
}

const QLayout *QDesignerWidgetItem::containingLayout() const
{
    if (!m_cachedContainingLayout) {
        if (QWidget *parentWidget = constWidget()->parentWidget())
            if (QLayout *parentLayout = parentWidget->layout()) {
                m_cachedContainingLayout = findLayoutOfItem(parentLayout, this);
                if (m_cachedContainingLayout)
                    connect(m_cachedContainingLayout, SIGNAL(destroyed()), this, SLOT(layoutChanged()));
            }
        if (DebugWidgetItem)
            qDebug() << Q_FUNC_INFO << " found " << m_cachedContainingLayout << " after reparenting " << constWidget();
    }
    return m_cachedContainingLayout;
}

void QDesignerWidgetItem::layoutChanged()        
{
    if (DebugWidgetItem)
        qDebug() << Q_FUNC_INFO;
    m_cachedContainingLayout = 0;
}

bool QDesignerWidgetItem::eventFilter(QObject * /* watched */, QEvent *event)
{    
    if (event->type() == QEvent::ParentChange)
        layoutChanged();
    return false;
}

// ------------------   QDesignerWidgetItemInstaller

int QDesignerWidgetItemInstaller::m_instanceCount = 0;

QDesignerWidgetItemInstaller::QDesignerWidgetItemInstaller()
{
    if (m_instanceCount++ == 0) {
        if (DebugWidgetItem)
            qDebug() << "QDesignerWidgetItemInstaller: installing";
        QDesignerWidgetItem::install();
    }
}

QDesignerWidgetItemInstaller::~QDesignerWidgetItemInstaller()
{
    if (--m_instanceCount == 0) {
        if (DebugWidgetItem)
            qDebug() << "QDesignerWidgetItemInstaller: deinstalling";
        QDesignerWidgetItem::deinstall();
    }
}

}

QT_END_NAMESPACE
