#include "qlightboxdialog.h"

#include <QEventLoop>
#include <QGridLayout>
#include <QKeyEvent>
#include <QLabel>
#include <QProgressBar>


QLightBoxDialog::QLightBoxDialog(QWidget *_parent, bool _followToHeadWidget, bool _isContentStretchable) :
    QLightBoxWidget(_parent, _followToHeadWidget),
    m_initialized(false),
    m_title(new QLabel(this)),
    m_centralWidget(nullptr),
    m_progress(new QProgressBar(this)),
    m_isContentStretchable(_isContentStretchable),
    m_execResult(Rejected)
{
    updateTitle();
}

int QLightBoxDialog::exec()
{
    m_execResult = Rejected;

    show();

    QEventLoop dialogEventLoop;
    connect(this, &QLightBoxDialog::finished, &dialogEventLoop, &QEventLoop::quit);
    dialogEventLoop.exec();

    hide();

    return m_execResult;
}

void QLightBoxDialog::setVisible(bool _visible)
{
    init();

    QLightBoxWidget::setVisible(_visible);
}

void QLightBoxDialog::accept()
{
    m_execResult = Accepted;
    emit accepted();
    emit finished(m_execResult);
}

void QLightBoxDialog::reject()
{
    m_execResult = Rejected;
    emit rejected();
    emit finished(m_execResult);
}

void QLightBoxDialog::done(int _result)
{
    m_execResult = _result;
    emit finished(m_execResult);
}

bool QLightBoxDialog::isProressVisible() const
{
    //
    // Определяем скрыт ли прогрессбар по его стилю, т.к. для сокрытия используетс маскировка
    //
    return m_progress->styleSheet().isEmpty();
}

void QLightBoxDialog::showProgress(int _minimumValue, int _maximumValue)
{
    //
    // Убираем маскирующий стиль
    //
    m_progress->setStyleSheet(QString());

    m_progress->setRange(_minimumValue, _maximumValue);
}

void QLightBoxDialog::setProgressValue(int _value)
{
    m_progress->setValue(_value);
}

void QLightBoxDialog::hideProgress()
{
    //
    // Тут мы просто применяем маскирующий стиль для виджета
    // Делается это для того, чтобы не происходило скачков интерфейса при отображении/скрытии
    // виджета прогресса внутри компоновщика интерфейса
    //
    m_progress->setStyleSheet("QProgressBar {border: none; background-color: transparent;} QProgressBar::chunk {background-color: transparent;}");
}

bool QLightBoxDialog::event(QEvent* _event)
{
    bool result = true;
    bool needHandle = true;
    if (_event->type() == QEvent::KeyPress
        && !isProressVisible()) {
        QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(_event);
        if (keyEvent->key() == Qt::Key_Enter
            || keyEvent->key() == Qt::Key_Return) {
            accept();
            needHandle = false;
        } else if (keyEvent->key() == Qt::Key_Escape) {
            reject();
            needHandle = false;
        }
    }

    if (needHandle) {
        result = QLightBoxWidget::event(_event);
    }

    return result;
}

QWidget* QLightBoxDialog::titleWidget() const
{
    return m_title;
}

QWidget* QLightBoxDialog::focusedOnExec() const
{
    return m_centralWidget;
}

void QLightBoxDialog::init()
{
    if (m_initialized == false) {
        m_initialized = true;

        initView();
        initConnections();

        //
        // Устанавливаем фокус после того, как диалог будет полностью показан
        //
        connect(this, &QLightBoxDialog::showed, this, [this] { focusedOnExec()->setFocus(); });

        //
        // Настраиваем прогресс
        //
        m_progress->setFixedHeight(5);
        m_progress->setValue(0);
        m_progress->setRange(0, 0);
        m_progress->setFormat(QString());
        hideProgress();

        //
        // Настраиваем компоновщик
        //
        if (layout() != nullptr) {
            m_centralWidget = new QFrame(this);
            m_centralWidget->setProperty("lightBoxDialogCentralWidget", true);
            m_centralWidget->setMinimumSize(minimumSize());
            m_centralWidget->setMaximumSize(maximumSize());
            m_centralWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

            QLayout* centralWidgetLayout = layout();
            m_centralWidget->setLayout(centralWidgetLayout);

            setMinimumSize(QSize(0, 0));
            setMaximumSize(QSize(16777215, 16777215));

            QGridLayout* newLayout = new QGridLayout;
            newLayout->setContentsMargins(QMargins());
            newLayout->setSpacing(0);
            newLayout->addWidget(titleWidget(), 1, 1);
            newLayout->addWidget(m_centralWidget, 2, 1);
            newLayout->setRowStretch(0, 1);
            if (m_isContentStretchable) {
                newLayout->setRowStretch(2, 8);
            }
            newLayout->addWidget(m_progress, 3, 1);
#ifdef MOBILE_OS
            newLayout->setRowStretch(4, 2);
#else
            newLayout->setRowStretch(4, 1);
#endif
            newLayout->setColumnStretch(0, 1);
            newLayout->setColumnStretch(2, 1);
            setLayout(newLayout);
        }
    }

    //
    // Заголовок необходимо настраивать каждый раз заново
    //
    updateTitle();
}

void QLightBoxDialog::updateTitle()
{
    if (titleWidget() == m_title) {
        m_title->setProperty("lightBoxDialogTitle", true);
        m_title->setWordWrap(true);
#ifdef Q_OS_MAC
        m_title->setAlignment(Qt::AlignHCenter);
#endif
        m_title->setText(windowTitle());
        m_title->setVisible(!m_title->text().isEmpty());
    } else {
        m_title->hide();
    }
}
