/* Copyright (C) 2018 by Intevation GmbH <info@intevation.de>
 *
 * This file is free software under the GNU GPL (v>=2)
 * and comes with ABSOLUTELY NO WARRANTY!
 * See LICENSE.txt for details.
 */

#include "overlay.h"

#include <QProgressBar>
#include <QVBoxLayout>
#include <QLabel>
#include <QMouseEvent>
#include <QWindow>
#include <QTimer>
#include <QPainter>
#include <QBrush>
#include <QLinearGradient>
#include <QStyle>
#include <QPushButton>
#include <QApplication>
#include <QDebug>

#include "w32-util.h"
#include "w32-qt-util.h"

#include <iostream>

#ifdef Q_OS_WIN

#include <windows.h>

class Overlay::Private
{
public:
    Private(Overlay *qq, WId id, const QString &text):
        q(qq)
    {
        m_target = (HWND) id;

        q->setWindowFlags(Qt::FramelessWindowHint |
                          Qt::Tool | Qt::CustomizeWindowHint |
                          Qt::WindowStaysOnTopHint);
        q->setAttribute(Qt::WA_TransparentForMouseEvents);
        q->setAttribute(Qt::WA_TranslucentBackground);

        W32::setupForeignParent(id, q, true);

        auto vLay = new QVBoxLayout(q);
        auto bar = new QProgressBar;
        auto label = new QLabel;
        label->setText(QStringLiteral("<h3>%1</h3>").arg(text));
        bar->setRange(0, 0);
        vLay->addStretch(1);

        auto cancelBtn = new QPushButton;
        cancelBtn->setIcon(q->style()->standardPixmap(QStyle::SP_TitleBarCloseButton));
        cancelBtn->setFlat(true);

        auto subLay1 = new QVBoxLayout;
        auto subLay3 = new QHBoxLayout;
        subLay3->addStretch(0.5);
        subLay3->addWidget(label);
        subLay3->addStretch(1);
        subLay3->addWidget(cancelBtn);
        subLay1->addLayout(subLay3);
        subLay1->addWidget(bar);

        auto subLay2 = new QHBoxLayout;
        subLay2->addStretch(0.1);
        subLay2->addLayout(subLay1);
        subLay2->addStretch(0.1);

        vLay->addLayout(subLay2);

        vLay->addStretch(1);

        connect(cancelBtn, &QPushButton::clicked, q, [this] () {
            std::cout << "cancel" << std::endl;
            qApp->quit();
        });

        auto refreshTimer = new QTimer(q);
        connect(refreshTimer, &QTimer::timeout, q, [this] () {
            RECT rect;
            if (GetWindowRect(m_target, &rect)) {
#if 0
                HWND myself = (HWND) q->winId();
                if (!SetWindowPos(myself, HWND_NOTOPMOST, rect.left,
                                  rect.top, rect.right - rect.left,
                                  rect.bottom - rect.top, SWP_SHOWWINDOW)) {
                    qDebug() << "Set Window pos failed.";
                    UpdateWindow(m_target);
                }
#endif
                q->setGeometry(rect.left, rect.top, rect.right - rect.left,
                               rect.bottom - rect.top);
            } else {
                //maybe window was closed
                OutputDebugStringA ("Overlay GetWindowRect failed.");
                std::cout << "cancel" << std::endl;
                qApp->quit();
            }
        });
        refreshTimer->start(50); // update interval in milliseconds
        q->show();
    }
    HWND m_target;

    Overlay *q;
};

Overlay::Overlay (WId id, const QString &text):
    d(new Private(this, id, text))
{
}

#else
Overlay::Overlay (WId id, const QString &text)
{
}
#endif

void Overlay::paintEvent(QPaintEvent *e) {
    QPainter painter(this);

    int width = size().width();
    int height = size().height();

    QLinearGradient gradient(0, 0, 0, height);
    gradient.setColorAt(0, Qt::transparent);
    gradient.setColorAt(0.5, Qt::white);
    gradient.setColorAt(1, Qt::transparent);

    QBrush brush(gradient);

    painter.fillRect(0, 0, width, height, gradient);
    QWidget::paintEvent(e);
}
