/****************************************************************************
**
** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved.
**
** This file is part of the Qt Designer of the Qt Toolkit.
**
** Licensees holding a valid Qt License Agreement may use this file in
** accordance with the rights, responsibilities and obligations
** contained therein.  Please consult your licensing agreement or
** contact sales@trolltech.com if any conditions of this licensing
** agreement are not clear to you.
**
** Further information about Qt licensing is available at:
** http://www.trolltech.com/products/qt/licensing.html or by
** contacting info@trolltech.com.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

#include "formbuilderextra_p.h"
#include "abstractformbuilder.h"

#include <QtCore/QVariant>
#include <QtGui/QLabel>
#include <QtCore/qdebug.h>

#ifdef QFORMINTERNAL_NAMESPACE
namespace QFormInternal {
#endif

void uiLibWarning(const QString &message) {
    qWarning("Designer: %s", qPrintable(message));
}

QFormBuilderExtra::QFormBuilderExtra() :
    m_buddyPropertyName(QLatin1String("buddy")), m_layoutWidget(false)
{
}
void QFormBuilderExtra::clear()
{
    m_buddies.clear();
    m_rootWidget = 0;
#ifndef QT_FORMBUILDER_NO_SCRIPT
    m_FormScriptRunner.clearErrors();
    m_customWidgetScriptHash.clear();
#endif
}

bool QFormBuilderExtra::applyPropertyInternally(QObject *o, const QString &propertyName, const QVariant &value)
{
    // Store buddies and apply them later on as the widgets might not exist yet.
    QLabel *label = qobject_cast<QLabel*>(o);
    if (!label || propertyName !=  m_buddyPropertyName)
        return false;

    m_buddies.insert(label, value.toString());
    return true;
}

void QFormBuilderExtra::applyInternalProperties() const
{
    if (m_buddies.empty())
        return;

    const BuddyHash::const_iterator cend = m_buddies.constEnd();
    for (BuddyHash::const_iterator it = m_buddies.constBegin(); it != cend; ++it )
        applyBuddy(it.value(), BuddyApplyAll, it.key());
}

bool QFormBuilderExtra::applyBuddy(const QString &buddyName, BuddyMode applyMode, QLabel *label)
{
    if (buddyName.isEmpty()) {
        return false;
    }

    const QWidgetList widgets = qFindChildren<QWidget*>(label->topLevelWidget(), buddyName);
    if (widgets.empty()) {
        return false;
    }

    const QWidgetList::const_iterator cend = widgets.constEnd();
    for ( QWidgetList::const_iterator it =  widgets.constBegin(); it !=  cend; ++it) {
        if (applyMode == BuddyApplyAll || !(*it)->isHidden()) {
            return true;
        }
    }

    return false;
}

const QPointer<QWidget> &QFormBuilderExtra::rootWidget() const
{
    return m_rootWidget;
}

void QFormBuilderExtra::setRootWidget(const QPointer<QWidget> &w)
{
    m_rootWidget = w;
}

#ifndef QT_FORMBUILDER_NO_SCRIPT
QFormScriptRunner &QFormBuilderExtra::formScriptRunner()
{
    return m_FormScriptRunner;
}

void QFormBuilderExtra::storeCustomWidgetScript(const QString &className, const QString &script)
{
    m_customWidgetScriptHash.insert(className, script);
}

QString QFormBuilderExtra::customWidgetScript(const QString &className) const
{
    const CustomWidgetScriptHash::const_iterator it = m_customWidgetScriptHash.constFind(className);
    if ( it == m_customWidgetScriptHash.constEnd())
        return QString();
    return it.value();
}

#endif

namespace {
    typedef QHash<const QAbstractFormBuilder *, QFormBuilderExtra *> FormBuilderPrivateHash;
}

Q_GLOBAL_STATIC(FormBuilderPrivateHash, g_FormBuilderPrivateHash)

QFormBuilderExtra *QFormBuilderExtra::instance(const QAbstractFormBuilder *afb)
{
    FormBuilderPrivateHash &fbHash = *g_FormBuilderPrivateHash();

    FormBuilderPrivateHash::iterator it = fbHash.find(afb);
    if (it == fbHash.end())
        it = fbHash.insert(afb, new QFormBuilderExtra);
    return it.value();
}

void QFormBuilderExtra::removeInstance(const QAbstractFormBuilder *afb)
{
    FormBuilderPrivateHash &fbHash = *g_FormBuilderPrivateHash();

    FormBuilderPrivateHash::iterator it = fbHash.find(afb);
    if (it != fbHash.end()) {
        delete it.value();
        fbHash.erase(it);
    }
}

void QFormBuilderExtra::setProcessingLayoutWidget(bool processing)
{
    m_layoutWidget = processing;
}

bool QFormBuilderExtra::processingLayoutWidget() const
{
    return m_layoutWidget;
}

#ifdef QFORMINTERNAL_NAMESPACE
} // namespace QFormInternal
#endif
