/***************************************************************************
 *   Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr  *
 *                                                                         *
 *   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, see <http://www.gnu.org/licenses/>  *
 ***************************************************************************/
/** @file
 * A plugin to print pages
 *
 * @author Stephane MANKOWSKI
 */
#include "skgprintplugin.h"
#include "skgprint_settings.h"
#include "skgtraces.h"
#include "skgmainpanel.h"

#include <kactioncollection.h>
#include <kstandardaction.h>

#include <QPrinter>
#include <QPrintDialog>
#include <QPrintPreviewDialog>
#include <QPainter>
#include <QPicture>
#include <kaboutdata.h>

/**
 * This plugin factory.
 */
K_PLUGIN_FACTORY(SKGPrintPluginFactory, registerPlugin<SKGPrintPlugin>();)
/**
 * This plugin export.
 */
K_EXPORT_PLUGIN(SKGPrintPluginFactory("skg_print", "skg_print"))

SKGPrintPlugin::SKGPrintPlugin(QObject* iParent, const QVariantList& /*iArg*/) : SKGInterfacePlugin(iParent)
{
    SKGTRACEIN(10, "SKGPrintPlugin::SKGPrintPlugin");
}

SKGPrintPlugin::~SKGPrintPlugin()
{
    SKGTRACEIN(10, "SKGPrintPlugin::~SKGPrintPlugin");
    m_currentDocument = NULL;
    m_printAction = NULL;
    m_printPreviewAction = NULL;
}

bool SKGPrintPlugin::setupActions(SKGDocument* iDocument, const QStringList& iArgument)
{
    SKGTRACEIN(10, "SKGPrintPlugin::setupActions");
    Q_UNUSED(iArgument);

    m_currentDocument = iDocument;

    setComponentData(KGlobal::mainComponent());
    setXMLFile("../skg_print/skg_print.rc");

    m_printAction = KStandardAction::print(this, SLOT(actionPrint()), actionCollection());
    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("print", m_printAction);

    m_printPreviewAction = KStandardAction::printPreview(this, SLOT(actionPrintPreview()), actionCollection());
    if (SKGMainPanel::getMainPanel()) SKGMainPanel::getMainPanel()->registerGlobalAction("print_preview", m_printPreviewAction);

    return true;
}

void SKGPrintPlugin::refresh()
{
    SKGTRACEIN(10, "SKGPrintPlugin::refresh");
    if (m_currentDocument) {
        bool test = (m_currentDocument->getDatabase() != NULL);
        if (m_printAction) m_printAction->setEnabled(test);
        if (m_printPreviewAction) m_printPreviewAction->setEnabled(test);
    }
}

KConfigSkeleton* SKGPrintPlugin::getPreferenceSkeleton()
{
    return skgprint_settings::self();
}

QString SKGPrintPlugin::title() const
{
    return i18nc("Verb, action to use a printer", "print");
}

int SKGPrintPlugin::getOrder() const
{
    return 2;
}

QStringList SKGPrintPlugin::tips() const
{
    QStringList output;
    output.push_back(i18nc("Description of a tips", "<p>... you can print all opened pages.</p>"));
    return output;
}

void SKGPrintPlugin::actionPrint()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGPrintPlugin::actionPrint", err);

    if (SKGMainPanel::getMainPanel()) {
        QPrinter printer(QPrinter::HighResolution);
        QPointer<QPrintDialog> dialog = new QPrintDialog(&printer, SKGMainPanel::getMainPanel());
        if (dialog->exec() == QDialog::Accepted) {
            QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
            print(&printer);
            QApplication::restoreOverrideCursor();
        }
        delete dialog;
    }
}

void SKGPrintPlugin::actionPrintPreview()
{
    SKGError err;
    SKGTRACEINRC(10, "SKGPrintPlugin::actionPrintPreview", err);
    QPrintPreviewDialog preview(SKGMainPanel::getMainPanel());
    connect(&preview, SIGNAL(paintRequested(QPrinter*)), this, SLOT(print(QPrinter*)));
    preview.exec();
}

void SKGPrintPlugin::print(QPrinter* iPrinter)
{
    SKGTRACEIN(10, "SKGPrintPlugin::print");
    if (SKGMainPanel::getMainPanel() && iPrinter) {
        SKGError err;
        QPainter painter;
        if (!painter.begin(iPrinter)) {
            err = SKGError(ERR_FAIL, i18nc("Error message", "Printer initialization failed"));
        } else {
            //Get printer options
            int docCopies;
            int pageCopies;
            if (iPrinter->collateCopies()) {
                docCopies = 1;
                pageCopies = iPrinter->actualNumCopies();
            } else {
                docCopies = iPrinter->actualNumCopies();
                pageCopies = 1;
            }
            int fromPage = qMin(iPrinter->fromPage(), iPrinter->toPage());
            int toPage = qMax(iPrinter->fromPage(), iPrinter->toPage());

            SKGTabWidget* tabs = SKGMainPanel::getMainPanel()->getTabWidget();

            //Compute the number of pages
            QList<QWidget*> pages;
            int nbtabs = tabs ? tabs->count() : 0;
            for (int i = 0; i < nbtabs; ++i) {
                //Yes, get the widget
                SKGTabPage* page = (SKGTabPage*) tabs->widget(i);
                if (page) pages += page->printableWidgets();
            }
            int nbpages = pages.count();

            if (fromPage == 0 && toPage == 0) {
                fromPage = 1;
                toPage = nbpages;
            }
            SKGTRACEL(10) << "Nb copy document=" << docCopies << endl;
            SKGTRACEL(10) << "Nb copy page=" << docCopies << endl;
            SKGTRACEL(10) << "From=" << fromPage << endl;
            SKGTRACEL(10) << "To=" << toPage << endl;
            //Copy document
            QRect rect = painter.viewport();
            for (int d = 1; d <= docCopies; ++d) {
                for (int i = 1; i <= nbpages; ++i) {
                    //Compute page
                    int pageToTreat = (iPrinter->pageOrder() == QPrinter::LastPageFirst ? nbpages + 1 - i : i);

                    //Do we have to print it
                    if (pageToTreat >= fromPage && pageToTreat <= toPage) {
                        //Yes, get the widget
                        //Copy pages
                        for (int c = 1; c <= pageCopies; ++c) {
                            QWidget* widget = pages.at(pageToTreat - 1);
                            if (widget) {
                                //Save palette
                                QPalette previousPalette = widget->palette();

                                //Draw in a picture with white background
                                QImage image(widget->size(), QImage::Format_ARGB32);
                                QPainter painter2(&image);
                                QPalette palette;
                                palette.setColor(QPalette::Background, Qt::white);
                                widget->setPalette(palette);
                                widget->render(&painter2);
                                painter2.end();

                                //Restore palette
                                widget->setPalette(previousPalette);

                                //Print the picture
                                QSize size = image.size();
                                size.scale(rect.size(), Qt::KeepAspectRatio);
                                painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
                                painter.setWindow(image.rect());
                                painter.drawImage(0, 0, image);

                                if (!(i == nbpages && d == docCopies && c == pageCopies)) {
                                    if (!iPrinter->newPage()) {
                                        err = SKGError(ERR_FAIL, i18nc("Error message", "Creation of new page failed"));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            painter.end();
        }

        //status bar
        if (!err) err = SKGError(0, i18nc("Successful message after an user action", "Print successfully done."));
        else err.addError(ERR_FAIL, i18nc("Error message", "Print failed"));

        //Display error
        SKGMainPanel::displayErrorMessage(err);
    }
}
#include "skgprintplugin.moc"
