/**********************************************************************
 * 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 "document.h"
#include <QFile>
#include <QDomDocument>
#include <QtDebug>
#include <QTextDocument>
#include <QTextFrameFormat>
#include <QTextFrame>
#include "mobiparser.h"

namespace LeechCraft
{
namespace Monocle
{
namespace Dik
{
	namespace
	{
		class MobiTextDocument : public QTextDocument
		{
			const std::shared_ptr<MobiParser> P_;
		public:
			MobiTextDocument (const std::shared_ptr<MobiParser>& p, QObject *parent = 0)
			: QTextDocument (parent)
			, P_ (p)
			{
			}
		protected:
			QVariant loadResource (int type, const QUrl& name);
		};

		QVariant MobiTextDocument::loadResource (int type, const QUrl& name)
		{
			if (type != ImageResource || name.scheme () != "rec")
				return QTextDocument::loadResource (type, name);

			bool ok = false;
			const quint16 recnum = static_cast<quint16> (name.path ().mid (1).toUInt (&ok));
			if (!ok)
				return {};

			QVariant resource;
			resource.setValue (P_->GetImage (recnum - 1));
			addResource (type, name, resource);

			return resource;
		}

		QString Fix (QString markup)
		{
			QRegExp imgRx ("<img.*recindex=\"([\\d]*)\".*>", Qt::CaseInsensitive);
			imgRx.setMinimal (true);
			markup.replace (imgRx, "<img src='rec:/\\1' />");

			markup.replace ("<mbp:pagebreak/>", "<p style='page-break-after: always' />");

			return markup;
		}
	}

	Document::Document (const QString& filename, QObject *plugin)
	: DocURL_ (QUrl::fromLocalFile (filename))
	, Parser_ (new MobiParser (filename))
	, Plugin_ (plugin)
	{
		if (!Parser_->IsValid ())
			return;

		QString contents;
		try
		{
			contents = Parser_->GetText ();
		}
		catch (const std::exception&)
		{
			return;
		}

		auto doc = std::make_shared<MobiTextDocument> (Parser_);
		doc->setPageSize (QSize (600, 800));
		doc->setUndoRedoEnabled (false);

		if (contents.contains ("<html", Qt::CaseInsensitive))
			doc->setHtml (Fix (contents));
		else
			doc->setPlainText (contents);

		QTextFrameFormat format;
		format.setMargin (30);
		doc->rootFrame ()->setFrameFormat (format);

		SetDocument (doc);
		Info_ = Parser_->GetDocInfo ();
	}

	QObject* Document::GetBackendPlugin () const
	{
		return Plugin_;
	}

	QObject* Document::GetQObject ()
	{
		return this;
	}

	DocumentInfo Document::GetDocumentInfo () const
	{
		return Info_;
	}

	QUrl Document::GetDocURL () const
	{
		return DocURL_;
	}
}
}
}
