/****************************************************************************
**
** 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 QtSCriptTools 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 "qscriptdebuggerlocalswidget_p.h"
#include "qscriptdebuggerlocalswidgetinterface_p_p.h"
#include "qscriptdebuggerlocalsmodel_p.h"
#include "qscriptcompletionproviderinterface_p.h"
#include "qscriptcompletiontaskinterface_p.h"

#include <QtCore/qdebug.h>
#include <QtGui/qheaderview.h>
#include <QtGui/qcompleter.h>
#include <QtGui/qstringlistmodel.h>
#include <QtGui/qtreeview.h>
#include <QtGui/qboxlayout.h>
#include <QtGui/qsortfilterproxymodel.h>
#include <QtGui/qlineedit.h>
#include <QtGui/qstyleditemdelegate.h>
#include <QtGui/qevent.h>
#include <QtGui/qmessagebox.h>
#include <QtScript/qscriptengine.h>

QT_BEGIN_NAMESPACE

namespace {

class CustomProxyModel : public QSortFilterProxyModel
{
public:
    CustomProxyModel(QObject *parent = 0)
        : QSortFilterProxyModel(parent) {}

    bool hasChildren(const QModelIndex &parent) const
    {
        if (!sourceModel())
            return false;
        QModelIndex sourceParent = mapToSource(parent);
        if (parent.isValid() && !sourceParent.isValid())
            return false;
        return sourceModel()->hasChildren(sourceParent);
    }
};

} // namespace

class QScriptDebuggerLocalsWidgetPrivate
    : public QScriptDebuggerLocalsWidgetInterfacePrivate
{
    Q_DECLARE_PUBLIC(QScriptDebuggerLocalsWidget)
public:
    QScriptDebuggerLocalsWidgetPrivate();
    ~QScriptDebuggerLocalsWidgetPrivate();

    void complete(QLineEdit *le);

    // private slots
    void _q_onCompletionTaskFinished();
    void _q_insertCompletion(const QString &text);
    void _q_expandIndex(const QModelIndex &index);

    QTreeView *view;
    QPointer<QLineEdit> completingEditor;
    QCompleter *completer;
    CustomProxyModel *proxy;
};

QScriptDebuggerLocalsWidgetPrivate::QScriptDebuggerLocalsWidgetPrivate()
{
    completingEditor = 0;
    completer = 0;
    proxy = 0;
}

QScriptDebuggerLocalsWidgetPrivate::~QScriptDebuggerLocalsWidgetPrivate()
{
}

void QScriptDebuggerLocalsWidgetPrivate::complete(QLineEdit *le)
{
    Q_Q(QScriptDebuggerLocalsWidget);
    QScriptCompletionTaskInterface *task = 0;
    // ### need to pass the current frame #
    task = completionProvider->createCompletionTask(
        le->text(), le->cursorPosition(),
        q->localsModel()->frameIndex(), /*options=*/0);
    QObject::connect(task, SIGNAL(finished()),
                     q, SLOT(_q_onCompletionTaskFinished()));
    completingEditor = le;
    task->start();
}

void QScriptDebuggerLocalsWidgetPrivate::_q_onCompletionTaskFinished()
{
    Q_Q(QScriptDebuggerLocalsWidget);
    QScriptCompletionTaskInterface *task = 0;
    task = qobject_cast<QScriptCompletionTaskInterface*>(q_func()->sender());
    if (!completingEditor) {
        task->deleteLater();
        return;
    }

    if (task->resultCount() == 1) {
        // do the completion right away
        QString completion = task->resultAt(0);
        completion.append(task->appendix());
        QString tmp = completingEditor->text();
        tmp.remove(task->position(), task->length());
        tmp.insert(task->position(), completion);
        completingEditor->setText(tmp);
        completingEditor = 0;
    } else if (task->resultCount() > 1) {
        // popup completion
        if (!completer) {
            completer = new QCompleter(q);
            completer->setCompletionMode(QCompleter::PopupCompletion);
            completer->setCaseSensitivity(Qt::CaseSensitive);
            completer->setWrapAround(false);
            QObject::connect(completer, SIGNAL(activated(QString)),
                             q, SLOT(_q_insertCompletion(QString)));
        }
        QStringListModel *model = qobject_cast<QStringListModel*>(completer->model());
        if (!model) {
            model = new QStringListModel(q);
            completer->setModel(model);
        }
        QStringList strings;
        for (int i = 0; i < task->resultCount(); ++i)
            strings.append(task->resultAt(i));
        model->setStringList(strings);
        QString prefix = completingEditor->text().mid(task->position(), task->length());
        completer->setCompletionPrefix(prefix);
        completingEditor->setCompleter(completer);
        // we want to handle the insertion ourselves
        QObject::disconnect(completer, 0, completingEditor, 0);
        completer->complete();
    }
    task->deleteLater();
}

void QScriptDebuggerLocalsWidgetPrivate::_q_insertCompletion(const QString &text)
{
    Q_ASSERT(completingEditor != 0);
    QString tmp = completingEditor->text();
    tmp.insert(completingEditor->cursorPosition(), text.mid(completer->completionPrefix().length()));
    completingEditor->setText(tmp);
    completingEditor = 0;
}

void QScriptDebuggerLocalsWidgetPrivate::_q_expandIndex(const QModelIndex &index)
{
    if (view->model() == index.model())
        view->expand(proxy->mapFromSource(index));
}

class QScriptDebuggerLocalsItemDelegate
    : public QStyledItemDelegate
{
    Q_OBJECT
public:
    QScriptDebuggerLocalsItemDelegate(QObject *parent = 0);

    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;

    bool eventFilter(QObject *watched, QEvent *event);

private Q_SLOTS:
    void validateInput(const QString &text)
    {
        QWidget *editor = qobject_cast<QWidget*>(sender());
        QPalette pal = editor->palette();
        QColor col;
        bool ok = (QScriptEngine::checkSyntax(text).state() == QScriptSyntaxCheckResult::Valid);
        if (ok) {
            col = Qt::white;
        } else {
            QScriptSyntaxCheckResult result = QScriptEngine::checkSyntax(
                text + QLatin1Char('\n'));
            if (result.state() == QScriptSyntaxCheckResult::Intermediate)
                col = QColor(255, 240, 192);
            else
                col = QColor(255, 102, 102);
        }
        pal.setColor(QPalette::Active, QPalette::Base, col);
        editor->setPalette(pal);
    }

private:
    static const QWidget *widget(const QStyleOptionViewItem &option)
    {
        if (const QStyleOptionViewItemV3 *v3 = qstyleoption_cast<const QStyleOptionViewItemV3 *>(&option))
            return v3->widget;
        return 0;
    }
};

QScriptDebuggerLocalsItemDelegate::QScriptDebuggerLocalsItemDelegate(
    QObject *parent)
    : QStyledItemDelegate(parent)
{
}

QWidget *QScriptDebuggerLocalsItemDelegate::createEditor(
    QWidget *parent, const QStyleOptionViewItem &option,
    const QModelIndex &index) const
{
    QWidget *editor = QStyledItemDelegate::createEditor(parent, option, index);
    if (index.column() == 1) {
        // value
        QLineEdit *le = qobject_cast<QLineEdit*>(editor);
        if (le) {
            QObject::connect(le, SIGNAL(textEdited(QString)),
                             this, SLOT(validateInput(QString)));
        }
    }
    return editor;
}

bool QScriptDebuggerLocalsItemDelegate::eventFilter(QObject *watched, QEvent *event)
{
    QLineEdit *le = qobject_cast<QLineEdit*>(watched);
    if (!le)
        return QStyledItemDelegate::eventFilter(watched, event);

    QScriptDebuggerLocalsWidget *localsWidget = qobject_cast<QScriptDebuggerLocalsWidget*>(parent());
    Q_ASSERT(localsWidget != 0);
    QScriptDebuggerLocalsWidgetPrivate *lvp =
        reinterpret_cast<QScriptDebuggerLocalsWidgetPrivate*>(
            QScriptDebuggerLocalsWidgetPrivate::get(localsWidget));

    if ((event->type() == QEvent::FocusIn) && lvp->completingEditor) {
        // because QLineEdit insists on being difficult...
        return true;
    }

    if (event->type() != QEvent::KeyPress)
        return QStyledItemDelegate::eventFilter(watched, event);
    QKeyEvent *ke = static_cast<QKeyEvent*>(event);
    if ((ke->key() == Qt::Key_Enter) || (ke->key() == Qt::Key_Return)) {
        if (QScriptEngine::checkSyntax(le->text()).state() != QScriptSyntaxCheckResult::Valid) {
            // ignore when script contains syntax error
            return true;
        }
    }
    if (ke->key() != Qt::Key_Tab)
        return QStyledItemDelegate::eventFilter(watched, event);

    // trigger completion
    lvp->complete(le);
    return true;
}

void QScriptDebuggerLocalsItemDelegate::setModelData(
    QWidget *editor, QAbstractItemModel *model,
    const QModelIndex &index) const
{
    if (index.column() == 1) {
        // check that the syntax is OK
        QString expression = qobject_cast<QLineEdit*>(editor)->text();
        if (QScriptEngine::checkSyntax(expression).state() != QScriptSyntaxCheckResult::Valid)
            return;
    }
    QStyledItemDelegate::setModelData(editor, model, index);
}

void QScriptDebuggerLocalsItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                                              const QModelIndex &index) const
{
    QStyledItemDelegate::paint(painter, option, index);
#if 0
    QModelIndex parent = index.parent();
    if (parent.isValid()) {
        QStyledItemDelegate::paint(painter, option, index);
    } else {
        // this is a top-level item.
        const QTreeView *view = qobject_cast<const QTreeView*>(widget(option));
        Q_ASSERT(view != 0);

        QStyleOptionButton buttonOption;

        buttonOption.state = option.state;
#ifdef Q_WS_MAC
        buttonOption.state |= QStyle::State_Raised;
#endif
        buttonOption.state &= ~QStyle::State_HasFocus;

        buttonOption.rect = option.rect;
        buttonOption.palette = option.palette;
        buttonOption.features = QStyleOptionButton::None;
        view->style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter, view);

        QStyleOption branchOption;
        static const int i = 9; // ### hardcoded in qcommonstyle.cpp
        QRect r = option.rect;
        branchOption.rect = QRect(r.left() + i/2, r.top() + (r.height() - i)/2, i, i);
        branchOption.palette = option.palette;
        branchOption.state = QStyle::State_Children;

        if (view->isExpanded(index))
            branchOption.state |= QStyle::State_Open;

        view->style()->drawPrimitive(QStyle::PE_IndicatorBranch, &branchOption, painter, view);

        // draw text
        QRect textrect = QRect(r.left() + i*2, r.top(), r.width() - ((5*i)/2), r.height());
        QString text = elidedText(option.fontMetrics, textrect.width(), Qt::ElideMiddle, 
            index.data(Qt::DisplayRole).toString());
        view->style()->drawItemText(painter, textrect, Qt::AlignCenter,
                                    option.palette, view->isEnabled(), text);
    }
#endif
}

QScriptDebuggerLocalsWidget::QScriptDebuggerLocalsWidget(QWidget *parent)
    : QScriptDebuggerLocalsWidgetInterface(*new QScriptDebuggerLocalsWidgetPrivate, parent, 0)
{
    Q_D(QScriptDebuggerLocalsWidget);
    d->view = new QTreeView();
    d->view->setItemDelegate(new QScriptDebuggerLocalsItemDelegate(this));
    d->view->setEditTriggers(QAbstractItemView::DoubleClicked);
//    d->view->setEditTriggers(QAbstractItemView::NoEditTriggers);
    d->view->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked);
    d->view->setAlternatingRowColors(true);
    d->view->setSelectionBehavior(QAbstractItemView::SelectRows);
    d->view->setSortingEnabled(true);
    d->view->header()->setDefaultAlignment(Qt::AlignLeft);
//    d->view->header()->setSortIndicatorShown(true);
//    d->view->header()->setResizeMode(QHeaderView::ResizeToContents);

    QVBoxLayout *vbox = new QVBoxLayout(this);
    vbox->setMargin(0);
    vbox->addWidget(d->view);
}

QScriptDebuggerLocalsWidget::~QScriptDebuggerLocalsWidget()
{
}

/*!
  \reimp
*/
QScriptDebuggerLocalsModel *QScriptDebuggerLocalsWidget::localsModel() const
{
    Q_D(const QScriptDebuggerLocalsWidget);
    if (!d->proxy)
        return 0;
    return qobject_cast<QScriptDebuggerLocalsModel*>(d->proxy->sourceModel());
}

/*!
  \reimp
*/
void QScriptDebuggerLocalsWidget::setLocalsModel(QScriptDebuggerLocalsModel *model)
{
    Q_D(QScriptDebuggerLocalsWidget);
    if (localsModel()) {
        QObject::disconnect(localsModel(), 0, d->view, 0);
    }
    if (model) {
        QObject::connect(model, SIGNAL(scopeObjectAvailable(QModelIndex)),
                         this, SLOT(_q_expandIndex(QModelIndex)));
    }
    if (!d->proxy) {
        d->proxy = new CustomProxyModel(this);
        d->view->sortByColumn(0, Qt::AscendingOrder);
    }
    d->proxy->setSourceModel(model);
    d->view->setModel(d->proxy);
}

/*!
  \reimp
*/
void QScriptDebuggerLocalsWidget::expand(const QModelIndex &index)
{
    Q_D(QScriptDebuggerLocalsWidget);
    d->view->expand(index);
    d->view->setFirstColumnSpanned(index.row(), QModelIndex(), true);
}

QT_END_NAMESPACE

#include "qscriptdebuggerlocalswidget.moc"

#include "moc_qscriptdebuggerlocalswidget_p.cpp"
