/***************************************************************************
 *   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 <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>
#include <KIcon>
#include <KStandardAction>
#include <KLocale>
#include <KSaveFile>

#include "math.h"

#include "skgtraces.h"
#include "skgmainpanel.h"

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

SKGWebView::~SKGWebView()
{}

QString SKGWebView::getState()
{
    SKGTRACEINFUNC(10);
    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)
{
    SKGTRACEINFUNC(10);
    QDomDocument doc("SKGML");
    doc.setContent(iState);
    QDomElement root = doc.documentElement();
    QString zoomPosition = root.attribute("zoomFactor");
    if (zoomPosition.isEmpty()) {
        zoomPosition = '0';
    }
    double z = qPow(10, (static_cast<qreal>(SKGServices::stringToInt(zoomPosition)) / 30.0));
    setZoomFactor(z);
    emit zoomChanged(z);
}

void SKGWebView::contextMenuEvent(QContextMenuEvent* iEvent)
{
    if (iEvent) {
        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(static_cast<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(iEvent->pos()));

        iEvent->accept();
    }
}

bool SKGWebView::eventFilter(QObject* iObject, QEvent* iEvent)
{
    SKGTRACEINFUNC(10);
    if (iEvent && iEvent->type() == QEvent::Wheel) {
        QWheelEvent* e = static_cast<QWheelEvent*>(iEvent);
        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(iObject, iEvent);
}

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

    emit zoomChanged(z);
}

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

    emit zoomChanged(z);
}

void SKGWebView::onZoomOriginal()
{
    _SKGTRACEINFUNC(10);
    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);
        print(&printer);
    } else if (extension == "HTML" || extension == "HTM") {
        KSaveFile file(iFileName);
        if (file.open()) {
            QTextStream out(&file);
            out << page()->mainFrame()->toHtml();
        }

        // Close file
        file.finalize();
        file.close();
    } else {
        QImage image(this->size(), QImage::Format_ARGB32);
        QPainter painter(&image);
        this->render(&painter);
        painter.end();
        image.save(iFileName);
    }
}

void SKGWebView::onExport()
{
    _SKGTRACEINFUNC(10);
    QString fileName = SKGMainPanel::getSaveFileName("kfiledialog:///IMPEXP", "application/pdf text/html 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()
{
    SKGTRACEINFUNC(10);
    QPointer<QPrintPreviewDialog> dialog = new QPrintPreviewDialog(this);
    connect(dialog, SIGNAL(paintRequested(QPrinter*)), this, SLOT(print(QPrinter*)));
    dialog->exec();
    delete dialog;
}

void SKGWebView::onPrint()
{
    _SKGTRACEINFUNC(10);
    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;
}
#include "skgwebview.moc"
