/****************************************************************************
 ** Copyright (C) 2008-2013 Grigory A. Mozhaev <zcrendel@gmail.com>
 **
 ** This file is part of QMultiRecord (http://qt-apps.org/content/show.php?content=106254).
 **
 ** This file may be used under the terms of the GNU General Public
 ** License version 2.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 GNU
 ** General Public Licensing requirements will be met:
 ** http://www.trolltech.com/products/qt/opensource.html
 **
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 ****************************************************************************/

//! -*- coding: UTF-8 -*-
#define SOURCE_CODING "UTF-8"

#include <QtCore>

#include <QApplication>
#include <QKeyEvent>
#include <QMouseEvent>

#include "define.h"

#include "checkableitemdelegate.h"

void CheckableItemDelegate::drawCheck(QPainter *apPainter, const QStyleOptionViewItem &aOption,
                                        const QRect &, Qt::CheckState aState) const  {
    Q_ASSERT(apPainter);

    const int vTextMargin = qApp->style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
    
    QRect vCheckRect = QStyle::alignedRect(aOption.direction,  mAlignFlags,
                                           //check(aOption, aOption.rect, Qt::Checked).size()
                                           QSize(20,20),
                                           QRect(aOption.rect.x() + vTextMargin, aOption.rect.y(),
                                                 aOption.rect.width() - (vTextMargin * 2), 
                                                 aOption.rect.height()));
    
    //QItemDelegate::drawCheck(apPainter, aOption, vCheckRect, aState);
    NoFocusItemDelegate::drawCheck(apPainter, aOption, vCheckRect, aState);
}

bool CheckableItemDelegate::editorEvent(QEvent *apEvent, QAbstractItemModel *apModel, const QStyleOptionViewItem &aOption,
                                          const QModelIndex &aIndex) {
    Q_ASSERT(apEvent);
    Q_ASSERT(apModel);

    Qt::ItemFlags vFlags = apModel->flags(aIndex);

    if (!(vFlags & Qt::ItemIsUserCheckable) || !(vFlags & Qt::ItemIsEnabled))  return false;

    QVariant vValue = aIndex.data(Qt::CheckStateRole);

    if (!vValue.isValid()) return false;
    
    if (apEvent->type() == QEvent::MouseButtonRelease) {
        const int vTextMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
        QRect vCheckRect = QStyle::alignedRect(aOption.direction, Qt::AlignCenter,
                                               //check(aOption, aOption.rect, Qt::Checked).size(),
                                               QSize(20,20),
                                               QRect(aOption.rect.x() + vTextMargin, aOption.rect.y(),
                                                     aOption.rect.width() - (2 * vTextMargin), 
                                                     aOption.rect.height()));

        if (!vCheckRect.contains(static_cast<QMouseEvent*>(apEvent)->pos())) return false;

    } else if (apEvent->type() == QEvent::KeyPress) {
        if (static_cast<QKeyEvent*>(apEvent)->key() != Qt::Key_Space
            && static_cast<QKeyEvent*>(apEvent)->key() != Qt::Key_Select)
        return false;
    } else {
        return false;
    }

    Qt::CheckState vState = (static_cast<Qt::CheckState>(vValue.toInt()) == Qt::Checked
                             ? Qt::Unchecked : Qt::Checked);

    return apModel->setData(aIndex, vState, Qt::CheckStateRole);
}
/*
void CheckableItemDelegate::drawFocus(QPainter *apPainter, const QStyleOptionViewItem &aOption,
                                        const QRect &aRect) const  {
    Q_ASSERT(apPainter);
    Q_UNUSED(aRect);

    NoFocusItemDelegate::drawFocus(apPainter, aOption, aOption.rect);
}
*/
void CheckableItemDelegate::paint(QPainter * apPainter, const QStyleOptionViewItem & aOption,
                                    const QModelIndex & aIndex) const {
    Q_ASSERT(apPainter);

    NoFocusItemDelegate::paint(apPainter, aOption, aIndex);

    if (aOption.state & QStyle::State_Selected) {

        QVariant vValue = aIndex.data(Qt::CheckStateRole);

        if (!vValue.isValid()) return ;

        Qt::CheckState vState = static_cast<Qt::CheckState>(vValue.toInt());

        drawCheck(apPainter, aOption, QRect(), vState);
    }
}


