/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <QtWinExtras/QtWin>

#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDialogButtonBox>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QLabel>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QShortcut>
#include <QtWidgets/QVBoxLayout>

#include <QtGui/QImage>
#include <QtGui/QPainter>
#include <QtGui/QPaintEvent>

#include <QtCore/QCommandLineOption>
#include <QtCore/QCommandLineParser>
#include <QtCore/QDebug>
#include <QtCore/QTimer>
#include <QtCore/qt_windows.h>

static void formatData(QDebug d, const void *data, int size)
{
    QDebugStateSaver saver(d);
    d.noquote();
    d.nospace();
    d << "\nData: " << QByteArray(reinterpret_cast<const char *>(data), qMin(20, size)).toHex();
    if (size > 20)
        d << "...";
    d << "\n      0000000011111111222222223333333344444444";
}

QDebug operator<<(QDebug d, const BITMAP &b)
{
    QDebugStateSaver saver(d);
    d.nospace();
    d << "BITMAP(type=" << b.bmType << ", " << b.bmWidth << 'x' << b.bmHeight
        << ", widthBytes=" << b.bmWidthBytes << ", planes=" << b.bmPlanes
        << ", bitsPixel=" << b.bmBitsPixel << ", bits=" << b.bmBits << ')';
    return d;
}

QDebug operator<<(QDebug d, const BITMAPINFOHEADER &bih)
{
    QDebugStateSaver saver(d);
    d.nospace();
    d << "BITMAPINFOHEADER(" << bih.biWidth << 'x' << qAbs(bih.biHeight)
      << (bih.biHeight < 0 ? ", top-down" : ", bottom-up")
      << ", planes=" << bih.biPlanes << ", bitCount=" << bih.biBitCount
      << ", compression="  << bih.biCompression << ", size="
      << bih.biSizeImage << ')';
    return d;
}

static void formatImage(QDebug d, const QImage &image)
{
    QDebugStateSaver s(d);
    d.noquote();
    d.nospace();
    d << image;
    if (const int colorTableSize = image.colorCount()) {
        QVector<QRgb> colorTable = image.colorTable();
        d << " Color table: " << colorTableSize << " (" << showbase << hex; // 256 by standard
        int c = 0;
        for ( ; c < qMin(8, colorTableSize); ++c) {
            if (c)
                d << ", ";
            d << colorTable[c];
        }
        if (c < colorTableSize)
            d << "...";
        d << ')' << noshowbase << dec;
    }
    formatData(d, image.constBits(), image.byteCount());
}

enum ParseOptionResult {
    OptionError,
    OptionUnset,
    OptionSet
};

static ParseOptionResult parseIntOption(const QCommandLineParser &parser, const QCommandLineOption &option,
                                        int minValue, int maxValue, int *target)
{
    if (!parser.isSet(option))
        return OptionUnset;

    const QString spec = parser.value(option);
    bool ok;
    const int value = spec.toInt(&ok);
    if (!ok || value < minValue || value > maxValue) {
        qWarning() << "Invalid value" << spec << "for" << option.names();
        return OptionError;
    }
    *target = value;
    return OptionSet;
}

template <typename Enum>
static ParseOptionResult parseEnumOption(const QCommandLineParser &parser, const QCommandLineOption &option,
                                         Enum minValue, Enum maxValue, Enum *target)
{
    int intValue;
    const ParseOptionResult result = parseIntOption(parser, option, int(minValue), int(maxValue), &intValue);
    if (result == OptionSet)
        *target = static_cast<Enum>(intValue);
    return result;
}

// Display a QImage in a dialog.
class PreviewDialog : public QDialog
{
public:
    explicit PreviewDialog(const QImage &image, QWidget *parent = nullptr);
};

PreviewDialog::PreviewDialog(const QImage &image, QWidget *parent) : QDialog(parent)
{
    setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
    QString description;
    QDebug(&description) << image.size() << ", format=" << image.format();
    QLabel *descriptionLabel = new QLabel(description, this);
    descriptionLabel->setWordWrap(true);
    auto *layout = new QVBoxLayout(this);
    layout->addWidget(descriptionLabel);
    auto *hLayout = new QHBoxLayout;
    QLabel *label = new QLabel(this);
    label->setFrameShape(QFrame::Box);
    label->setPixmap(QPixmap::fromImage(image));
    hLayout->addStretch();
    hLayout->addWidget(label);
    hLayout->addStretch();
    layout->addLayout(hLayout);
    QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, this);
    connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
    layout->addWidget(buttonBox);
}

// Widget that paints a HBITMAP using GDI API in WM_PAINT.
class PaintWidget : public QWidget
{
    Q_OBJECT
public:
    explicit PaintWidget(HBITMAP hBitmap, QWidget *p = nullptr) : QWidget(p), m_hBitmap(hBitmap) { }

    bool nativeEvent(const QByteArray &eventType, void *message, long *result) override;

public slots:
    void saveBitmap();
    void convertBack();

protected:
    void contextMenuEvent(QContextMenuEvent *) override;

private:
    const HBITMAP m_hBitmap;
};

bool PaintWidget::nativeEvent(const QByteArray &eventType, void *messageIn, long *result)
{
    MSG *message = reinterpret_cast<MSG *>(messageIn);
    if (message->message != WM_PAINT)
        return QWidget::nativeEvent(eventType, message, result);

    PAINTSTRUCT paintStruct;
    BITMAP bitmap;

    const HDC hdc = BeginPaint(message->hwnd, &paintStruct);
    SelectObject(hdc, GetStockObject(BLACK_PEN));
    Rectangle(hdc, 1, 1, width() - 1, height() - 1);

    const HDC hdcMem = CreateCompatibleDC(hdc);
    const HGDIOBJ oldBitmap = SelectObject(hdcMem, m_hBitmap);

    GetObject(m_hBitmap, sizeof(bitmap), &bitmap);
    {
        QDebug d = qDebug();
        d << __FUNCTION__ << bitmap;
        formatData(d, bitmap.bmBits, bitmap.bmHeight * bitmap.bmWidthBytes);
    }
    BitBlt(hdc, 5, 5, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);
    SelectObject(hdcMem, oldBitmap);
    DeleteDC(hdcMem);

    EndPaint(message->hwnd, &paintStruct);
    return true;
}

void PaintWidget::convertBack()
{
    QImage image = QtWin::imageFromHBITMAP(m_hBitmap);
    formatImage(qDebug(), image);
    auto *dialog = new PreviewDialog(image, this);
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setModal(false);
    dialog->setWindowTitle(QLatin1String("QImage - Qt ") + QLatin1String(QT_VERSION_STR));
    dialog->show();
}

void PaintWidget::saveBitmap()
{
    QImage image = QtWin::imageFromHBITMAP(m_hBitmap);
    formatImage(qDebug(), image);
    QFileDialog fileDialog(this);
    fileDialog.setAcceptMode(QFileDialog::AcceptSave);
    fileDialog.setMimeTypeFilters(QStringList(QStringLiteral("image/png")));
    fileDialog.setDefaultSuffix(QStringLiteral("png"));
    fileDialog.selectFile(QStringLiteral("test.png"));
    while (fileDialog.exec() == QDialog::Accepted) {
        const QString fileName = fileDialog.selectedFiles().first();
        if (image.save(fileName)) {
            qDebug().noquote() << "saved" << QDir::toNativeSeparators(fileName);
            break;
        }
        qWarning().noquote() << "Could not save" << QDir::toNativeSeparators(fileName);
    }
}

void PaintWidget::contextMenuEvent(QContextMenuEvent *e)
{
    QMenu contextMenu;
    contextMenu.addAction(QStringLiteral("Convert into QImage"), this, &PaintWidget::convertBack);
    QAction *saveAction = contextMenu.addAction(QStringLiteral("Save"), this, &PaintWidget::saveBitmap);
    saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
    contextMenu.exec(e->globalPos());
}

static const char description[] =
"\nCreates a HBITMAP from a QImage either passed as file name or by drawing in a\n"
"format determined by a command line option and draws it onto a native window\n"
"for comparison. Provides a context menu for converting the HBITMAP back to a\n"
"QImage and saving that for checking the reverse conversion.";

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QCoreApplication::setApplicationName("imageconversion");
    QCoreApplication::setOrganizationName("QtProject");
    QCoreApplication::setApplicationVersion(QT_VERSION_STR);
    QCommandLineParser parser;
    parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
    parser.setApplicationDescription("Qt Windows Extras Image Conversion Tester");
    parser.addHelpOption();
    parser.addVersionOption();
    parser.setApplicationDescription(description);

    const QCommandLineOption formatOption(QStringList{"format", "f"},
                                          "QImage format", "format");
    parser.addOption(formatOption);
    const QCommandLineOption colorOption(QStringList{"color", "c"},
                                         "Fill color", "color-spec");
    parser.addOption(colorOption);
    const QCommandLineOption globalColorOption(QStringList{"globalColor", "g"},
                                               "Fill color (global color enum value)", "global-color");
    parser.addOption(globalColorOption);
    const QCommandLineOption widthOption(QStringList{"width", "w"},
                                         "Width", "width");
    parser.addOption(widthOption);
    const QCommandLineOption heightOption(QStringList{"height", "h"},
                                          "Height", "height");
    parser.addOption(heightOption);
    const QCommandLineOption previewOption(QStringList{"preview", "p"},
                                           "Show a preview");
    parser.addOption(previewOption);

    parser.addPositionalArgument("file", "The image file to open.");
    parser.process(app);

    QColor defaultColor(Qt::red);
    if (parser.isSet(colorOption)) {
        const QString spec = parser.value(colorOption);
        defaultColor = QColor(spec);
        if (!defaultColor.isValid()) {
            qWarning() << "Invalid color specification" << spec;
            return -1;
        }
    } else {
        // Color 0: color0, 1: color1, 2: black, 3: white, 7:red, 9: blue, 8: green
        Qt::GlobalColor globalColor = Qt::color0;
        if (!parseEnumOption(parser, globalColorOption, Qt::black, Qt::transparent, &globalColor))
            return -1;
        if (globalColor != Qt::color0)
            defaultColor = QColor(defaultColor);
    }

    // Format: 1: mono, 3: Indexed8, 7: RGB 16, 11: RGB555, 13: RGB888
    QImage::Format targetFormat = QImage::Format_ARGB32_Premultiplied;
    if (!parseEnumOption(parser, formatOption, QImage::Format_Mono, QImage::Format_Grayscale8, &targetFormat))
        return -1;
    // Can't paint on indexed nor mono, need transform?
    const QImage::Format drawFormat = targetFormat == QImage::Format_Indexed8
        || targetFormat == QImage::Format_Mono || targetFormat == QImage::Format_MonoLSB
        ? QImage::Format_ARGB32_Premultiplied : targetFormat;

    if (targetFormat == QImage::Format_Mono || targetFormat == QImage::Format_MonoLSB)
        defaultColor = Qt::white;

    int width = 73;
    int height = 57;
    if (!parseIntOption(parser, widthOption, 1, 2000, &width) || !parseIntOption(parser, heightOption, 1, 2000, &height))
        return -1;

    const bool preview = parser.isSet(previewOption);

    QImage image;
    if (!parser.positionalArguments().isEmpty()) {
        QString fileName = parser.positionalArguments().constFirst();
        image = QImage(fileName);
        if (image.isNull() || image.size().isEmpty()) {
            qWarning().noquote() << "Image load fail" << QDir::toNativeSeparators(fileName);
            return -1;
        }
    }

    if (image.isNull()) {
        qDebug() << "Default image color=" << defaultColor
            << showbase << hex << defaultColor.rgba() << noshowbase << dec
            << ", format=" << drawFormat;
        image = QImage(width, height, drawFormat);
        image.fill(defaultColor);
        QPainter painter(&image);
        painter.drawLine(0, 0, image.width(), image.height());
    }

    if (image.format() != targetFormat) {
        qDebug() << "Converting " << image.format() << targetFormat;
        image = image.convertToFormat(targetFormat);
    }

    formatImage(qDebug(), image);

    const HBITMAP bitmap = QtWin::imageToHBITMAP(image);
    if (!bitmap) {
        qWarning() << "Failed to create HBITMAP";
        return -1;
    }

    int exitCode = 0;
    {
        PaintWidget paintWidget(bitmap);
        auto *quitShortcut = new QShortcut(&paintWidget);
        quitShortcut->setKey(Qt::CTRL + Qt::Key_Q);
        quitShortcut->setContext(Qt::ApplicationShortcut);
        QObject::connect(quitShortcut, &QShortcut::activated, qApp, &QCoreApplication::quit);
        paintWidget.setWindowTitle(QLatin1String("HBITMAP - Qt ") + QLatin1String(QT_VERSION_STR));
        paintWidget.show();
        if (preview) {
            auto *dialog = new PreviewDialog(image);
            dialog->setModal(false);
            dialog->setWindowTitle(QLatin1String("QImage - Qt ") + QLatin1String(QT_VERSION_STR));
            dialog->move(paintWidget.frameGeometry().topRight() + QPoint(50, 0));
            dialog->show();
        }
        exitCode = app.exec();
    }

    DeleteObject(bitmap);

    return exitCode;
}

#include "main.moc"
