/***************************************************************************
 *   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 web viewer with more features.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgwebview.h"
#include "skgtraces.h"
#include "skgmainpanel.h"

#include <QPrinter>
#include <QPrintDialog>
#include <QClipboard>
#include <QPointer>
#include <QContextMenuEvent>
#include <QPrintPreviewDialog>
#include <QApplication>
#include <QDesktopServices>
#include <QWheelEvent>
#include <QTextDocumentWriter>
#include <QTextDocument>
#include <QWebFrame>
#include <QFileInfo>
#include <qmath.h>

#include <kmenu.h>
#include <kicon.h>
#include <kstandardaction.h>
#include <klocale.h>

#include "math.h"

SKGWebView::SKGWebView(QWidget* parent, const char* name)
    : QWebView(parent)
{
    setObjectName(name);
    this->installEventFilter(this);
    page()->installEventFilter(this);
}

SKGWebView::~SKGWebView()
{}

QString SKGWebView::getState()
{
    SKGTRACEIN(10, "SKGWebView::getState");
    QDomDocument doc("SKGML");
    QDomElement root = doc.createElement("parameters");
    doc.appendChild(root);
    root.setAttribute("zoomFactor", SKGServices::intToString(qMax(qRound(30.0 * log10(zoomFactor())), -10)));
    return doc.toString();
}

void SKGWebView::setState(const QString& iState)
{
    SKGTRACEIN(10, "SKGWebView::setState");
    QDomDocument doc("SKGML");
    doc.setContent(iState);
    QDomElement root = doc.documentElement();
    QString zoomPosition = root.attribute("zoomFactor");
    if (zoomPosition.isEmpty()) zoomPosition = '0';
    double z = qPow(10, ((qreal) SKGServices::stringToInt(zoomPosition)) / 30.0);
    setZoomFactor(z);
    emit zoomChanged(z);
}

void SKGWebView::contextMenuEvent(QContextMenuEvent* event)
{
    if (event) {
        KMenu* menu = new KMenu(this);

        menu->addAction(pageAction(QWebPage::Copy));

        QAction* actPrint = menu->addAction(KIcon("printer"), i18nc("Action", "Print..."));
        connect(actPrint, SIGNAL(triggered(bool)), this, SLOT(onPrint()));

        menu->addAction((QAction*) KStandardAction::printPreview(this, SLOT(onPrintPreview()), this));

        QAction* actExport = menu->addAction(KIcon("document-export"), i18nc("Noun, user action", "Export..."));
        connect(actExport, SIGNAL(triggered(bool)), this, SLOT(onExport()));

        menu->popup(this->mapToGlobal(event->pos()));

        event->accept();
    }
}

bool SKGWebView::eventFilter(QObject* object, QEvent* event)
{
    SKGTRACEIN(10, "SKGWebView::eventFilter");
    QWheelEvent* e = dynamic_cast<QWheelEvent*>(event);
    if (e) {
        if (e->orientation() == Qt::Vertical && QApplication::keyboardModifiers() &Qt::ControlModifier) {
            int numDegrees = e->delta() / 8;
            int numTicks = numDegrees / 15;

            if (numTicks > 0) {
                onZoomIn();
            } else {
                onZoomOut();
            }
            e->setAccepted(true);
            return true;
        }
    }
    return QWidget::eventFilter(object, event);
}

void SKGWebView::onZoomIn()
{
    _SKGTRACEIN(10, "SKGWebView::onZoomIn");
    int z = qMin(((int) qRound(30.0 * log10(zoomFactor()))) + 1, 10);
    setZoomFactor(qPow(10, ((qreal) z) / 30.0));

    emit zoomChanged(z);
}

void SKGWebView::onZoomOut()
{
    _SKGTRACEIN(10, "SKGWebView::onZoomOut");
    int z = qMax(((int) qRound(30.0 * log10(zoomFactor()))) - 1, -10);
    setZoomFactor(qPow(10, ((qreal) z) / 30.0));

    emit zoomChanged(z);
}

void SKGWebView::onZoomOriginal()
{
    _SKGTRACEIN(10, "SKGWebView::onZoomOriginal");
    setZoomFactor(0);

    emit zoomChanged(0);
}

void SKGWebView::exportInFile(const QString& iFileName)
{
    QString extension = QFileInfo(iFileName).suffix().toUpper();
    if (extension == "ODT") {
        QTextDocument doc;
        doc.setHtml(page()->mainFrame()->toHtml());

        QTextDocumentWriter docWriter(iFileName);
        docWriter.write(&doc);
    } else if (extension == "PDF") {
        QPrinter printer;
        printer.setOutputFileName(iFileName);
        QPainter painter(&printer);
        this->render(&painter);
        painter.end();
    } else {
        QImage image(this->size(), QImage::Format_ARGB32);
        QPainter painter(&image);
        this->render(&painter);
        painter.end();
        image.save(iFileName);
    }
}

void SKGWebView::onExport()
{
    _SKGTRACEIN(10, "SKGWebView::onExport");
    QString fileName = SKGMainPanel::getSaveFileName("kfiledialog:///IMPEXP", "application/pdf application/vnd.oasis.opendocument.text image/png image/jpeg image/gif image/tiff", this);
    if (fileName.isEmpty()) return;

    exportInFile(fileName);

    QDesktopServices::openUrl(QUrl(fileName));
}

void SKGWebView::onPrintPreview()
{
    SKGTRACEIN(10, "SKGWebView::onPrintPreview");
    QPrintPreviewDialog preview(this);
    connect(&preview, SIGNAL(paintRequested(QPrinter*)), this, SLOT(print(QPrinter*)));
    preview.exec();
}

void SKGWebView::onPrint()
{
    _SKGTRACEIN(10, "SKGWebView::onPrint");
#ifndef QT_NO_PRINTER
    QPrinter printer;
    QPointer<QPrintDialog> dialog = new QPrintDialog(&printer, this);
    if (dialog->exec() == QDialog::Accepted) {
        QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
        print(&printer);
        QApplication::restoreOverrideCursor();
    }

    delete dialog;
#endif
}
#include "skgwebview.moc"
