/* This file is part of the KDE project
   Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this program; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#include "kexisimpleprintpreviewwindow.h"
#include "kexisimpleprintingengine.h"
#include "kexisimpleprintpreviewwindow_p.h"
#include <kexi_version.h>

#include <tqlayout.h>
#include <tqaccel.h>
#include <tqtimer.h>
#include <tqlabel.h>

#include <kdialogbase.h>
#include <tdetoolbarbutton.h>
#include <tdelocale.h>
#include <kiconloader.h>
#include <kdebug.h>
#include <kpushbutton.h>
#include <tdeapplication.h>

KexiSimplePrintPreviewView::KexiSimplePrintPreviewView(
	TQWidget *parent, KexiSimplePrintPreviewWindow *window)
 : TQWidget(parent, "KexiSimplePrintPreviewView", WStaticContents)//|WNoAutoErase)
 , m_window(window)
{
	enablePainting = false;
//			resize(300,400);
//			resizeContents(200, 400);
}

void KexiSimplePrintPreviewView::paintEvent( TQPaintEvent *pe )
{
	Q_UNUSED(pe);
	if (!enablePainting)
		return;
	TQPixmap pm(size()); //dbl buffered
	TQPainter p;
	p.begin(&pm, this);
//! @todo only for screen!
	p.fillRect(TQRect(TQPoint(0,0),pm.size()), TQBrush(white));//pe->rect(), TQBrush(white));
	if (m_window->currentPage()>=0)
		m_window->m_engine.paintPage(m_window->currentPage(), p);
//		emit m_window->paintingPageRequested(m_window->currentPage(), p);
	p.end();
	bitBlt(this, 0, 0, &pm);
}

//--------------------------

#define KexiSimplePrintPreviewScrollView_MARGIN KDialogBase::marginHint()

KexiSimplePrintPreviewScrollView::KexiSimplePrintPreviewScrollView(
	KexiSimplePrintPreviewWindow *window)
 : TQScrollView(window, "scrollview", WStaticContents|WNoAutoErase)
 , m_window(window)
{
//			this->settings = settings;
	widget = new KexiSimplePrintPreviewView(viewport(), m_window);

/*			int widthMM = KoPageFormat::width( 
		settings.pageLayout.format, settings.pageLayout.orientation);
	int heightMM = KoPageFormat::height( 
		settings.pageLayout.format, settings.pageLayout.orientation);
//			int constantHeight = 400;
//			widget->resize(constantHeight * widthMM / heightMM, constantHeight ); //keep aspect
*/
	addChild(widget);
}

void KexiSimplePrintPreviewScrollView::resizeEvent( TQResizeEvent *re )
{
	TQScrollView::resizeEvent(re);
//	kdDebug() << re->size().width() << " " << re->size().height() << endl;
//	kdDebug() << contentsWidth() << " " << contentsHeight() << endl;
//	kdDebug() << widget->width() << " " << widget->height() << endl;
	setUpdatesEnabled(false);
	if (re->size().width() > (widget->width()+2*KexiSimplePrintPreviewScrollView_MARGIN)
		|| re->size().height() > (widget->height()+2*KexiSimplePrintPreviewScrollView_MARGIN))
	{
		resizeContents(
			TQMAX(re->size().width(), widget->width()+2*KexiSimplePrintPreviewScrollView_MARGIN),
			TQMAX(re->size().height(), widget->height()+2*KexiSimplePrintPreviewScrollView_MARGIN));
		int vscrbarWidth = verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0;
		int newContentsWidth
			= TQMAX(re->size().width(), widget->width()+2*KexiSimplePrintPreviewScrollView_MARGIN);
		int newContentsHeight
			= TQMAX(re->size().height(), widget->height()+2*KexiSimplePrintPreviewScrollView_MARGIN);
		moveChild(widget, (newContentsWidth - vscrbarWidth - widget->width())/2, 
			(newContentsHeight - widget->height())/2);
		resizeContents( newContentsWidth, newContentsHeight );
	}
	setUpdatesEnabled(true);
}

void KexiSimplePrintPreviewScrollView::setFullWidth()
{
	viewport()->setUpdatesEnabled(false);
	double widthMM = KoPageFormat::width( 
		m_window->settings().pageLayout.format, 
		m_window->settings().pageLayout.orientation);
	double heightMM = KoPageFormat::height( 
		m_window->settings().pageLayout.format, m_window->settings().pageLayout.orientation);
//	int constantWidth = m_window->width()- KexiSimplePrintPreviewScrollView_MARGIN*6;
	double constantWidth = width()- KexiSimplePrintPreviewScrollView_MARGIN*6;
	double heightForWidth = constantWidth * heightMM / widthMM;
//	heightForWidth = TQMIN(kapp->desktop()->height()*4/5, heightForWidth);
	kdDebug() << "1: " << heightForWidth << endl;
#if 0 //todo we can use this if we want to fix the height to width of the page
	heightForWidth = TQMIN(height(), heightForWidth);
	kdDebug() << "2: " << heightForWidth << endl;
#endif
	constantWidth = heightForWidth * widthMM / heightMM;
	widget->resize((int)constantWidth, (int)heightForWidth); //keep aspect
	resizeContents(int(widget->width() + 2*KexiSimplePrintPreviewScrollView_MARGIN), 
		int(widget->height() + 2*KexiSimplePrintPreviewScrollView_MARGIN));
	moveChild(widget, (contentsWidth()-widget->width())/2, 
		(contentsHeight()-widget->height())/2);
	viewport()->setUpdatesEnabled(true);
	resize(size()+TQSize(1,1)); //to update pos.
	widget->enablePainting = true;
	widget->repaint();
}

void KexiSimplePrintPreviewScrollView::setContentsPos(int x, int y)
{
//	kdDebug() << "############" << x << " " << y << " " << contentsX()<< " " <<contentsY() << endl;
	if (x<0 || y<0) //to avoid endless loop on Linux
		return;
	TQScrollView::setContentsPos(x,y);
}

//------------------

KexiSimplePrintPreviewWindow::KexiSimplePrintPreviewWindow(
	KexiSimplePrintingEngine &engine, const TQString& previewName, 
	TQWidget *parent, WFlags f)
 : TQWidget(parent, "KexiSimplePrintPreviewWindow", f)
 , m_engine(engine)
 , m_settings(*m_engine.settings())
 , m_pageNumber(-1)
 , m_pagesCount(-1)
{
	setCaption(i18n("%1 - Print Preview - %2").arg(previewName).arg(KEXI_APP_NAME));
	setIcon(DesktopIcon("document-print-preview"));
	TQVBoxLayout *lyr = new TQVBoxLayout(this, 6);

	int id;
	m_toolbar = new TDEToolBar(0, this);
	m_toolbar->setLineWidth(0);
	m_toolbar->setFrameStyle(TQFrame::NoFrame);
	m_toolbar->setIconText(TDEToolBar::IconTextRight);
	lyr->addWidget(m_toolbar);

	id = m_toolbar->insertWidget( -1, 0, new KPushButton(KStdGuiItem::print(), m_toolbar) );
	m_toolbar->addConnection(id, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotPrintClicked()));
	static_cast<KPushButton*>(m_toolbar->getWidget(id))->setAccel(TQt::CTRL|TQt::Key_P);
	m_toolbar->insertSeparator();

	id = m_toolbar->insertWidget(-1, 0, new KPushButton(i18n("Page Set&up..."), m_toolbar));
	m_toolbar->addConnection(id, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotPageSetup()));
	m_toolbar->insertSeparator();


#ifndef KEXI_NO_UNFINISHED 
//! @todo unfinished
	id = m_toolbar->insertWidget( -1, 0, new KPushButton(BarIconSet("zoom-in"), i18n("Zoom In"), m_toolbar));
	m_toolbar->addConnection(id, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotZoomInClicked()));
	m_toolbar->insertSeparator();

	id = m_toolbar->insertWidget( -1, 0, new KPushButton(BarIconSet("zoom-out"), i18n("Zoom Out"), m_toolbar));
	m_toolbar->addConnection(id, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotZoomOutClicked()));
	m_toolbar->insertSeparator();
#endif

	id = m_toolbar->insertWidget(-1, 0, new KPushButton(KStdGuiItem::close(), m_toolbar));
	m_toolbar->addConnection(id, TQ_SIGNAL(clicked()), this, TQ_SLOT(close()));
	m_toolbar->alignItemRight(id);

	m_scrollView = new KexiSimplePrintPreviewScrollView(this);
	m_scrollView->setUpdatesEnabled(false);
	m_view = m_scrollView->widget;
	m_scrollView->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum);
	lyr->addWidget(m_scrollView);

	TQWidget* navToolbarWidget = new TQWidget(this); //widget used to center the navigator toolbar
	navToolbarWidget->setSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Fixed);
	TQHBoxLayout *navToolbarLyr = new TQHBoxLayout(navToolbarWidget);
	lyr->addWidget(navToolbarWidget);

	m_navToolbar = new TDEToolBar(0, navToolbarWidget);
	navToolbarLyr->addStretch(1);
	navToolbarLyr->addWidget(m_navToolbar);
	navToolbarLyr->addStretch(1);
//	m_navToolbar->setFullWidth(true);
	m_navToolbar->setLineWidth(0);
	m_navToolbar->setFrameStyle(TQFrame::NoFrame);
	m_navToolbar->setIconText(TDEToolBar::IconTextRight);

	m_idFirst = m_navToolbar->insertWidget( -1, 0, new KPushButton(BarIconSet("go-first"), i18n("First Page"), m_navToolbar));
	m_navToolbar->addConnection(m_idFirst, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotFirstClicked()));
	m_navToolbar->insertSeparator();

	m_idPrevious = m_navToolbar->insertWidget( -1, 0, new KPushButton(BarIconSet("go-previous"), i18n("Previous Page"), m_navToolbar));
	m_navToolbar->addConnection(m_idPrevious, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotPreviousClicked()));
	m_navToolbar->insertSeparator();

	m_idPageNumberLabel = m_navToolbar->insertWidget( -1, 0, new TQLabel(m_navToolbar));
	m_navToolbar->insertSeparator();

	m_idNext = m_navToolbar->insertWidget( -1, 0, new KPushButton(BarIconSet("go-next"), i18n("Next Page"), m_navToolbar));
	m_navToolbar->addConnection(m_idNext, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotNextClicked()));
	m_navToolbar->insertSeparator();

	m_idLast = m_navToolbar->insertWidget( -1, 0, new KPushButton(BarIconSet("go-last"), i18n("Last Page"), m_navToolbar));
	m_navToolbar->addConnection(m_idLast, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotLastClicked()));
	m_navToolbar->insertSeparator();

	resize(width(), kapp->desktop()->height()*4/5);

//! @todo progress bar...

	TQTimer::singleShot(50, this, TQ_SLOT(initLater()));
}

void KexiSimplePrintPreviewWindow::initLater()
{
	setFullWidth();
	updatePagesCount();
	goToPage(0);
}

KexiSimplePrintPreviewWindow::~KexiSimplePrintPreviewWindow()
{
}

/*void KexiSimplePrintPreviewWindow::setPagesCount(int pagesCount)
{
	m_pagesCount = pagesCount;
	goToPage(0);
}*/

void KexiSimplePrintPreviewWindow::slotPrintClicked()
{
	hide();
	emit printRequested();
	show();
	raise();
}

void KexiSimplePrintPreviewWindow::slotPageSetup()
{
	lower();
	emit pageSetupRequested();
}

void KexiSimplePrintPreviewWindow::slotZoomInClicked()
{
	//! @todo
}

void KexiSimplePrintPreviewWindow::slotZoomOutClicked()
{
	//! @todo
}

void KexiSimplePrintPreviewWindow::slotFirstClicked()
{
	goToPage(0);
}

void KexiSimplePrintPreviewWindow::slotPreviousClicked()
{
	goToPage(m_pageNumber-1);
}

void KexiSimplePrintPreviewWindow::slotNextClicked()
{
	goToPage(m_pageNumber+1);
}

void KexiSimplePrintPreviewWindow::slotLastClicked()
{
	goToPage(m_engine.pagesCount()-1);
}

void KexiSimplePrintPreviewWindow::goToPage(int pageNumber)
{
	if ((pageNumber==m_pageNumber && m_pagesCount == (int)m_engine.pagesCount()) 
		|| pageNumber < 0 || pageNumber > ((int)m_engine.pagesCount()-1))
		return;
	m_pageNumber = pageNumber;
	m_pagesCount = m_engine.pagesCount();

	m_view->repaint(); //this will automatically paint a new page

	m_navToolbar->setItemEnabled(m_idNext, pageNumber < ((int)m_engine.pagesCount()-1));
	m_navToolbar->setItemEnabled(m_idLast, pageNumber < ((int)m_engine.pagesCount()-1));
	m_navToolbar->setItemEnabled(m_idPrevious, pageNumber > 0);
	m_navToolbar->setItemEnabled(m_idFirst, pageNumber > 0);
	static_cast<TQLabel*>(m_navToolbar->getWidget(m_idPageNumberLabel))->setText(
		i18n("Page (number) of (total)", "Page %1 of %2").arg(m_pageNumber+1).arg(m_engine.pagesCount()));
}

void KexiSimplePrintPreviewWindow::setFullWidth()
{
	m_scrollView->setFullWidth();
}

void KexiSimplePrintPreviewWindow::updatePagesCount()
{
	TQPixmap pm(m_view->size()); //dbl buffered
	TQPainter p(m_view);
	//p.begin(&pm, this);
////! @todo only for screen!
//	p.fillRect(pe->rect(), TQBrush(white));
	m_engine.calculatePagesCount(p);
	p.end();
}

bool KexiSimplePrintPreviewWindow::event( TQEvent * e )
{
	TQEvent::Type t = e->type();
	if (t==TQEvent::KeyPress) {
		TQKeyEvent *ke = static_cast<TQKeyEvent*>(e);
		const int k = ke->key();
		bool ok = true;
		if (k==TQt::Key_Equal || k==TQt::Key_Plus)
			slotZoomInClicked();
		else if (k==TQt::Key_Minus)
			slotZoomOutClicked();
		else if (k==TQt::Key_Home)
			slotFirstClicked();
		else if (k==TQt::Key_End)
			slotLastClicked();
		else
			ok = false;

		if (ok) {
			ke->accept();
			return true;
		}
	}
	else if (t==TQEvent::AccelOverride) {
		TQKeyEvent *ke = static_cast<TQKeyEvent*>(e);
		const int k = ke->key();
		bool ok = true;
		if (k==TQt::Key_PageUp)
			slotPreviousClicked();
		else if (k==TQt::Key_PageDown)
			slotNextClicked();
		else
			ok = false;

		if (ok) {
			ke->accept();
			return true;
		}
	}
	return TQWidget::event(e);
}


#include "kexisimpleprintpreviewwindow.moc"
#include "kexisimpleprintpreviewwindow_p.moc"
