/**********************************************************************
 * 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.
 **********************************************************************/

#include "packproxymodel.h"
#include <QtDebug>
#include <util/sys/resourceloader.h>

namespace LeechCraft
{
namespace Azoth
{
namespace AdiumStyles
{
	PackProxyModel::PackProxyModel (std::shared_ptr<Util::ResourceLoader> loader, QObject *parent)
	: QStandardItemModel (parent)
	, Loader_ (loader)
	{
		const auto model = loader->GetSubElemModel ();

		connect (model,
				SIGNAL (rowsInserted (QModelIndex, int, int)),
				this,
				SLOT (handleRowsInserted (QModelIndex, int, int)));

		connect (model,
				SIGNAL (rowsAboutToBeRemoved (QModelIndex, int, int)),
				this,
				SLOT (handleRowsRemoved (QModelIndex, int, int)));

		connect (model,
				SIGNAL (modelReset ()),
				this,
				SLOT (handleModelReset ()));

		handleModelReset ();
	}

	QString PackProxyModel::GetOrigName (const QString& pack) const
	{
		const auto& our = pack.split ('/', QString::SkipEmptyParts).value (0);
		if (!OrigDatas_.contains (our))
		{
			qWarning () << Q_FUNC_INFO
					<< "orig datas don't contain"
					<< our
					<< pack;
			return our;
		}

		return our + OrigDatas_ [our].Suffix_;
	}

	QString PackProxyModel::GetVariant (const QString& pack) const
	{
		return pack.split ('/', QString::SkipEmptyParts).value (1);
	}

	namespace
	{
		void DeSuf (QString& ourName, QString& suffix)
		{
			const QStringList suffixes { ".AdiumMessageStyle" };

			for (const auto& suf : suffixes)
				if (ourName.endsWith (suf))
				{
					ourName.chop (suf.length ());
					suffix = suf;
					break;
				}
		}
	}

	void PackProxyModel::handleRowsInserted (const QModelIndex& parent, int start, int end)
	{
		for (int i = start; i <= end; ++i)
		{
			const auto& origName = Loader_->GetSubElemModel ()->
					index (i, 0, parent).data ().toString ();

			OrigData origData;

			auto ourName = origName;
			DeSuf (ourName, origData.Suffix_);

			const auto item = new QStandardItem (ourName);
			item->setData (origName);
			appendRow (item);

			OrigDatas_ [ourName] = origData;
		}
	}

	void PackProxyModel::handleRowsRemoved (const QModelIndex& parent, int start, int end)
	{
		for (int i = start; i <= end; ++i)
		{
			auto ourName = Loader_->GetSubElemModel ()->
					index (i, 0, parent).data ().toString ();

			QString suf;
			DeSuf (ourName, suf);

			for (const auto item : findItems (ourName))
				removeRow (item->row ());
		}
	}

	void PackProxyModel::handleModelReset ()
	{
		clear ();

		if (const int rc = Loader_->GetSubElemModel ()->rowCount ())
			handleRowsInserted ({}, 0, rc);
	}
}
}
}
