#include <sstream>
#include <iostream>

#include <QAbstractItemView>
#include <qcheckbox.h>
#include <QDebug>
#include <qlayout.h>
#include <qlabel.h>
#include <QImageReader>
#include <QMainWindow>
#include <qmessagebox.h>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <qpoint.h>
#include <QScrollArea>
#include <QVBoxLayout>

#include <helpers.h>
#include <exception.h>

// NPlugin
#include <packagenotfoundexception.h>
#include <iprovider.h>

#include "screenshotplugin.h"

using namespace std;

namespace NPlugin
{

const QString ScreenshotPlugin::PLUGIN_NAME = "ScreenshotPlugin";


/////////////////////////////////////////////////////
// Constructors/ Destructors
/////////////////////////////////////////////////////

ScreenshotPlugin::ScreenshotPlugin(const ScreenshotPluginContainer& container) :
	_container(container)
{ 
	_pProvider = 0;
	_pReply = 0;
}

ScreenshotPlugin::~ScreenshotPlugin() 
{ 
}

/////////////////////////////////////////////////////
// Plugin Interface
/////////////////////////////////////////////////////

void ScreenshotPlugin::init(IProvider* pProvider)
{
	_pProvider = pProvider;
	QMainWindow* pWindow = pProvider->mainWindow();
	_pScrollArea = new QScrollArea(pWindow);
	_pScreenshotWidget = new QLabel("", pWindow);
	_pScrollArea->setWidget(_pScreenshotWidget);
	_pScrollArea->setWidgetResizable(true);
	//_pScrollArea->setVisible(false);
}


QString ScreenshotPlugin::title() const 
{ 
	return tr("Screenshot Plugin"); 
}

QString ScreenshotPlugin::briefDescription() const 
{ 
	return tr("Displays screenshots of the packages to be installed"); 
}

QString ScreenshotPlugin::description() const 
{ 
	return tr("This plugin displays screenshots of the packages to be installed. "
		"It fetches the screenshots from http://screenshots.debian.net so a working "
		"internet connection is required."); 
}

/////////////////////////////////////////////////////
// Information Plugin Interface 
/////////////////////////////////////////////////////

QWidget* ScreenshotPlugin::informationWidget() const	
{
	return _pScrollArea; 
}

void ScreenshotPlugin::updateInformationWidget(const string& package) 
{
/*	qDebug() << "Label size: " << _pScreenshotWidget->size();
	qDebug() << "Scroll size: " << _pScrollArea->size();*/
	if (_pReply) // if we have a download running, delete it
	{
		abortDownload();
	}


	_pScreenshotWidget->setText(tr("Loading screenshot\nEstablishing connection, please wait..."));
	//_pReply = _nam.get(QNetworkRequest("myfile"));

	QUrl url(QString("http://screenshots.debian.net/screenshot/")+toQString(package));
	_pReply = _pProvider->network()->get(QNetworkRequest(url));
	connect(_pReply, SIGNAL(finished()), SLOT(httpFinished()));
	connect(_pReply, SIGNAL(error(QNetworkReply::NetworkError)), 
			SLOT(httpError(QNetworkReply::NetworkError)));
	connect(_pReply, SIGNAL(downloadProgress(qint64,qint64)),
			SLOT(httpDownloadProgress(qint64,qint64)));
	
}


/////////////////////////////////////////////////////
// Helper Methods
/////////////////////////////////////////////////////



void ScreenshotPlugin::abortDownload()
{
	if (_pReply) 
	{
		_pReply->abort();
		_pReply->deleteLater();
		_pReply = 0;
	}
}

void ScreenshotPlugin::httpFinished() 
{
	// if an error other than ContentNotFound (which is expected if no screenshot is available) occured 
	if (_pReply->error() != QNetworkReply::NoError && _pReply->error() != QNetworkReply::ContentNotFoundError)
		return;
	QImageReader reader(_pReply);
	QImage image = reader.read();
	_pReply->deleteLater();
	_pReply = 0;
	_pScreenshotWidget->setPixmap(QPixmap::fromImage(image));
	
}

void ScreenshotPlugin::httpDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
	// if an error occured or the download is finished
	if (_pReply->error() != QNetworkReply::NoError || _pReply->isFinished())
		return;
	if (bytesTotal > 10*1024*1024) 
	{
		abortDownload();
		_pScreenshotWidget->setText(tr("The screenshot size exceeds 10 MB. "
				"Something seems to be wrong here!\n Aborting Download."));
		return;
	}
	QString progress;
	progress.setNum((int) (((float) bytesReceived)/bytesTotal*100.0f) ) ;
	// ToDo insert linebreak instead of " - " here, but  currently this leads to loads of QT warnings
	_pScreenshotWidget->setText(tr("Loading screenshot - Progress: ") + progress + "%");
}

void ScreenshotPlugin::httpError(QNetworkReply::NetworkError e) 
{
	// this error is normally returned by if there was no screenshot available
	if (e==QNetworkReply::ContentNotFoundError) 
	{
		_pScreenshotWidget->setText(tr("No screenshot available for ") + _pReply->url().toString());
		return;
	}
	// if the error is OperationCanceled that is no error
	if (e==QNetworkReply::OperationCanceledError) 
		return;
	qDebug() << "Network error\n" << _pReply->errorString();
	// in all other cases abort the download

	_pScreenshotWidget->setText(tr("An error occured while trying to download the screenshot:\n") +
			_pReply->errorString());
	abortDownload();
}



}	// namespace NPlugin

