#include "pch.h"
#include "MFC/CWizardPage.h"
#include "MFC/CWizard.h"

CWizardPage::CWizardPage(UINT nIDTemplate, CWizard* pParentWnd)
    : CBCGPDialog(nIDTemplate, pParentWnd)
    , _wizard(pParentWnd)
{
    EnableVisualManagerStyle();
}

void CWizardPage::setTitle(const wchar_t* t) 
{ 
    _title = t; 
	if (_wizard && _wizard->currentPage() == this)
		_wizard->onChangeTitle();
}
void CWizardPage::setTitle(const CString& t) 
{ 
    _title = t; 
	if (_wizard && _wizard->currentPage() == this)
		_wizard->onChangeTitle();
}
void CWizardPage::setDesc(const wchar_t* t) 
{ 
    _desc = t; 
	if (_wizard && _wizard->currentPage() == this)
		_wizard->onChangeDesc();
}
void CWizardPage::setDesc(const CString& t) 
{ 
    _desc = t; 
	if (_wizard && _wizard->currentPage() == this)
		_wizard->onChangeDesc();
}

/*!
    This virtual function is called by QWizard::cleanupPage() when
    the user leaves the page by clicking \uicontrol Back (unless the \l QWizard::IndependentPages
    option is set).

    The default implementation resets the page's fields to their
    original values (the values they had before initializePage() was
    called).

    \sa QWizard::cleanupPage(), initializePage(), QWizard::IndependentPages
*/
void CWizardPage::cleanupPage()
{
    //if (d->wizard) {
    //    const QVector<QWizardField>& fields = d->wizard->d_func()->fields;
    //    for (const auto& field : fields) {
    //        if (field.page == this)
    //            field.object->setProperty(field.property, field.initialValue);
    //    }
    //}
}



/*!
    This virtual function is called by QWizard to determine whether
    the \uicontrol Next or \uicontrol Finish button should be enabled or
    disabled.

    The default implementation returns \c true if all \l{mandatory
    fields} are filled; otherwise, it returns \c false.

    If you reimplement this function, make sure to emit completeChanged(),
    from the rest of your implementation, whenever the value of isComplete()
    changes. This ensures that QWizard updates the enabled or disabled state of
    its buttons. An example of the reimplementation is
    available \l{http://doc.qt.io/archives/qq/qq22-qwizard.html#validatebeforeitstoolate}
    {here}.

    \sa completeChanged(), isFinalPage()
*/
bool CWizardPage::isComplete() const
{
    //if (!_wizard)
    //    return true;

//    const QVector<QWizardField>& wizardFields = d->wizard->d_func()->fields;
//    for (int i = wizardFields.count() - 1; i >= 0; --i) {
//        const QWizardField& field = wizardFields.at(i);
//        if (field.page == this && field.mandatory) {
//            QVariant value = field.object->property(field.property);
//            if (value == field.initialValue)
//                return false;
//
//#if QT_CONFIG(lineedit)
//            if (QLineEdit* lineEdit = qobject_cast<QLineEdit*>(field.object)) {
//                if (!lineEdit->hasAcceptableInput())
//                    return false;
//            }
//#endif
//#if QT_CONFIG(spinbox)
//            if (QAbstractSpinBox* spinBox = qobject_cast<QAbstractSpinBox*>(field.object)) {
//                if (!spinBox->hasAcceptableInput())
//                    return false;
//            }
//#endif
//        }
//    }
    return true;
}

/*!
    Explicitly sets this page to be final if \a finalPage is true.

    After calling setFinalPage(true), isFinalPage() returns \c true and the \uicontrol
    Finish button is visible (and enabled if isComplete() returns
    true).

    After calling setFinalPage(false), isFinalPage() returns \c true if
    nextId() returns -1; otherwise, it returns \c false.

    \sa isComplete(), QWizard::HaveFinishButtonOnEarlyPages
*/
void CWizardPage::setFinalPage(bool finalPage)
{
    explicitlyFinal = finalPage;
    auto w = this->wizard();
    if (w && w->currentPage() == this)
        w->updateCurrentPage();
}

/*!
    This function is called by QWizard to determine whether the \uicontrol
    Finish button should be shown for this page or not.

    By default, it returns \c true if there is no next page
    (i.e., nextId() returns -1); otherwise, it returns \c false.

    By explicitly calling setFinalPage(true), you can let the user perform an
    "early finish".

    \sa isComplete(), QWizard::HaveFinishButtonOnEarlyPages
*/
bool CWizardPage::isFinalPage() const
{
     if (explicitlyFinal)
        return true;

    auto w = static_cast<const CWizard *> (_wizard);
    if (w && w->currentPage() == this) {
        // try to use the QWizard implementation if possible
        return w->nextId() == -1;
    }
    else {
        return nextId() == -1;
    }
}

/*!
    Sets this page to be a commit page if \a commitPage is true; otherwise,
    sets it to be a normal page.

    A commit page is a page that represents an action which cannot be undone
    by clicking \uicontrol Back or \uicontrol Cancel.

    A \uicontrol Commit button replaces the \uicontrol Next button on a commit page. Clicking this
    button simply calls QWizard::next() just like clicking \uicontrol Next does.

    A page entered directly from a commit page has its \uicontrol Back button disabled.

    \sa isCommitPage()
*/
void CWizardPage::setCommitPage(bool commitPage)
{
    commit = commitPage;
    auto w = this->wizard();
    if (w && w->currentPage() == this)
        w->updateCurrentPage();
}

/*!
    Returns \c true if this page is a commit page; otherwise returns \c false.

    \sa setCommitPage()
*/
bool CWizardPage::isCommitPage() const
{
    return commit;
}

/*!
    Sets the text on button \a which to be \a text on this page.

    By default, the text on buttons depends on the QWizard::wizardStyle,
    but may be redefined for the wizard as a whole using QWizard::setButtonText().

    \sa buttonText(), QWizard::setButtonText(), QWizard::buttonText()
*/
void CWizardPage::setButtonText(int which, const CString& text)
{
	ASSERT(which >= 0);
	ASSERT(which < CWizard::NButtons);
    buttonCustomTexts.insert({which, text });
    if (wizard() && wizard()->currentPage() == this)
        wizard()->btns[which].SetWindowText(text);
}

/*!
    This virtual function is called by QWizard::nextId() to find
    out which page to show when the user clicks the \uicontrol Next button.

    The return value is the ID of the next page, or -1 if no page follows.

    By default, this function returns the lowest ID greater than the ID
    of the current page, or -1 if there is no such ID.

    By reimplementing this function, you can specify a dynamic page
    order. For example:

    \snippet dialogs/licensewizard/licensewizard.cpp 18

    \sa QWizard::nextId()
*/
int CWizardPage::nextId() const
{
    if (!_wizard)
        return -1;

    bool foundCurrentPage = false;

    const auto& pageMap = _wizard->pageMap;
    CWizard::PageMap::const_iterator i = pageMap.cbegin();
    CWizard::PageMap::const_iterator end = pageMap.cend();

    for (; i != end; ++i) {
        if (i->second == this) {
            foundCurrentPage = true;
        }
        else if (foundCurrentPage) {
            return i->first;
        }
    }
    return -1;
}