/**********************************************************************
 * 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 "shareriexdialog.h"
#include <QStandardItemModel>
#include <QSortFilterProxyModel>
#include "interfaces/azoth/iclentry.h"
#include "interfaces/azoth/iaccount.h"
#include "interfaces/azoth/iprotocol.h"

Q_DECLARE_METATYPE (LeechCraft::Azoth::ICLEntry*);

namespace LeechCraft
{
namespace Azoth
{
	ShareRIEXDialog::ShareRIEXDialog (ICLEntry *entry, QWidget *parent)
	: QDialog (parent)
	, Entry_ (entry)
	, Model_ (new QStandardItemModel (this))
	{
		Ui_.setupUi (this);

		const QString& name = entry->GetEntryName ();
		const QString& hrID = entry->GetHumanReadableID ();
		Ui_.MessageLabel_->setText (tr ("Select items to be shared with %1:")
					.arg (name.isEmpty () ? hrID : name + " (" + hrID + ")"));

		connect (Ui_.AllAccountsBox_,
				SIGNAL (toggled (bool)),
				this,
				SLOT (fillModel ()));

		fillModel ();

		QSortFilterProxyModel *proxy = new QSortFilterProxyModel (this);
		proxy->setSourceModel (Model_);
		Ui_.ContactsTree_->setModel (proxy);

		connect (Ui_.FilterLine_,
				SIGNAL (textChanged (const QString&)),
				proxy,
				SLOT (setFilterFixedString (const QString&)));
	}

	QList<ICLEntry*> ShareRIEXDialog::GetSelectedEntries () const
	{
		QList<ICLEntry*> result;

		for (int i = 0, iSize = Model_->rowCount ();
				i < iSize; ++i)
		{
			QStandardItem *groupItem = Model_->item (i);
			for (int j = 0, jSize = groupItem->rowCount ();
					j < jSize; ++j)
			{
				QStandardItem *entryItem = groupItem->child (j);
				if (entryItem->checkState () == Qt::Checked )
					result << entryItem->data ().value<ICLEntry*> ();
			}
		}

		return result;
	}

	QString ShareRIEXDialog::GetShareMessage () const
	{
		return Ui_.Message_->toPlainText ();
	}

	bool ShareRIEXDialog::ShouldSuggestGroups () const
	{
		return Ui_.SuggestGroupsBox_->checkState () == Qt::Checked;
	}

	namespace
	{
		QMap<QString, QList<ICLEntry*>> GetEntries (IAccount *acc)
		{
			QMap<QString, QList<ICLEntry*>> result;

			Q_FOREACH (QObject *entryObj, acc->GetCLEntries ())
			{
				ICLEntry *entry = qobject_cast<ICLEntry*> (entryObj);
				if (!entry ||
						(entry->GetEntryFeatures () & ICLEntry::FMaskLongetivity) != ICLEntry::FPermanentEntry)
					continue;

				if (entry->Groups ().isEmpty ())
					result [""] << entry;
				else
					Q_FOREACH (const QString& group, entry->Groups ())
						result [group] << entry;
			}

			return result;
		}
	}

	void ShareRIEXDialog::fillModel ()
	{
		Model_->clear ();

		Model_->setHorizontalHeaderLabels (QStringList (tr ("Name"))
						<< tr ("ID")
						<< tr ("Account")
						<< tr ("Groups"));

		IAccount *acc = qobject_cast<IAccount*> (Entry_->GetParentAccount ());

		auto entries = GetEntries (acc);
		if (Ui_.AllAccountsBox_->checkState () == Qt::Checked)
		{
			IProtocol *proto = qobject_cast<IProtocol*> (acc->GetParentProtocol ());
			Q_FOREACH (QObject *accObj, proto->GetRegisteredAccounts ())
			{
				IAccount *otherAcc = qobject_cast<IAccount*> (accObj);
				if (!otherAcc || otherAcc == acc)
					continue;

				auto others = GetEntries (otherAcc);
				Q_FOREACH (const QString& key, others.keys ())
					entries [key] << others [key];
			}
		}

		Q_FOREACH (const QString& group, entries.keys ())
		{
			const QString& title = group.isEmpty () ? tr ("General") : group;
			QStandardItem *groupItem = new QStandardItem (title);

			Q_FOREACH (ICLEntry *entry, entries [group])
			{
				QList<QStandardItem*> row;

				QStandardItem *itemName = new QStandardItem;
				itemName->setCheckState (Qt::Unchecked);
				itemName->setCheckable (true);
				itemName->setText (entry->GetEntryName ().isEmpty () ?
							entry->GetHumanReadableID () :
							entry->GetEntryName ());
				itemName->setData (QVariant::fromValue<ICLEntry*> (entry));
				row << itemName;

				row << new QStandardItem (entry->GetHumanReadableID ());
				const QString& accName = qobject_cast<IAccount*> (entry->
							GetParentAccount ())->GetAccountName ();
				row << new QStandardItem (accName);
				row << new QStandardItem (entry->Groups ().join ("; "));

				groupItem->appendRow (row);
			}

			Model_->appendRow (groupItem);
		}
	}
}
}
