/*
 * Copyright (C) 2014-2023 CZ.NIC
 *
 * 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 3 of the License, or
 * (at your option) any later version.
 *
 * 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/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#include <QTreeView>

#include "src/models/collapsible_account_proxy_model.h"

CollapsibleAccountProxyModel::CollapsibleAccountProxyModel(QObject *parent)
    : QIdentityProxyModel(parent),
    m_watchedTreeView(Q_NULLPTR),
    m_collapsedRoleBit(0)
{
}

QVariant CollapsibleAccountProxyModel::data(const QModelIndex &index,
    int role) const
{
	QAbstractItemModel *model = sourceModel();
	if (Q_UNLIKELY((Q_NULLPTR == m_watchedTreeView) || (Q_NULLPTR == model))) {
		/* Use defaults if no view or source model specified. */
		return QIdentityProxyModel::data(index, role);
	}

	/* Source index in model, index in view. */
	if ((model->rowCount(mapToSource(index)) > 0) &&
	    (!m_watchedTreeView->isExpanded(index))) {
		/*
		 * Set collapsed bit (alter the role) if source node has
		 * children and is collapsed in view.
		 */
		role |= m_collapsedRoleBit;
	}

	/* Use default implementation but with altered role. */
	return QIdentityProxyModel::data(index, role);
}

QTreeView *CollapsibleAccountProxyModel::watchedTreeView(void) const
{
	return m_watchedTreeView;
}

void CollapsibleAccountProxyModel::setWatchedTreeView(QTreeView *treeView)
{
	beginResetModel();

	if (Q_NULLPTR != m_watchedTreeView) {
		m_watchedTreeView->disconnect(SIGNAL(collapsed(QModelIndex)),
		    this, SLOT(nodeCollapsedOrExpanded(QModelIndex)));
		m_watchedTreeView->disconnect(SIGNAL(expanded(QModelIndex)),
		    this, SLOT(nodeCollapsedOrExpanded(QModelIndex)));
	}

	m_watchedTreeView = treeView;

	if (Q_NULLPTR != m_watchedTreeView) {
		connect(m_watchedTreeView, SIGNAL(collapsed(QModelIndex)),
		    this, SLOT(nodeCollapsedOrExpanded(QModelIndex)));
		connect(m_watchedTreeView, SIGNAL(expanded(QModelIndex)),
		    this, SLOT(nodeCollapsedOrExpanded(QModelIndex)));
	}

	endResetModel();
}

int CollapsibleAccountProxyModel::collapsedRoleBit(void) const
{
	return m_collapsedRoleBit;
}

void CollapsibleAccountProxyModel::setCollapsedRoleBit(int roleBit)
{
	beginResetModel();

	m_collapsedRoleBit = roleBit;

	endResetModel();
}

void CollapsibleAccountProxyModel::nodeCollapsedOrExpanded(
    const QModelIndex &index)
{
	emit dataChanged(index, index);
}
