/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Quick Templates 2 module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickpage_p.h"
#include "qquickpage_p_p.h"
#include "qquicktabbar_p.h"
#include "qquicktoolbar_p.h"
#include "qquickdialogbuttonbox_p.h"

QT_BEGIN_NAMESPACE

/*!
    \qmltype Page
    \inherits Pane
//!     \instantiates QQuickPage
    \inqmlmodule QtQuick.Controls
    \since 5.7
    \ingroup qtquickcontrols2-containers
    \ingroup qtquickcontrols2-focusscopes
    \brief Styled page control with support for a header and footer.

    Page is a container control which makes it convenient to add
    a \l header and \l footer item to a page.

    \image qtquickcontrols2-page-wireframe.png

    The following example snippet illustrates how to use a page-specific
    toolbar header and an application-wide tabbar footer.

    \qml
    import QtQuick.Controls 2.12

    ApplicationWindow {
        visible: true

        StackView {
            anchors.fill: parent

            initialItem: Page {
                header: ToolBar {
                    // ...
                }
            }
        }

        footer: TabBar {
            // ...
        }
    }
    \endqml

    \sa ApplicationWindow, {Container Controls},
        {Focus Management in Qt Quick Controls}
*/

static const QQuickItemPrivate::ChangeTypes LayoutChanges = QQuickItemPrivate::Geometry | QQuickItemPrivate::Visibility | QQuickItemPrivate::Destroyed
                                                          | QQuickItemPrivate::ImplicitWidth | QQuickItemPrivate::ImplicitHeight;

namespace {
    enum Position {
        Header,
        Footer
    };

    Q_STATIC_ASSERT(int(Header) == int(QQuickTabBar::Header));
    Q_STATIC_ASSERT(int(Footer) == int(QQuickTabBar::Footer));

    Q_STATIC_ASSERT(int(Header) == int(QQuickToolBar::Header));
    Q_STATIC_ASSERT(int(Footer) == int(QQuickToolBar::Footer));

    Q_STATIC_ASSERT(int(Header) == int(QQuickDialogButtonBox::Header));
    Q_STATIC_ASSERT(int(Footer) == int(QQuickDialogButtonBox::Footer));

    static void setPos(QQuickItem *item, Position position)
    {
        if (QQuickToolBar *toolBar = qobject_cast<QQuickToolBar *>(item))
            toolBar->setPosition(static_cast<QQuickToolBar::Position>(position));
        else if (QQuickTabBar *tabBar = qobject_cast<QQuickTabBar *>(item))
            tabBar->setPosition(static_cast<QQuickTabBar::Position>(position));
        else if (QQuickDialogButtonBox *buttonBox = qobject_cast<QQuickDialogButtonBox *>(item))
            buttonBox->setPosition(static_cast<QQuickDialogButtonBox::Position>(position));
    }
}

void QQuickPagePrivate::relayout()
{
    Q_Q(QQuickPage);
    const qreal hh = header && header->isVisible() ? header->height() : 0;
    const qreal fh = footer && footer->isVisible() ? footer->height() : 0;
    const qreal hsp = hh > 0 ? spacing : 0;
    const qreal fsp = fh > 0 ? spacing : 0;

    if (contentItem) {
        contentItem->setY(q->topPadding() + hh + hsp);
        contentItem->setX(q->leftPadding());
        contentItem->setWidth(q->availableWidth());
        contentItem->setHeight(q->availableHeight() - hh - fh - hsp - fsp);
    }

    if (header)
        header->setWidth(q->width());

    if (footer) {
        footer->setY(q->height() - footer->height());
        footer->setWidth(q->width());
    }
}

void QQuickPagePrivate::resizeContent()
{
    relayout();
}

void QQuickPagePrivate::itemVisibilityChanged(QQuickItem *item)
{
    Q_Q(QQuickPage);
    QQuickPanePrivate::itemVisibilityChanged(item);
    if (item == header) {
        QBoolBlocker signalGuard(emittingImplicitSizeChangedSignals);
        emit q->implicitHeaderWidthChanged();
        emit q->implicitHeaderHeightChanged();
        relayout();
    } else if (item == footer) {
        QBoolBlocker signalGuard(emittingImplicitSizeChangedSignals);
        emit q->implicitFooterWidthChanged();
        emit q->implicitFooterHeightChanged();
        relayout();
    }
}

void QQuickPagePrivate::itemImplicitWidthChanged(QQuickItem *item)
{
    Q_Q(QQuickPage);
    QQuickPanePrivate::itemImplicitWidthChanged(item);

    // Avoid binding loops by skipping signal emission if we're already doing it.
    if (emittingImplicitSizeChangedSignals)
        return;

    if (item == header)
        emit q->implicitHeaderWidthChanged();
    else if (item == footer)
        emit q->implicitFooterWidthChanged();
}

void QQuickPagePrivate::itemImplicitHeightChanged(QQuickItem *item)
{
    Q_Q(QQuickPage);
    QQuickPanePrivate::itemImplicitHeightChanged(item);

    // Avoid binding loops by skipping signal emission if we're already doing it.
    if (emittingImplicitSizeChangedSignals)
        return;

    if (item == header)
        emit q->implicitHeaderHeightChanged();
    else if (item == footer)
        emit q->implicitFooterHeightChanged();
}

void QQuickPagePrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF & diff)
{
    QQuickPanePrivate::itemGeometryChanged(item, change, diff);
    if (item == header || item == footer)
        relayout();
}

void QQuickPagePrivate::itemDestroyed(QQuickItem *item)
{
    Q_Q(QQuickPage);
    QQuickPanePrivate::itemDestroyed(item);
    if (item == header) {
        header = nullptr;
        relayout();
        emit q->implicitHeaderWidthChanged();
        emit q->implicitHeaderHeightChanged();
        emit q->headerChanged();
    } else if (item == footer) {
        footer = nullptr;
        relayout();
        emit q->implicitFooterWidthChanged();
        emit q->implicitFooterHeightChanged();
        emit q->footerChanged();
    }
}

QQuickPage::QQuickPage(QQuickItem *parent)
    : QQuickPane(*(new QQuickPagePrivate), parent)
{
}

QQuickPage::QQuickPage(QQuickPagePrivate &dd, QQuickItem *parent)
    : QQuickPane(dd, parent)
{
}

QQuickPage::~QQuickPage()
{
    Q_D(QQuickPage);
    if (d->header)
        QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, LayoutChanges);
    if (d->footer)
        QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, LayoutChanges);
}

/*!
    \qmlproperty string QtQuick.Controls::Page::title

    This property holds the page title.

    The title is often displayed at the top of a page to give
    the user context about the page they are viewing.

    \code
    ApplicationWindow {
        visible: true
        width: 400
        height: 400

        header: Label {
            text: view.currentItem.title
            horizontalAlignment: Text.AlignHCenter
        }

        SwipeView {
            id: view
            anchors.fill: parent

            Page {
                title: qsTr("Home")
            }
            Page {
                title: qsTr("Discover")
            }
            Page {
                title: qsTr("Activity")
            }
        }
    }
    \endcode
*/

QString QQuickPage::title() const
{
    return d_func()->title;
}

void QQuickPage::setTitle(const QString &title)
{
    Q_D(QQuickPage);
    if (d->title == title)
        return;

    d->title = title;
    maybeSetAccessibleName(title);
    emit titleChanged();
}

/*!
    \qmlproperty Item QtQuick.Controls::Page::header

    This property holds the page header item. The header item is positioned to
    the top, and resized to the width of the page. The default value is \c null.

    \note Assigning a ToolBar, TabBar, or DialogButtonBox as a page header
    automatically sets the respective \l ToolBar::position, \l TabBar::position,
    or \l DialogButtonBox::position property to \c Header.

    \sa footer, ApplicationWindow::header
*/
QQuickItem *QQuickPage::header() const
{
    Q_D(const QQuickPage);
    return d->header;
}

void QQuickPage::setHeader(QQuickItem *header)
{
    Q_D(QQuickPage);
    if (d->header == header)
        return;

    if (d->header) {
        QQuickItemPrivate::get(d->header)->removeItemChangeListener(d, LayoutChanges);
        d->header->setParentItem(nullptr);
    }
    d->header = header;
    if (header) {
        header->setParentItem(this);
        QQuickItemPrivate::get(header)->addItemChangeListener(d, LayoutChanges);
        if (qFuzzyIsNull(header->z()))
            header->setZ(1);
        setPos(header, Header);
    }
    if (isComponentComplete())
        d->relayout();
    emit headerChanged();
}

/*!
    \qmlproperty Item QtQuick.Controls::Page::footer

    This property holds the page footer item. The footer item is positioned to
    the bottom, and resized to the width of the page. The default value is \c null.

    \note Assigning a ToolBar, TabBar, or DialogButtonBox as a page footer
    automatically sets the respective \l ToolBar::position, \l TabBar::position,
    or \l DialogButtonBox::position property to \c Footer.

    \sa header, ApplicationWindow::footer
*/
QQuickItem *QQuickPage::footer() const
{
    Q_D(const QQuickPage);
    return d->footer;
}

void QQuickPage::setFooter(QQuickItem *footer)
{
    Q_D(QQuickPage);
    if (d->footer == footer)
        return;

    if (d->footer) {
        QQuickItemPrivate::get(d->footer)->removeItemChangeListener(d, LayoutChanges);
        d->footer->setParentItem(nullptr);
    }
    d->footer = footer;
    if (footer) {
        footer->setParentItem(this);
        QQuickItemPrivate::get(footer)->addItemChangeListener(d, LayoutChanges);
        if (qFuzzyIsNull(footer->z()))
            footer->setZ(1);
        setPos(footer, Footer);
    }
    if (isComponentComplete())
        d->relayout();
    emit footerChanged();
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Page::implicitHeaderWidth
    \readonly

    This property holds the implicit header width.

    The value is equal to \c {header && header.visible ? header.implicitWidth : 0}.

    \sa implicitHeaderHeight, implicitFooterWidth
*/
qreal QQuickPage::implicitHeaderWidth() const
{
    Q_D(const QQuickPage);
    if (!d->header || !d->header->isVisible())
        return 0;
    return d->header->implicitWidth();
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Page::implicitHeaderHeight
    \readonly

    This property holds the implicit header height.

    The value is equal to \c {header && header.visible ? header.implicitHeight : 0}.

    \sa implicitHeaderWidth, implicitFooterHeight
*/
qreal QQuickPage::implicitHeaderHeight() const
{
    Q_D(const QQuickPage);
    if (!d->header || !d->header->isVisible())
        return 0;
    return d->header->implicitHeight();
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Page::implicitFooterWidth
    \readonly

    This property holds the implicit footer width.

    The value is equal to \c {footer && footer.visible ? footer.implicitWidth : 0}.

    \sa implicitFooterHeight, implicitHeaderWidth
*/
qreal QQuickPage::implicitFooterWidth() const
{
    Q_D(const QQuickPage);
    if (!d->footer || !d->footer->isVisible())
        return 0;
    return d->footer->implicitWidth();
}

/*!
    \since QtQuick.Controls 2.5 (Qt 5.12)
    \qmlproperty real QtQuick.Controls::Page::implicitFooterHeight
    \readonly

    This property holds the implicit footer height.

    The value is equal to \c {footer && footer.visible ? footer.implicitHeight : 0}.

    \sa implicitFooterWidth, implicitHeaderHeight
*/
qreal QQuickPage::implicitFooterHeight() const
{
    Q_D(const QQuickPage);
    if (!d->footer || !d->footer->isVisible())
        return 0;
    return d->footer->implicitHeight();
}

void QQuickPage::componentComplete()
{
    Q_D(QQuickPage);
    QQuickPane::componentComplete();
    d->relayout();
}

void QQuickPage::spacingChange(qreal newSpacing, qreal oldSpacing)
{
    Q_D(QQuickPage);
    QQuickPane::spacingChange(newSpacing, oldSpacing);
    d->relayout();
}

#if QT_CONFIG(accessibility)
QAccessible::Role QQuickPage::accessibleRole() const
{
    return QAccessible::PageTab;
}

void QQuickPage::accessibilityActiveChanged(bool active)
{
    Q_D(QQuickPage);
    QQuickPane::accessibilityActiveChanged(active);

    if (active)
        maybeSetAccessibleName(d->title);
}
#endif

QT_END_NAMESPACE
