/**********************************************************************
 * 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 "optionsconfigwidget.h"
#include <QStandardItemModel>
#include <QTreeView>
#include <QVBoxLayout>
#include <QtDebug>
#include "kbctl.h"
#include "rulesstorage.h"
#include "xmlsettingsmanager.h"

namespace LeechCraft
{
namespace KBSwitch
{
	OptionsConfigWidget::OptionsConfigWidget (QWidget *parent)
	: QWidget (parent)
	, Model_ (new QStandardItemModel (this))
	{
		Model_->setHorizontalHeaderLabels ({ tr ("Code"), tr ("Description") });

		const auto& opts = XmlSettingsManager::Instance ()
				.property ("EnabledOptions").toStringList ();

		const auto& options = KBCtl::Instance ().GetRulesStorage ()->GetOptions ();
		for (auto groupPos = options.begin (); groupPos != options.end (); ++groupPos)
		{
			const auto& submap = *groupPos;

			auto groupRootItem = new QStandardItem (groupPos.key ());
			auto groupRootDesc = new QStandardItem ((*groupPos) [{}]);
			groupRootItem->setEditable (false);
			groupRootDesc->setEditable (false);

			for (auto sgPos = submap.begin (); sgPos != submap.end (); ++sgPos)
			{
				if (sgPos.key ().isEmpty ())
					continue;

				auto optionItem = new QStandardItem (sgPos.key ());
				optionItem->setEditable (false);
				optionItem->setCheckable (true);

				const auto& fullname = groupPos.key () + ':' + sgPos.key ();
				optionItem->setCheckState (opts.contains (fullname) ?
						Qt::Checked :
						Qt::Unchecked);

				auto optionDesc = new QStandardItem (sgPos.value ());
				optionDesc->setEditable (false);

				groupRootItem->appendRow ({ optionItem, optionDesc });
			}

			Model_->appendRow ({ groupRootItem, groupRootDesc });
		}

		KBCtl::Instance ().SetOptions (opts);

		connect (Model_,
				SIGNAL (itemChanged (QStandardItem*)),
				this,
				SLOT (markModified ()));

		auto treeView = new QTreeView ();
		auto layout = new QVBoxLayout ();
		layout->setContentsMargins (0, 0, 0, 0);
		layout->addWidget (treeView);
		setLayout (layout);

		treeView->setModel (Model_);
	}

	void OptionsConfigWidget::accept ()
	{
		if (!Modified_)
			return;

		Modified_ = false;

		auto opts = XmlSettingsManager::Instance ()
				.property ("EnabledOptions").toStringList ();
		opts.sort ();

		QStringList newOpts;
		for (int i = 0; i < Model_->rowCount (); ++i)
		{
			auto groupItem = Model_->item (i);

			const auto& groupPrefix = groupItem->text ();

			for (int j = 0; j < groupItem->rowCount (); ++j)
			{
				auto optItem = groupItem->child (j);
				if (optItem->checkState () == Qt::Checked)
					newOpts << groupPrefix + ':' + optItem->text ();
			}
		}
		newOpts.sort ();

		if (opts == newOpts)
			return;

		XmlSettingsManager::Instance ().setProperty ("EnabledOptions", newOpts);
		KBCtl::Instance ().SetOptions (newOpts);
	}

	void OptionsConfigWidget::reject ()
	{
		const auto& opts = XmlSettingsManager::Instance ()
				.property ("EnabledOptions").toStringList ();
		for (int i = 0; i < Model_->rowCount (); ++i)
		{
			auto groupItem = Model_->item (i);

			const auto& groupPrefix = groupItem->text ();

			for (int j = 0; j < groupItem->rowCount (); ++j)
			{
				auto optItem = groupItem->child (j);
				const auto& fullname = groupPrefix + ':' + optItem->text ();
				optItem->setCheckState (opts.contains (fullname) ?
						Qt::Checked :
						Qt::Unchecked);
			}
		}

		Modified_ = false;
	}

	void OptionsConfigWidget::markModified ()
	{
		Modified_ = true;
	}
}
}
