/**********************************************************************
 * LeechCraft - modular cross-platform feature rich internet client.
 * Copyright (C) 2006-2011  Georg Rudoy
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **********************************************************************/

#include "importbinary.h"
#include <QFile>
#include <QDataStream>
#include <QFileDialog>
#include <QDir>
#include <QMessageBox>
#include <QTimer>
#include <QtDebug>

namespace LeechCraft
{
namespace Aggregator
{
	ImportBinary::ImportBinary (QWidget *parent)
	: QDialog (parent)
	{
		Ui_.setupUi (this);
		on_Browse__released ();
	}

	ImportBinary::~ImportBinary ()
	{
	}

	QString ImportBinary::GetFilename () const
	{
		return Ui_.File_->text ();
	}

	QString ImportBinary::GetTags () const
	{
		return Ui_.AdditionalTags_->text ().trimmed ();
	}

	feeds_container_t ImportBinary::GetSelectedFeeds () const
	{
		feeds_container_t result;

		QMap<IDType_t, IDType_t> foreignIDs2Local;

		for (int i = 0, end = Ui_.FeedsToImport_->topLevelItemCount ();
				i < end; ++i)
		{
			if (Ui_.FeedsToImport_->topLevelItem (i)->checkState (0) !=
					Qt::Checked)
				continue;

			Channel_ptr chan = Channels_ [i];
			if (!foreignIDs2Local.contains (chan->FeedID_))
			{
				Feed_ptr feed (new Feed ());
				feed->LastUpdate_ = QDateTime::currentDateTime ();
				result.push_back (feed);
				foreignIDs2Local [chan->FeedID_] = feed->FeedID_;
			}

			IDType_t our = foreignIDs2Local [chan->FeedID_];
			auto pos = std::find_if (result.begin (), result.end (),
					[our] (Feed_ptr feed) { return feed->FeedID_ == our; });
			(*pos)->Channels_.push_back (chan);
		}

		return result;
	}

	void ImportBinary::on_File__textEdited (const QString& newFilename)
	{
		Reset ();

		if (QFile (newFilename).exists ())
			Ui_.ButtonBox_->button (QDialogButtonBox::Open)->
				setEnabled (HandleFile (newFilename));
		else
			Reset ();
	}

	void ImportBinary::on_Browse__released ()
	{
		QString startingPath = QFileInfo (Ui_.File_->text ()).path ();
		if (startingPath.isEmpty ())
			startingPath = QDir::homePath ();

		QString filename = QFileDialog::getOpenFileName (this,
				tr ("Select binary file"),
				startingPath,
				tr ("Aggregator exchange files (*.lcae);;"
					"All files (*.*)"));

		if (filename.isEmpty ())
		{
			QTimer::singleShot (0,
					this,
					SLOT (reject ()));
			return;
		}

		Reset ();

		Ui_.File_->setText (filename);

		Ui_.ButtonBox_->button (QDialogButtonBox::Open)->
			setEnabled (HandleFile (filename));
	}

	bool ImportBinary::HandleFile (const QString& filename)
	{
		QFile file (filename);
		if (!file.open (QIODevice::ReadOnly))
		{
			QMessageBox::critical (this,
					tr ("LeechCraft"),
					tr ("Could not open file %1 for reading.")
						.arg (filename));
			return false;
		}

		QByteArray buffer = qUncompress (file.readAll ());
		QDataStream stream (&buffer, QIODevice::ReadOnly);

		int magic = 0;
		stream >> magic;
		if (magic != static_cast<int> (0xd34df00d))
		{
			QMessageBox::warning (this,
					tr ("LeechCraft"),
					tr ("Selected file %1 is not a valid "
						"LeechCraft::Aggregator exchange file.")
					.arg (filename));
			return false;
		}

		int version = 0;
		stream >> version;

		if (version != 1)
		{
			QMessageBox::warning (this,
					tr ("LeechCraft"),
					tr ("Selected file %1 is a valid LeechCraft::Aggregator "
						"exchange file, but its version %2 is unknown")
					.arg (filename)
					.arg (version));
		}

		QString title, owner, ownerEmail;
		stream >> title >> owner >> ownerEmail;

		while (stream.status () == QDataStream::Ok)
		{
			Channel_ptr channel (new Channel (-1, -1));
			stream >> (*channel);
			Channels_.push_back (channel);

			QStringList strings (channel->Title_);
			strings << QString::number (channel->Items_.size ());

			QTreeWidgetItem *item =
				new QTreeWidgetItem (Ui_.FeedsToImport_, strings);

			item->setCheckState (0, Qt::Checked);
		}

		return true;
	}

	void ImportBinary::Reset ()
	{
		Channels_.clear ();
		Ui_.FeedsToImport_->clear ();

		Ui_.ButtonBox_->button (QDialogButtonBox::Open)->setEnabled (false);
	}
}
}
