/*
 * Plasma applet to display indicators from libindicate
 *
 * Copyright 2009 Canonical Ltd.
 *
 * Authors:
 * - Aurélien Gâteau <aurelien.gateau@canonical.com>
 *
 * License: GPL v3
 */
#include "view.h"

// Qt
#include <QScrollBar>
#include <QTimer>

// KDE
#include <KDebug>

ExpandedTreeView::ExpandedTreeView(QWidget* parent)
: QTreeView(parent)
, mAdjustSizeTimer(new QTimer(this))
{
    connect(mAdjustSizeTimer, SIGNAL(timeout()), SLOT(adjustSizeTightly()));
    mAdjustSizeTimer->setSingleShot(true);
    mAdjustSizeTimer->setInterval(0);
}

/**
 * Returns the size of the smallest rect which would be big enough to fit two
 * rects of size size1 and size2 on top of each others.
 */
inline QSize stackedSize(const QSize& size1, const QSize& size2)
{
    return QSize(
        qMax(size1.width(), size2.width()),
        size1.height() + size2.height()
        );
}

QSize ExpandedTreeView::sizeHintForIndexAndChildren(const QModelIndex& parent, int depth) const
{
    QSize size(0, 0);
    for (int row = model()->rowCount(parent) - 1; row >= 0; --row) {
        QModelIndex index = model()->index(row, 0, parent);
        QSize itemSizeHint = sizeHintForIndex(index);
        itemSizeHint.rwidth() += depth * indentation();
        size = stackedSize(size, itemSizeHint);
        //kDebug() << index.data().toString() << itemSizeHint;
        if (model()->hasChildren(index)) {
            size = stackedSize(size, sizeHintForIndexAndChildren(index, depth + 1));
        }
    }
    return size;
}

QSize ExpandedTreeView::minimumSizeHint() const
{
    return sizeHintForIndexAndChildren(QModelIndex(), 0);
}

QSize ExpandedTreeView::sizeHint() const
{
    return minimumSizeHint();
}

void ExpandedTreeView::rowsInserted(const QModelIndex& parent, int start, int end)
{
    QTreeView::rowsInserted(parent, start, end);
    if (!parent.isValid()) {
        for (int row = start; row <= end; ++row) {
            setUpRootIndex(row);
        }
    }
    mAdjustSizeTimer->start();
}

void ExpandedTreeView::rowsAboutToBeRemoved(const QModelIndex& parent, int start, int end)
{
    QTreeView::rowsAboutToBeRemoved(parent, start, end);
    mAdjustSizeTimer->start();
}

void ExpandedTreeView::dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
    QTreeView::dataChanged(topLeft, bottomRight);
    mAdjustSizeTimer->start();
}

void ExpandedTreeView::reset()
{
    QTreeView::reset();
    for (int row = 0; row < model()->rowCount(); ++row) {
        setUpRootIndex(row);
    }
    mAdjustSizeTimer->start();
}

void ExpandedTreeView::drawTree(QPainter*, const QRegion&) const
{
}

void ExpandedTreeView::drawBranches(QPainter*, const QRect&, const QModelIndex&) const
{
}

void ExpandedTreeView::setUpRootIndex(int row)
{
    expand(model()->index(row, 0));
    setFirstColumnSpanned(row, QModelIndex(), true);
}

void ExpandedTreeView::adjustSizeTightly()
{
    updateGeometry();
    sizeChanged();
}

#include "view.moc"
