/**********************************************************************
 * 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 "pluginmanagerdialog.h"
#include <QStyledItemDelegate>
#include <QPushButton>
#include <QSortFilterProxyModel>
#include "util/gui/clearlineeditaddon.h"
#include "interfaces/ihavesettings.h"
#include "interfaces/iinfo.h"
#include "core.h"
#include "iconthemeengine.h"
#include "coreinstanceobject.h"
#include "settingstab.h"
#include "coreproxy.h"

namespace LeechCraft
{
	namespace
	{
		class PrefDelegate : public QStyledItemDelegate
		{
		public:
			PrefDelegate (QObject* parent = 0)
			: QStyledItemDelegate (parent)
			{
			}

			virtual QWidget* createEditor (QWidget *parent,
					const QStyleOptionViewItem& option,
					const QModelIndex& index) const
			{
				if (index.column () != 2 ||
						!(index.flags () & Qt::ItemIsEditable))
					return QStyledItemDelegate::createEditor (parent, option, index);

				QPushButton *button = new QPushButton (parent);
				button->setIcon (IconThemeEngine::Instance ().GetIcon ("configure", QString ()));
				button->setToolTip (tr ("Configure..."));
				button->setMaximumWidth (48);
				button->setProperty ("SettableObject",
						index.data (PluginManager::Roles::PluginObject));
				connect (button,
						SIGNAL (released ()),
						Core::Instance ().GetCoreInstanceObject ()->GetSettingsTab (),
						SLOT (handleSettingsForObject ()));
				return button;
			}

			void updateEditorGeometry (QWidget *editor,
					const QStyleOptionViewItem& option,
					const QModelIndex&) const
			{
				editor->setGeometry (option.rect);
			}

			QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const
			{
				return index.column () == 2 ?
						QSize (32, 32) :
						QStyledItemDelegate::sizeHint (option, index);
			}
		};

		class SizeFilter : public QObject
		{
			PluginManagerDialog *PMD_;
		public:
			SizeFilter (PluginManagerDialog *pmd)
			: QObject (pmd)
			, PMD_ (pmd)
			{
			}

			bool eventFilter (QObject *obj, QEvent *e)
			{
				if (e->type () == QEvent::Show ||
						e->type () == QEvent::Resize)
					PMD_->readjustColumns ();

				return QObject::eventFilter (obj, e);
			}
		};

		class PluginsProxyModel : public QSortFilterProxyModel
		{
		public:
			PluginsProxyModel (QObject *parent = 0)
			: QSortFilterProxyModel (parent)
			{
				setDynamicSortFilter (true);
			}
		protected:
			bool filterAcceptsRow (int row, const QModelIndex&) const
			{
				const QString& filter = filterRegExp ().pattern ();
				if (filter.isEmpty ())
					return true;

				auto m = sourceModel ();
				for (int c = 0, ccount = m->columnCount (); c < ccount; ++c)
					if (m->index (row, c).data ().toString ().contains (filter, Qt::CaseInsensitive))
						return true;

				return false;
			}

			bool lessThan (const QModelIndex& left, const QModelIndex& right) const
			{
				const QString& lPath = left.data (PluginManager::Roles::PluginFilename).toString ();
				const QString& rPath = right.data (PluginManager::Roles::PluginFilename).toString ();
				if (!lPath.isEmpty () && !rPath.isEmpty ())
					return lPath < rPath;
				return QSortFilterProxyModel::lessThan (left, right);
			}
		};
	}

	PluginManagerDialog::PluginManagerDialog (QWidget *parent)
	: QWidget (parent)
	, FilterProxy_ (new PluginsProxyModel (this))
	{
		Ui_.setupUi (this);
		Ui_.PluginsTree_->setWordWrap (true);

		auto model = Core::Instance ().GetPluginsModel ();
		FilterProxy_->setSourceModel (Core::Instance ().GetPluginsModel ());
		Ui_.PluginsTree_->setModel (FilterProxy_);
		Ui_.PluginsTree_->setItemDelegateForColumn (2, new PrefDelegate (this));

		for (int i = 0, rc = model->rowCount (); i < rc; ++i)
		{
			const auto& idx = model->index (i, 2);
			if (idx.flags () & Qt::ItemIsEditable)
				Ui_.PluginsTree_->openPersistentEditor (FilterProxy_->mapFromSource (idx));
		}

		Ui_.PluginsTree_->installEventFilter (new SizeFilter (this));

		connect (Ui_.FilterLine_,
				SIGNAL (textChanged (QString)),
				FilterProxy_,
				SLOT (setFilterFixedString (QString)));

		new Util::ClearLineEditAddon (ICoreProxy_ptr (new CoreProxy ()), Ui_.FilterLine_);
	}

	void PluginManagerDialog::readjustColumns ()
	{
		Ui_.PluginsTree_->setColumnWidth (1,
				Ui_.PluginsTree_->viewport ()->width () - 48 - Ui_.PluginsTree_->columnWidth (0));
		Ui_.PluginsTree_->setColumnWidth (2, 48);
	}

	void PluginManagerDialog::accept ()
	{
	}

	void PluginManagerDialog::reject ()
	{
	}
}
