/***************************************************************************
 *   Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org>             *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU General Public License as        *
 *   published by the Free Software Foundation; either version 2 of        *
 *   the License or (at your option) version 3 or any later version        *
 *   accepted by the membership of KDE e.V. (or its successor approved     *
 *   by the membership of KDE e.V.), which shall act as a proxy            *
 *   defined in Section 14 of version 3 of the license.                    *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include "UpdateDelegate.h"

// Qt
#include <QApplication>
#include <QtGui/QMouseEvent>
#include <QtGui/QPainter>

// KDE includes
#include <KDebug>
#include <KIcon>
#include <KIconLoader>

#define SPACING 4
#define ICON_SIZE KIconLoader::SizeSmallMedium

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

QSize UpdateDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    Q_UNUSED(index);

    QSize size;
    QFontMetrics metric = QFontMetrics(option.font);

    size.setWidth(metric.width(index.data(Qt::DisplayRole).toString()));
    size.setHeight(ICON_SIZE + SPACING);

    if (index.column() == 0) {
        const QStyle *style = QApplication::style();
        QRect rect = style->subElementRect(QStyle::SE_CheckBoxIndicator, &option);
        // Adds the icon size AND the checkbox size
        // [ x ] (icon) Text
        size.rwidth() += 4 * SPACING + ICON_SIZE + rect.width();
    }

    return size;
}

bool UpdateDelegate::editorEvent(QEvent *event,
                                 QAbstractItemModel *model,
                                 const QStyleOptionViewItem &option,
                                 const QModelIndex &index)
{
    bool setData = false;
    if (index.column() == 0 &&
        event->type() == QEvent::MouseButtonRelease) {
    }

    const QWidget *widget = 0;
    if (const QStyleOptionViewItemV4 *v4 = qstyleoption_cast<const QStyleOptionViewItemV4 *>(&option)) {
        widget = v4->widget;
    }

    QStyle *style = widget ? widget->style() : QApplication::style();

    // make sure that we have the right event type
    if ((event->type() == QEvent::MouseButtonRelease)
        || (event->type() == QEvent::MouseButtonDblClick)) {
        setData = true;
        QStyleOptionViewItemV4 viewOpt(option);
        initStyleOption(&viewOpt, index);
        QRect checkRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &viewOpt, widget);
        QMouseEvent *me = static_cast<QMouseEvent*>(event);
        if (me->button() != Qt::LeftButton || !checkRect.contains(me->pos()))
            return false;

        // eat the double click events inside the check rect
        if (event->type() == QEvent::MouseButtonDblClick)
            return true;

        setData = true;
    } else if (event->type() == QEvent::KeyPress) {
        if (static_cast<QKeyEvent*>(event)->key() == Qt::Key_Space
         || static_cast<QKeyEvent*>(event)->key() == Qt::Key_Select) {
            setData = true;
        }
    }

    if (setData) {
        return model->setData(index,
                       !index.data(Qt::CheckStateRole).toBool(),
                       Qt::CheckStateRole);
    }
    return false;
}
