/**********************************************************************
 * 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 <QSortFilterProxyModel>
#include "tagsconfig.h"

namespace LC
{
namespace Util
{
	/** @brief Provides filter model with additional tags filter mode.
	 *
	 * This model behaves just like a normal QSortFilterProxyModel except
	 * it supports filtering by tags. In this mode row is accepted either
	 * if all tags from the request are found in the row (the default
	 * mode) or if the intersection of the two sets is just non-empty.
	 * The mode can be set via SetTagsInclusionMode() function. The tags
	 * filtering mode itself is enabled via setTagsMode() slot.
	 *
	 * The tags are obtained by splitting the filter pattern by the
	 * separator, which is <em>;</em> by default but can be set via the
	 * SetSeparator() method.
	 */
	class UTIL_TAGS_API TagsFilterModel : public QSortFilterProxyModel
	{
		Q_OBJECT

		bool NormalMode_;
		QString Separator_;
	public:
		/** @brief Describes the modes of matching two sets of tags.
		 *
		 * @sa SetTagsInclusionMode()
		 */
		enum class TagsInclusionMode
		{
			/** @brief Tags intersection should be non-empty.
			 *
			 * In other words, at least one tag from the filter string
			 * should be found in the list of tags of a row.
			 */
			Any,

			/** @brief Filter string tags should be a subset of row tags.
			 *
			 * In other words, all of the tags from the filter string
			 * should be found in the list of tags of a row.
			 */
			All
		};
	private:
		TagsInclusionMode TagsMode_;
	public:
		/** @brief Creates the model with the given parent.
		 *
		 * @param[in] parent The parent object of this model.
		 */
		TagsFilterModel (QObject *parent = 0);

		/** @brief Sets the separator for the tags.
		 *
		 * The separator is used to split the regexp filter string (the
		 * one set via <code>setFilterFixedString()</code> method) into
		 * the list of tags.
		 *
		 * The default separator is <em>;</em>.
		 *
		 * Setting this property will invalidate the model if the
		 * <code>dynamicSortFilter()</code> property is true.
		 *
		 * @param[in] separator The separator string.
		 */
		void SetSeparator (const QString& separator);

		/** @brief Sets the tags inclusion mode.
		 *
		 * Setting this property will invalidate the model if the
		 * <code>dynamicSortFilter()</code> property is true.
		 *
		 * @param[in] mode The tags inclusion mode.
		 */
		void SetTagsInclusionMode (TagsInclusionMode mode);
	public slots:
		/** @brief Sets whether the tags filtering mode is enabled.
		 *
		 * By default the tags mode is disabled.
		 *
		 * @param[in] enabled Whether the tags mode should be enabled.
		 *
		 * @sa enableTagsMode(), disableTagsMode()
		 */
		void setTagsMode (bool enabled);

		/** @brief Convenience slot enabling the tags mode.
		 *
		 * This slot is equivalent to <code>setTagsMode (true)</code>.
		 *
		 * @sa setTagsMode()
		 */
		void enableTagsMode ();

		/** @brief Convenience slot disabling the tags mode.
		 *
		 * This slot is equivalent to <code>setTagsMode (false)</code>.
		 *
		 * @sa setTagsMode()
		 */
		void disableTagsMode ();
	protected:
		/** @brief Reimplemented from QSortFilterProxyModel::filterAcceptsRow().
		 */
		virtual bool filterAcceptsRow (int, const QModelIndex&) const;

		/** @brief Returns the list of tags for the given row.
		 *
		 * This function should return the list of tags for the given
		 * row. Reimplement it in your subclass to provide this filter
		 * model with correct tags for rows.
		 *
		 * @param[in] row The source row for which tags should be fetched.
		 * @return The list of tags for the \em row.
		 */
		virtual QStringList GetTagsForIndex (int row) const = 0;
	};
};
}
