/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <AppKit/AppKit.h>

#include "qprintdialog.h"
#include "qabstractprintdialog_p.h"

#include <QtCore/qtemporarydir.h>
#include <QtCore/private/qcore_mac_p.h>
#include <QtWidgets/private/qapplication_p.h>
#include <QtPrintSupport/qprinter.h>
#include <QtPrintSupport/qprintengine.h>
#include <qpa/qplatformprintdevice.h>

QT_BEGIN_NAMESPACE

extern qreal qt_pointMultiplier(QPageLayout::Unit unit);

class QPrintDialogPrivate : public QAbstractPrintDialogPrivate
{
    Q_DECLARE_PUBLIC(QPrintDialog)

public:
    QPrintDialogPrivate() : printInfo(0), printPanel(0)
       {}

    void openCocoaPrintPanel(Qt::WindowModality modality);
    void closeCocoaPrintPanel();

    inline QPrintDialog *printDialog() { return q_func(); }

    NSPrintInfo *printInfo;
    NSPrintPanel *printPanel;
};

QT_END_NAMESPACE

QT_USE_NAMESPACE


@class QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate);

@interface QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) : NSObject
@end

@implementation QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) {
    NSPrintInfo *printInfo;
}

- (instancetype)initWithNSPrintInfo:(NSPrintInfo *)nsPrintInfo
{
    if ((self = [self init])) {
        printInfo = nsPrintInfo;
    }
    return self;
}

- (void)printPanelDidEnd:(NSPrintPanel *)printPanel
        returnCode:(int)returnCode contextInfo:(void *)contextInfo
{
    Q_UNUSED(printPanel);

    QPrintDialog *dialog = static_cast<QPrintDialog *>(contextInfo);
    QPrinter *printer = dialog->printer();

    if (returnCode == NSModalResponseOK) {
        PMPrintSession session = static_cast<PMPrintSession>(printInfo.PMPrintSession);
        PMPrintSettings settings = static_cast<PMPrintSettings>(printInfo.PMPrintSettings);

        UInt32 frompage, topage;
        PMGetFirstPage(settings, &frompage);
        PMGetLastPage(settings, &topage);
        topage = qMin(UInt32(INT_MAX), topage);
        dialog->setFromTo(frompage, topage);

        // OK, I need to map these values back let's see
        // If from is 1 and to is INT_MAX, then print it all
        // (Apologies to the folks with more than INT_MAX pages)
        if (dialog->fromPage() == 1 && dialog->toPage() == INT_MAX) {
            dialog->setPrintRange(QPrintDialog::AllPages);
            dialog->setFromTo(0, 0);
        } else {
            dialog->setPrintRange(QPrintDialog::PageRange); // In a way a lie, but it shouldn't hurt.
            // Carbon hands us back a very large number here even for ALL, set it to max
            // in that case to follow the behavior of the other print dialogs.
            if (dialog->maxPage() < dialog->toPage())
                dialog->setFromTo(dialog->fromPage(), dialog->maxPage());
        }

        // Keep us in sync with chosen destination
        PMDestinationType dest;
        PMSessionGetDestinationType(session, settings, &dest);
        if (dest == kPMDestinationFile) {
            QCFType<CFURLRef> file;
            PMSessionCopyDestinationLocation(session, settings, &file);
            UInt8 localFile[2048];  // Assuming there's a POSIX file system here.
            CFURLGetFileSystemRepresentation(file, true, localFile, sizeof(localFile));
            auto outputFile = QFileInfo(QString::fromUtf8(reinterpret_cast<const char *>(localFile)));
            if (outputFile.suffix() == QLatin1String("pdf"))
                printer->setOutputFileName(outputFile.absoluteFilePath());
            else
                qWarning() << "Can not print to file type" << outputFile.suffix();
        } else if (dest == kPMDestinationPreview) {
            static QTemporaryDir printPreviews;
            auto documentName = printer->docName();
            if (documentName.isEmpty())
                documentName = QGuiApplication::applicationDisplayName();
            auto fileName = printPreviews.filePath(QString(QLatin1String("%1.pdf")).arg(documentName));
            printer->setOutputFileName(fileName);
            // Ideally we would have a callback when the PDF engine is done writing
            // to the file, and open Preview in response to that. Lacking that, we
            // use the quick and dirty assumption that the the print operation will
            // happen synchronously after the dialog is accepted, so we can defer
            // the opening of the file to the next runloop pass.
            dispatch_async(dispatch_get_main_queue(), ^{
                [NSWorkspace.sharedWorkspace openFile:fileName.toNSString()];
            });
        } else if (dest == kPMDestinationProcessPDF) {
            qWarning("Printing workflows are not supported");
        } else if (dest == kPMDestinationPrinter) {
            PMPrinter macPrinter;
            PMSessionGetCurrentPrinter(session, &macPrinter);
            QString printerId = QString::fromCFString(PMPrinterGetID(macPrinter)).trimmed();
            if (printer->printerName() != printerId)
                printer->setPrinterName(printerId);
        }
    }

    // Note this code should be in QCocoaPrintDevice, but that implementation is in the plugin,
    // we need to move the dialog implementation into the plugin first to be able to access it.
    // Need to tell QPrinter/QPageLayout if the page size or orientation has been changed
    PMPageFormat pageFormat = static_cast<PMPageFormat>([printInfo PMPageFormat]);
    PMPaper paper;
    PMGetPageFormatPaper(pageFormat, &paper);
    PMOrientation orientation;
    PMGetOrientation(pageFormat, &orientation);
    QPageSize pageSize;
    CFStringRef key;
    double width = 0;
    double height = 0;
    // If the PPD name is empty then is custom, for some reason PMPaperIsCustom doesn't work here
    PMPaperGetPPDPaperName(paper, &key);
    if (PMPaperGetWidth(paper, &width) == noErr && PMPaperGetHeight(paper, &height) == noErr) {
        QString ppdKey = QString::fromCFString(key);
        if (ppdKey.isEmpty()) {
            // Is using a custom page size as defined in the Print Dialog custom settings using mm or inches.
            // We can't ask PMPaper what those units actually are, we can only get the point size which may return
            // slightly wrong results due to rounding.
            // Testing shows if using metric/mm then is rounded mm, if imperial/inch is rounded to 2 decimal places
            // Even if we pass in our own custom size in mm with decimal places, the dialog will still round it!
            // Suspect internal storage is in rounded mm?
            if (QLocale().measurementSystem() == QLocale::MetricSystem) {
                QSizeF sizef = QSizeF(width, height) / qt_pointMultiplier(QPageLayout::Millimeter);
                // Round to 0 decimal places
                pageSize = QPageSize(sizef.toSize(), QPageSize::Millimeter);
            } else {
                qreal multiplier = qt_pointMultiplier(QPageLayout::Inch);
                const int w = qRound(width * 100 / multiplier);
                const int h = qRound(height * 100 / multiplier);
                pageSize = QPageSize(QSizeF(w / 100.0, h / 100.0), QPageSize::Inch);
            }
        } else {
            pageSize = QPlatformPrintDevice::createPageSize(ppdKey, QSize(width, height), QString());
        }
    }
    if (pageSize.isValid() && !pageSize.isEquivalentTo(printer->pageLayout().pageSize()))
        printer->setPageSize(pageSize);
    printer->setOrientation(orientation == kPMLandscape ? QPrinter::Landscape : QPrinter::Portrait);

    dialog->done((returnCode == NSModalResponseOK) ? QDialog::Accepted : QDialog::Rejected);
}

@end

QT_BEGIN_NAMESPACE

void QPrintDialogPrivate::openCocoaPrintPanel(Qt::WindowModality modality)
{
    Q_Q(QPrintDialog);

    if (printer->outputFormat() == QPrinter::NativeFormat) {
        // get the NSPrintInfo from the print engine in the platform plugin
        void *voidp = 0;
        (void) QMetaObject::invokeMethod(qApp->platformNativeInterface(),
                                         "NSPrintInfoForPrintEngine",
                                         Q_RETURN_ARG(void *, voidp),
                                         Q_ARG(QPrintEngine *, printer->printEngine()));
        printInfo = static_cast<NSPrintInfo *>(voidp);
        [printInfo retain];
    } else {
        printInfo = [NSPrintInfo.sharedPrintInfo retain];
    }

    // It seems the only way that PM lets you use all is if the minimum
    // for the page range is 1. This _kind of_ makes sense if you think about
    // it. However, calling PMSetFirstPage() or PMSetLastPage() always enforces
    // the range.
    // get print settings from the platform plugin
    PMPrintSettings settings = static_cast<PMPrintSettings>([printInfo PMPrintSettings]);
    PMSetPageRange(settings, q->minPage(), q->maxPage());
    if (q->printRange() == QAbstractPrintDialog::PageRange) {
        PMSetFirstPage(settings, q->fromPage(), false);
        PMSetLastPage(settings, q->toPage(), false);
    }
    [printInfo updateFromPMPrintSettings];

    QPrintDialog::PrintDialogOptions qtOptions = q->options();
    NSPrintPanelOptions macOptions = NSPrintPanelShowsCopies;
    if (qtOptions & QPrintDialog::PrintPageRange)
        macOptions |= NSPrintPanelShowsPageRange;
    if (qtOptions & QPrintDialog::PrintShowPageSize)
        macOptions |= NSPrintPanelShowsPaperSize | NSPrintPanelShowsPageSetupAccessory
                      | NSPrintPanelShowsOrientation;

    printPanel = [NSPrintPanel printPanel];
    [printPanel retain];
    [printPanel setOptions:macOptions];

    // Call processEvents in case the event dispatcher has been interrupted, and needs to do
    // cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
    // close down during the cleanup (QTBUG-17913):
    qApp->processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);

    QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) *delegate = [[QT_MANGLE_NAMESPACE(QCocoaPrintPanelDelegate) alloc] initWithNSPrintInfo:printInfo];
    if (modality == Qt::ApplicationModal || !q->parentWidget()) {
        if (modality == Qt::NonModal)
            qWarning("QPrintDialog is required to be modal on OS X");

        // Make sure we don't interrupt the runModalWithPrintInfo call.
        (void) QMetaObject::invokeMethod(qApp->platformNativeInterface(),
                                         "clearCurrentThreadCocoaEventDispatcherInterruptFlag");

        int rval = [printPanel runModalWithPrintInfo:printInfo];
        [delegate printPanelDidEnd:printPanel returnCode:rval contextInfo:q];
    } else {
        Q_ASSERT(q->parentWidget());
        QWindow *parentWindow = q->parentWidget()->windowHandle();
        NSWindow *window = static_cast<NSWindow *>(qApp->platformNativeInterface()->nativeResourceForWindow("nswindow", parentWindow));
        [printPanel beginSheetWithPrintInfo:printInfo
                             modalForWindow:window
                                   delegate:delegate
                             didEndSelector:@selector(printPanelDidEnd:returnCode:contextInfo:)
                                contextInfo:q];
    }
}

void QPrintDialogPrivate::closeCocoaPrintPanel()
{
    [printInfo release];
    printInfo = 0;
    [printPanel release];
    printPanel = 0;
}

QPrintDialog::QPrintDialog(QPrinter *printer, QWidget *parent)
    : QAbstractPrintDialog(*(new QPrintDialogPrivate), printer, parent)
{
    setAttribute(Qt::WA_DontShowOnScreen);
}

QPrintDialog::QPrintDialog(QWidget *parent)
    : QAbstractPrintDialog(*(new QPrintDialogPrivate), 0, parent)
{
    setAttribute(Qt::WA_DontShowOnScreen);
}

QPrintDialog::~QPrintDialog()
{
}

int QPrintDialog::exec()
{
    Q_D(QPrintDialog);

    QDialog::setVisible(true);

    QMacAutoReleasePool pool;
    d->openCocoaPrintPanel(Qt::ApplicationModal);
    d->closeCocoaPrintPanel();

    QDialog::setVisible(false);

    return result();
}


/*!
    \reimp
*/
void QPrintDialog::setVisible(bool visible)
{
    Q_D(QPrintDialog);

    bool isCurrentlyVisible = (d->printPanel != 0);

    if (!visible == !isCurrentlyVisible)
        return;

    if (d->printer->outputFormat() != QPrinter::NativeFormat)
        return;

    QDialog::setVisible(visible);

    if (visible) {
        Qt::WindowModality modality = windowModality();
        if (modality == Qt::NonModal) {
            // NSPrintPanels can only be modal, so we must pick a type
            modality = parentWidget() ? Qt::WindowModal : Qt::ApplicationModal;
        }
        d->openCocoaPrintPanel(modality);
        return;
    } else {
        if (d->printPanel) {
            d->closeCocoaPrintPanel();
            return;
        }
    }
}

QT_END_NAMESPACE

#include "moc_qprintdialog.cpp"
