/**********************************************************************
 * 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 "checktab.h"
#include <QStandardItemModel>
#include <QToolBar>

#if QT_VERSION < 0x050000
#include <QDeclarativeView>
#include <QDeclarativeContext>
#include <QDeclarativeEngine>
#else
#include <QQuickWidget>
#include <QQmlContext>
#include <QQmlEngine>
#endif

#include <QSortFilterProxyModel>
#include <util/sys/paths.h>
#include <util/qml/colorthemeproxy.h>
#include <util/qml/themeimageprovider.h>
#include <util/qml/standardnamfactory.h>
#include <util/qml/qmlerrorwatcher.h>
#include <interfaces/lmp/ilmpproxy.h>
#include <interfaces/lmp/ilocalcollection.h>
#include "checkmodel.h"
#include "checker.h"

namespace LeechCraft
{
namespace LMP
{
namespace BrainSlugz
{
	namespace
	{
		class MissingModel : public QSortFilterProxyModel
		{
		public:
			MissingModel (QAbstractItemModel *source, QObject *parent)
			: QSortFilterProxyModel { parent }
			{
				setSourceModel (source);
				setDynamicSortFilter (true);
			}
		protected:
			bool filterAcceptsRow (int row, const QModelIndex&) const
			{
				const auto& idx = sourceModel ()->index (row, 0);
				return idx.data (CheckModel::MissingCount).toInt ();
			}
		};
	}

	CheckTab::CheckTab (const ILMPProxy_ptr& lmpProxy,
			const ICoreProxy_ptr& coreProxy,
			const TabClassInfo& tc,
			QObject* plugin)
#if QT_VERSION < 0x050000
	: CheckView_ { new QDeclarativeView }
#else
	: CheckView_ { new QQuickWidget }
#endif
	, LmpProxy_ { lmpProxy }
	, CoreProxy_ { coreProxy }
	, TC_ (tc)
	, Plugin_ { plugin }
	, Toolbar_ { new QToolBar { this } }
	, Model_ { new CheckModel { lmpProxy->GetLocalCollection ()->GetAllArtists (),
				coreProxy, lmpProxy, this } }
	, CheckedModel_ { new MissingModel { Model_, this } }
	{
		Ui_.setupUi (this);
		Ui_.CheckViewWidget_->layout ()->addWidget (CheckView_);

		for (const auto& cand : Util::GetPathCandidates (Util::SysPath::QML, ""))
			CheckView_->engine ()->addImportPath (cand);
		CheckView_->engine ()->addImageProvider ("ThemeIcons",
				new Util::ThemeImageProvider { coreProxy });

#if QT_VERSION < 0x050000
		CheckView_->setResizeMode (QDeclarativeView::SizeRootObjectToView);
#else
		CheckView_->setResizeMode (QQuickWidget::SizeRootObjectToView);
#endif

		const auto root = CheckView_->rootContext ();
		root->setContextProperty ("colorProxy",
				new Util::ColorThemeProxy { coreProxy->GetColorThemeManager (), this });
		root->setContextProperty ("artistsModel", Model_);
		root->setContextProperty ("checkedModel", CheckedModel_);
		root->setContextProperty ("checkingState", "");

		new Util::StandardNAMFactory
		{
			"lmp/qml",
			[] { return 50 * 1024 * 1024; },
			CheckView_->engine ()
		};

		new Util::QmlErrorWatcher { CheckView_ };

		const auto& filename = Util::GetSysPath (Util::SysPath::QML, "lmp/brainslugz", "CheckView.qml");
		CheckView_->setSource (QUrl::fromLocalFile (filename));

		SetupToolbar ();
	}

	TabClassInfo CheckTab::GetTabClassInfo () const
	{
		return TC_;
	}

	QObject* CheckTab::ParentMultiTabs ()
	{
		return Plugin_;
	}

	void CheckTab::Remove ()
	{
		emit removeTab (this);
		if (!IsRunning_)
			deleteLater ();
	}

	QToolBar* CheckTab::GetToolBar () const
	{
		return Toolbar_;
	}

	void CheckTab::SetupToolbar ()
	{
		const auto startAction = Toolbar_->addAction (tr ("Start"));
		startAction->setProperty ("ActionIcon", "system-run");
		connect (startAction,
				SIGNAL (triggered ()),
				this,
				SLOT (handleStart ()));

		connect (this,
				SIGNAL (runningStateChanged (bool)),
				startAction,
				SLOT (setDisabled (bool)));
	}

	void CheckTab::on_SelectAll__released ()
	{
		Model_->selectAll ();
	}

	void CheckTab::on_SelectNone__released ()
	{
		Model_->selectNone ();
	}

	void CheckTab::handleStart ()
	{
		QList<Media::ReleaseInfo::Type> types;

		auto check = [&types] (QCheckBox *box, Media::ReleaseInfo::Type type)
		{
			if (box->checkState () == Qt::Checked)
				types << type;
		};
		check (Ui_.Album_, Media::ReleaseInfo::Type::Standard);
		check (Ui_.EP_, Media::ReleaseInfo::Type::EP);
		check (Ui_.Single_, Media::ReleaseInfo::Type::Single);
		check (Ui_.Compilation_, Media::ReleaseInfo::Type::Compilation);
		check (Ui_.Live_, Media::ReleaseInfo::Type::Live);
		check (Ui_.Soundtrack_, Media::ReleaseInfo::Type::Soundtrack);
		check (Ui_.Other_, Media::ReleaseInfo::Type::Other);

		Model_->RemoveUnscheduled ();

		const auto checker = new Checker { Model_, types, LmpProxy_, CoreProxy_, this };
		connect (checker,
				SIGNAL (finished ()),
				this,
				SLOT (handleCheckFinished ()));
		emit checkStarted (checker);

		CheckView_->rootContext ()->setContextProperty ("checkingState", "checking");

		IsRunning_ = true;
		emit runningStateChanged (IsRunning_);
	}

	void CheckTab::handleCheckFinished ()
	{
		IsRunning_ = false;
		emit runningStateChanged (IsRunning_);
	}
}
}
}
