/**********************************************************************
 * LeechCraft - modular cross-platform feature rich internet client.
 * Copyright (C) 2006-2014  Georg Rudoy
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 **********************************************************************/

#pragma once

#include <memory>
#include <QModelIndex>
#include <QVector>
#include "modelsconfig.h"

namespace LeechCraft
{
namespace Util
{
	class ModelItem;

	typedef std::shared_ptr<ModelItem> ModelItem_ptr;
	typedef std::weak_ptr<ModelItem> ModelItem_wtr;
	typedef QVector<ModelItem_ptr> ModelItemsList_t;
	typedef std::shared_ptr<const ModelItem> ModelItem_cptr;

	class UTIL_MODELS_API ModelItem : public std::enable_shared_from_this<ModelItem>
	{
		ModelItem_wtr Parent_;
		ModelItemsList_t Children_;

		QAbstractItemModel * const Model_;
		QModelIndex SrcIdx_;
	public:
		typedef ModelItemsList_t::iterator iterator;
		typedef ModelItemsList_t::const_iterator const_iterator;

		ModelItem ();
		ModelItem (QAbstractItemModel *model, const QModelIndex& idx, const ModelItem_wtr& parent);

		iterator begin ();
		iterator end ();
		const_iterator begin () const;
		const_iterator end () const;

		ModelItem_ptr GetChild (int row) const;
		const ModelItemsList_t& GetChildren () const;
		int GetRowCount () const;

		ModelItem* EnsureChild (int row);

		iterator EraseChild (iterator it);
		iterator EraseChildren (iterator begin, iterator end);

		template<typename... Args>
		void AppendChild (Args&&... args)
		{
			Children_ << std::make_shared<ModelItem> (std::forward<Args> (args)...);
		}

		template<typename... Args>
		void InsertChild (int pos, Args&&... args)
		{
			Children_.insert (pos, std::make_shared<ModelItem> (std::forward<Args> (args)...));
		}

		const QModelIndex& GetIndex () const;

		void RefreshIndex (int modelStartingRow);

		QAbstractItemModel* GetModel () const;

		ModelItem_ptr GetParent () const;

		int GetRow (const ModelItem_ptr& item) const;
		int GetRow (const ModelItem_cptr& item) const;
		int GetRow () const;

		ModelItem_ptr FindChild (QModelIndex index) const;
	};
}
}
