#include <QtGui>

#include "screenshot.h"

#define APP_NAME tr("Screenshot")
#define PROTOCOL_FTP "ftp"
#define PROTOCOL_HTTP "http"

Screenshot::Screenshot(QString aUrl, QString aFileNameFormat, QString aFormat)
		: QDialog(0)
{
	format = aFormat;
	fileNameFormat = aFileNameFormat;
	ftp = 0;

	screenshotLabel = new QLabel;
	screenshotLabel->setSizePolicy(QSizePolicy::Expanding,
                                   QSizePolicy::Expanding);
	screenshotLabel->setAlignment(Qt::AlignCenter);
	screenshotLabel->setMinimumSize(240, 160);

	progressBar = new QProgressBar(this);
	progressBar->hide();

	createButtonsLayout();

	mainLayout = new QVBoxLayout;
	mainLayout->addWidget(screenshotLabel);
	mainLayout->addWidget(progressBar);
	mainLayout->addLayout(buttonsLayout);
	setLayout(mainLayout);

	setWindowTitle(APP_NAME);
	resize(300, 200);

	setUrl(aUrl);
}

Screenshot::~Screenshot() {

}

void Screenshot::resizeEvent(QResizeEvent * /* event */)
{
	QSize scaledSize = originalPixmap.size();
	scaledSize.scale(screenshotLabel->size(), Qt::KeepAspectRatio);
	if (!screenshotLabel->pixmap() || scaledSize != screenshotLabel->pixmap()->size())
		updateScreenshotLabel();
}

void Screenshot::uploadScreenshot() {
	uploadScreenshotButton->setEnabled(false);
	if (u.scheme().toLower() == QLatin1String(PROTOCOL_FTP)) {
		uploadFtp();
	} else if (u.scheme().toLower() == QLatin1String(PROTOCOL_HTTP)) {
		uploadHttp();
	}
}

void Screenshot::shootScreen()
{
	qApp->beep();
	originalPixmap = QPixmap(); // clear image for low memory situations
                                // on embedded devices.
	originalPixmap = QPixmap::grabWindow(QApplication::desktop()->winId());
	updateScreenshotLabel();

	show();
}

void Screenshot::createButtonsLayout()
{
	saveScreenshotButton = createButton(tr("Save"), this, SLOT(saveScreenshot()));
	uploadScreenshotButton = createButton(tr("Upload"), this, SLOT(uploadScreenshot()));

	quitScreenshotButton = createButton(tr("Close"), this, SLOT(hide()));

	buttonsLayout = new QHBoxLayout;

	buttonsLayout->addWidget(saveScreenshotButton);
	buttonsLayout->addWidget(uploadScreenshotButton);
	buttonsLayout->addStretch();
	buttonsLayout->addWidget(quitScreenshotButton);
}

QPushButton *Screenshot::createButton(const QString &text, QWidget *receiver,
                                      const char *member)
{
	QPushButton *button = new QPushButton(text);
	button->connect(button, SIGNAL(clicked()), receiver, member);
	return button;
}

void Screenshot::updateScreenshotLabel()
{
	screenshotLabel->setPixmap(originalPixmap.scaled(screenshotLabel->size(),
                                                     Qt::KeepAspectRatio,
                                                     Qt::SmoothTransformation));
}

void Screenshot::setUrl(QString aUrl) {
	url = aUrl;
	u.setUrl(url);
	uploadScreenshotButton->setVisible(
			(u.scheme().toLower() == QLatin1String(PROTOCOL_FTP)) ||
			(u.scheme().toLower() == QLatin1String(PROTOCOL_HTTP)));
}

void Screenshot::dataTransferProgress( qint64 done, qint64 total ) {
	progressBar->setMaximum(total);
	progressBar->setValue(done);
}

void Screenshot::uploadFtp() {
	QBuffer buffer( &ba );
	buffer.open( QBuffer::ReadWrite );
	originalPixmap.save( &buffer , format.toAscii() );

	fileName = tr("%1.").arg(QDateTime::currentDateTime().toString(fileNameFormat)) + format;

	QFileInfo fi(fileName);
	fileName = fi.fileName();

	if (!ftp) {
		ftp = new QFtp(this);

		connect(ftp, SIGNAL(commandFinished(int, bool)),
				this, SLOT(ftpCommandFinished(int, bool)));

		connect(ftp, SIGNAL(dataTransferProgress( qint64 , qint64 )),
			this, SLOT(dataTransferProgress( qint64 , qint64 )));
	}

	progressBar->show();

	ftp->connectToHost(u.host(), u.port(21));
}

void Screenshot::uploadHttp() {
	uploadScreenshotButton->setEnabled(true);
}

void Screenshot::saveScreenshot() {
	saveScreenshotButton->setEnabled(false);
	QString initialPath = QDir::currentPath() + tr("/%1.").arg(QDateTime::currentDateTime().toString(fileNameFormat)) + format;

	fileName = QFileDialog::getSaveFileName(this, tr("Save As"),
							   initialPath,
							   tr("%1 Files (*.%2);;All Files (*)")
							   .arg(format.toUpper())
							   .arg(format));
	if (!fileName.isEmpty()) {
		originalPixmap.save(fileName, format.toAscii());
	}
	saveScreenshotButton->setEnabled(true);
}

void Screenshot::setFormat(QString aFormat) {
	format = aFormat;
}

void Screenshot::ftpCommandFinished(int commandId, bool error)
{
	if (ftp->currentCommand() == QFtp::ConnectToHost) {
		if (error) {
			showFtpError(tr("Unable to connect to the FTP server "
										"at %1.\nPlease check that the host "
										"name is correct.\n%2")
									 .arg(u.host()).arg(ftp->errorString()));
			progressBar->hide();
			return;
		}
		if (!u.userName().isEmpty())
			ftp->login(QUrl::fromPercentEncoding(u.userName().toLatin1()), u.password());
		else
			ftp->login();
		return;
	}

	if (ftp->currentCommand() == QFtp::Login) {
		if (error) {
			showFtpError(tr("Unable to login to the FTP server "
										"at %1.\nPlease check that the login %2 "
										"is correct.\n%3")
									 .arg(u.host()).arg(u.userName()).arg(ftp->errorString()));
			return;
		}
		if (!u.path().isEmpty())
			ftp->cd(u.path());
		else
			ftp->put(ba, fileName);
		return;
	}

	if (ftp->currentCommand() == QFtp::Cd) {
		if (error) {
			showFtpError(tr("Unable to change dir to %2 on the FTP server at %1.\nPlease check that the dir is correct.\n%3")
				.arg(u.host()).arg(u.path()).arg(ftp->errorString()));
			return;
		}
		ftp->put(ba, fileName);
		return;
	}

	if (ftp->currentCommand() == QFtp::Put) {
		if (error) {
			showFtpError(tr("Unable to upload file to the FTP server.\n%1").arg(ftp->errorString()));
			return;
		}
		ftp->close();
		progressBar->hide();
		uploadScreenshotButton->setEnabled(true);
	}
}

void Screenshot::showFtpError(QString error) {
	if (ftp) {
		ftp->abort();
		ftp->deleteLater();
		ftp = 0;
	}
	QMessageBox::warning(this, APP_NAME,error);
	progressBar->hide();
	uploadScreenshotButton->setEnabled(true);
}

void Screenshot::setFileNameFormat(QString aFileNameFormat) {
	fileNameFormat = aFileNameFormat;
}
