/*
 * Copyright (C) 2015  Ivan Romanov <drizt@land.ru>
 *
 * 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) 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 library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */

#include "abstracttreeitem.h"

#include <QDebug>

AbstractTreeItem::AbstractTreeItem(AbstractTreeItem *parent)
	: _parent(nullptr)
	, _children(AbstractTreeItemList())
{
	setParent(parent);
}

AbstractTreeItem::~AbstractTreeItem()
{
	qDeleteAll(_children);
	if (_parent)
		_parent->_children.removeOne(this);
}

void AbstractTreeItem::setRow(int row)
{
	Q_ASSERT(_parent);
	if (!_parent)
		return;

	_parent->_children.move(this->row(), row);
}

int AbstractTreeItem::row() const
{
	return _parent ? _parent->_children.indexOf(const_cast<AbstractTreeItem*>(this)) : 0;
}

void AbstractTreeItem::setParent(AbstractTreeItem *newParent)
{
	if (_parent)
		_parent->_children.removeOne(this);

	if (newParent)
		newParent->_children.append(this);

	_parent = newParent;
}

AbstractTreeItem *AbstractTreeItem::parent() const
{
	return _parent;
}

void AbstractTreeItem::insertChild(int row, AbstractTreeItem *child)
{
	Q_ASSERT(child);
	Q_ASSERT(!child->_parent);

	if (child->_parent)
		child->_parent->removeChild(child);

	child->_parent = this;
	_children.insert(row, child);
}

void AbstractTreeItem::appendChild(AbstractTreeItem *child)
{
	Q_ASSERT(child);
	Q_ASSERT(!child->_parent);

	if (child->_parent)
		child->_parent->removeChild(child);

	child->_parent = this;
	_children.append(child);
}

void AbstractTreeItem::removeChild(AbstractTreeItem *child)
{
	Q_ASSERT(child);
	Q_ASSERT(_children.contains(child));

	_children.removeOne(child);
}

AbstractTreeItem *AbstractTreeItem::child(int row) const
{
	Q_ASSERT(row < childCount());
	if (row < childCount())
		return _children.at(row);
	else
		return 0;
}

int AbstractTreeItem::childCount() const
{
	return _children.size();
}

AbstractTreeItemList AbstractTreeItem::children() const
{
	return _children;
}

void AbstractTreeItem::dump(int indent) const
{
	QString fill(indent, QLatin1Char(' '));
	qDebug() << qPrintable(fill + QLatin1String("{"));
	qDebug() << qPrintable(fill + QLatin1String(" ") + toString());
	qDebug() << qPrintable(fill + QLatin1String(" ") + QLatin1String("this")) << this;
	qDebug() << qPrintable(fill + QLatin1String(" ") + QLatin1String("parent")) << _parent;
	qDebug() << qPrintable(fill + QLatin1String(" ") + QLatin1String("children")) << _children;

	foreach (AbstractTreeItem *item, _children) {
		item->dump(indent + 1);
	}
	qDebug() << qPrintable(fill + QLatin1String("}"));
}
