/***************************************************************************
 *   Copyright (C) 2005 by Ian Reinhart Geiser                             *
 *   geiseri@sourcextreme.com                                              *
 *                                                                         *
 *   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 2 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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "mainwindow.h"
#include <QScrollArea>
#include <QFileDialog>
#include <QFile>
#include <QDir>
#include <QMenuBar>
#include <QMenu>
#include <QStatusBar>
#include <QImageReader>
#include <QImageWriter>
#include <QPrinter>
#include <QPrintDialog>
#include <QPainter>
#include <QSettings>
#include <QFileInfo>
#include <QDir>
#include <QComboBox>
#include <QMessageBox>
#include <QIcon>
#include <QPicture>
#include <QClipboard>
#include <QCursor>
#include <QDateTime>

#include <qdebug.h>
#include <dhwwidget.h>
#include <dhwpage.h>

MainWindow::MainWindow() : QMainWindow(0), mPage(0)
{
	setAttribute(Qt::WA_MacMetalStyle);
	QSettings settings;

	statusBar()->showMessage("Ready...");

	mView = new DHWWidget(this);
	ui.setupUi(this);
	ui.frame->setWidget(mView);
	ui.frame->setBackgroundRole(QPalette::Dark);

	ui.mZoom->insertItem ( Page, tr("Full Page") );
	ui.mZoom->insertItem ( PageWidth, tr("Page Width") );
	//ui.mZoom->insertItem ( Selection, tr("Selection") );
	ui.mZoom->insertItem ( TwentyFive, tr("25%") );
	ui.mZoom->insertItem ( Fifty, tr("50%") );
	ui.mZoom->insertItem ( SeventyFive, tr("75%") );
	ui.mZoom->insertItem ( OneHundred, tr("100%") );
	ui.mZoom->setCurrentIndex( (Zoom)settings.value("application/zoom", PageWidth).value<int>() );

	mView->setPage(0);

	setGeometry( settings.value("application/geometry", QRect(50,50,600,400)).value<QRect>() );
	mCurrentFile = settings.value("application/basedir").value<QString>();
	on_antialias_toggled(settings.value("application/smooth", false).value<bool>());

}

void MainWindow::on_antialias_toggled(bool state)
{
	ui.antialias->setChecked( state );
	mView->setAntialias(state);
	mView->update();
}

void MainWindow::on_mLayer_valueChanged(int newValue )
{
 	mView->setCurrentLayer(newValue);
 	if( mView->currentLayer() != ui.mLayer->value() )
 		ui.mLayer->setValue(mView->currentLayer());
 	mView->update();
}

void MainWindow::on_mZoom_activated(int newValue )
{
	QSizeF pgSize( ui.frame->size() );

	if( mPage )
		pgSize = mPage->readPageSize();
	switch( newValue )
	{
		case Page: // Full page
			pgSize.scale(ui.frame->size() - QSizeF(10,10), Qt::KeepAspectRatio);
		break;
		case PageWidth: // Page width
			pgSize.scale(ui.frame->size() - QSizeF(25,25), Qt::KeepAspectRatioByExpanding);
		break;
		case Selection:
		{
			QRect selection = mView->selection();
			if( selection != QRect(0,0,0,0) )
			{
				QSizeF selectionSize = selection.size();
				QSizeF frameSize = ui.frame->size();
				qreal wFactor = frameSize.width() / selectionSize.width();
				qreal hFactor = frameSize.height() / selectionSize.height();
				QSizeF newImageSize( wFactor * frameSize.width(), hFactor * frameSize.height() );

				pgSize.scale(newImageSize, Qt::KeepAspectRatioByExpanding);
				// scroll to x,y of selection.
				mView->resetSelection();
				ui.frame->scroll(selection.x(), selection.y() );
			}
			else
				return;
		}
		break;
		case TwentyFive: // 25%
			pgSize *= 0.25;
		break;
		case Fifty: // 50%
			pgSize *= 0.50;
		break;
		case SeventyFive: // 75%
			pgSize *= 0.75;
		break;
		case OneHundred: // 100%
		default:
		break;
	}

	mView->resize(pgSize.toSize());
}

MainWindow::~MainWindow()
{
	delete mPage;
}

void MainWindow::on_loadPage_triggered()
{
	QString startFile = mCurrentFile;
	if(startFile.isEmpty())
		startFile = QDir::homePath ();
	QString newFile = QFileDialog::getOpenFileName( this, tr("Select a Digital Handwriting file to open..."),
                    startFile,
                    tr("Digital Handwriting (*.dhw)"));
        if(newFile.isEmpty())
		return;
	openFile( newFile );
}

void MainWindow::openFile( const QString &fileName)
{
	if( fileName.isEmpty() )
		return;

	QFile loadFile( fileName );
	if( loadFile.open(QIODevice::ReadOnly) )
	{
		QByteArray bytes = loadFile.readAll();
		if( bytes.size() > 40 )
		{
			delete mPage;
			mPage = new DHWPage(bytes);
			mView->setPage(mPage);
			on_mLayer_valueChanged(mPage->layers());
			on_mZoom_activated(ui.mZoom->currentIndex());
			statusBar()->showMessage(tr("Loaded %1.").arg(fileName));
			mCurrentFile = fileName;
			return;
		}
	}
	else
	{
		QMessageBox::critical(this, tr("Error opening file..."),tr("%1 could not be loaded.").arg(fileName), QMessageBox::Ok, QMessageBox::NoButton);
	}
}

void MainWindow::on_exitApp_triggered()
{
	close();
}

QString generateImageFilter()
{
	QList<QByteArray> formats = QImageWriter::supportedImageFormats();
	QStringList returnFormats;
	const QString filterTemplate = "*.%1";
	foreach( QString format, formats )
		returnFormats += filterTemplate.arg(format);
	return returnFormats.join(" ");
}

void MainWindow::exportImage( const QString &exportFile )
{
	QSize pgSize(1024,768);
	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
	QImage image = mPage->drawImage( mPage->scaleTo(pgSize) );
	QApplication::restoreOverrideCursor();

	QFileInfo fileInfo(mCurrentFile);
	image.setText("Description", "DHWPageViewer by SourceXtreme, Inc.");
	image.setText("Date", QDateTime::currentDateTime().toString() );
	image.setText("Original File", fileInfo.completeBaseName() );

	QFileInfo exportFileInfo( exportFile );
	if( !image.save(exportFile, exportFileInfo.completeSuffix().toUpper().toLatin1().constData() ) )
	{
		QMessageBox::critical(this, tr("Error saving image..."),tr("The image %1 could not be saved.").arg(exportFile), QMessageBox::Ok, QMessageBox::NoButton);
	}
}

void MainWindow::on_exportPage_triggered()
{
	if( mPage == 0)
		return;
	QString startFile = mCurrentFile;
	startFile.replace(".dhw", ".png", Qt::CaseInsensitive);
	if(startFile.isEmpty())
		startFile = QDir::homePath ();
	QString exportFile = QFileDialog::getSaveFileName(
                    this,
                    tr("Choose a filename to save under"),
                    startFile,
                    tr("Image Files ( %1 );;All Files (*.*)").arg(generateImageFilter()));
        if(exportFile.isEmpty())
        	return;
	exportImage( exportFile );
}

void MainWindow::printToPDF( const QString &exportFile )
{
	QFileInfo fileInfo(mCurrentFile);
	QPrinter printer( QPrinter::HighResolution );
	printer.setOutputFormat( QPrinter::PdfFormat );
	printer.setOutputFileName( exportFile );
	printer.setDocName( fileInfo.completeBaseName() );
	printer.setCreator( tr("DHWPageViewer by SourceXtreme, Inc.") );

	QPainter painter;
	painter.begin(&printer);
	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
	mPage->drawLayer(printer.pageRect().size(), &painter, true);
	QApplication::restoreOverrideCursor();
	painter.end();
}

void MainWindow::on_exportPDF_triggered()
{
	QString startFile = mCurrentFile;
	startFile.replace(".dhw", ".pdf", Qt::CaseInsensitive);
	if(startFile.isEmpty())
		startFile = QDir::homePath ();
	QString exportFile = QFileDialog::getSaveFileName(
                    this,
                    tr("Choose a filename to save under"),
                    startFile,
                     tr("Portable Document Files ( *.pdf );;All Files (*.*)"));
        if(exportFile.isEmpty())
        	return;
	printToPDF( exportFile );
}

void MainWindow::on_printPage_triggered()
{
	if( mPage == 0)
		return;
	QSettings settings;
	QPrinter printer(QPrinter::HighResolution);
	printer.setOrientation( (QPrinter::Orientation)settings.value("printing/orientation", QPrinter::Portrait).toInt() );
	printer.setPageSize( (QPrinter::PageSize)settings.value("printing/pagesize", QPrinter::Letter ).toInt());

	QFileInfo fileInfo(mCurrentFile);
	printer.setDocName( fileInfo.completeBaseName() );
	printer.setCreator( tr("DHWPageViewer by SourceXtreme, Inc.") );

	QPrintDialog dlg( &printer, this);
	dlg.setEnabledOptions(QAbstractPrintDialog::PrintToFile);

	if (dlg.exec() == QDialog::Accepted)
	{
		QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
		QRect pageRect = printer.pageRect();
		QSize pageSize( pageRect.width() - pageRect.x(), pageRect.height() - pageRect.y());

		QPainter painter(&printer);
		mPage->drawLayer(pageSize, &painter, false);
		painter.end();

		settings.setValue("printing/orientation", printer.orientation());
		settings.setValue("printing/pagesize", printer.pageSize() );
		QApplication::restoreOverrideCursor();

	}
}

void MainWindow::closeEvent( QCloseEvent * e )
{
	Q_UNUSED(e);
	QSettings settings;
	settings.setValue("application/geometry", geometry() );
	settings.setValue("application/smooth", mView->antialias() );
	QFileInfo dir(mCurrentFile);
	settings.setValue("application/basedir", dir.dir().absolutePath() );
	if( ui.mZoom->currentIndex() == Selection )
		settings.setValue("application/zoom", PageWidth );
	else
		settings.setValue("application/zoom", ui.mZoom->currentIndex() );
}


void MainWindow::resizeEvent( QResizeEvent * e )
{
	Q_UNUSED(e);
	on_mZoom_activated( ui.mZoom->currentIndex() );
}

void MainWindow::on_helpAbout_triggered()
{
	QMessageBox::about(this, tr("About Digital Handwriting Viewer"),
		tr("This is the multiplatform viewer for the ACECAD Digital Handwriting format.\nCopyright 2005 SourceXtreme, Inc."));
}

void MainWindow::on_helpAboutQt_triggered()
{
	qApp->aboutQt();
}

void MainWindow::on_editCopySelection_triggered()
{
	if( mPage == 0)
		return;
	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
	QRect selection = mView->selection();
	QClipboard *clipboard = QApplication::clipboard();
	QImage img = mPage->drawImage( mView->size(), selection );
	clipboard->setImage(img);
	mView->resetSelection();
	QApplication::restoreOverrideCursor();
}

void MainWindow::on_editCopyPage_triggered()
{
	if( mPage == 0)
		return;
	QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
	QClipboard *clipboard = QApplication::clipboard();
	QImage img = mPage->drawImage( mView->size() );
	clipboard->setImage(img);
	QApplication::restoreOverrideCursor();
}

