/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of Qt 3D Studio.
**
** $QT_BEGIN_LICENSE:GPL$
** 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 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** 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$
**
****************************************************************************/

#ifndef Q3DSSLIDEPLAYER_OG_P_H
#define Q3DSSLIDEPLAYER_OG_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists for the convenience
// of a number of Qt sources files.  This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//

#include <QObject>

#include "q3dsuippresentation_p.h"
#include "q3dsscenemanager_p.h"
#include <QtCore/qvector.h>
#include "q3dsabstractslideplayer_p.h"

QT_BEGIN_NAMESPACE

class Q3DSAnimationManager;
class Q3DSSlideDeck;
class Q3DSSceneManager;

class Q3DSV_PRIVATE_EXPORT Q3DSSlidePlayer : public Q3DSAbstractSlidePlayer
{
    Q_OBJECT

public:
    Q3DSSlidePlayer(Q3DSSceneManager *sceneManager,
                    Q3DSAbstractSlidePlayer *parent = nullptr);
    ~Q3DSSlidePlayer() override;

    Q3DSSlideDeck *slideDeck() const override;
    void advanceFrame(float) override;
    void sceneReady() override;

    float duration() const override;
    float position() const override;
    PlayerState state() const override { return m_data.state; }

    void setMode(PlayerMode mode) override;
    PlayerMode mode() const override { return m_mode; }

    void objectAboutToBeAddedToScene(Q3DSGraphObject *obj) override;
    void objectAboutToBeRemovedFromScene(Q3DSGraphObject *obj) override;

    void objectAddedToSlide(Q3DSGraphObject *obj, Q3DSSlide *slide) override;
    void objectRemovedFromSlide(Q3DSGraphObject *obj, Q3DSSlide *slide) override;

    float playbackRate() const override;

public Q_SLOTS:
    void play() override;
    void stop() override;
    void pause() override;
    void seek(float) override;
    void setSlideDeck(Q3DSSlideDeck *slideDeck) override;
    void setPlaybackRate(float rate) override;
    void nextSlide() override;
    void previousSlide() override;
    void precedingSlide() override;
    void reload() override;

private:
    Q3DSSlidePlayer(QSharedPointer<Q3DSAnimationManager> animationManager,
                    Q3DSSceneManager *sceneManager,
                    Q3DSComponentNode *component,
                    Q3DSAbstractSlidePlayer *parent = nullptr);

    void init();
    void reset();
    void setInternalState(PlayerState state);
    void onDurationChanged(float duration);
    void onSlideFinished(Q3DSSlide *slide);
    void setSlideTime(Q3DSSlide *slide, float time, bool forceUpdate = false);

    void handleCurrentSlideChanged(Q3DSSlide *slide,
                                   Q3DSSlide *previousSlide,
                                   bool forceUpdate = false);

    // TODO: Move out to a "slide manager"?
    void sendPositionChanged(Q3DSSlide *slide, float pos);
    void setObjectVisibility(Q3DSGraphObject *obj, bool parentVisible, bool forceUpdate, float time);
    void updateObjectVisibility(Q3DSGraphObject *obj, bool visible, float time);
    bool isSlideVisible(Q3DSSlide *slide);
    void processPropertyChanges(Q3DSSlide *currentSlide, Q3DSSlide *previousSlide);
    void evaluateDynamicObjectVisibility(Q3DSGraphObject *obj);
    void flushQueuedCalls();

    struct Data {
        Q3DSSlideDeck *slideDeck = nullptr;
        PlayerState state = PlayerState::Idle;
        PlayerState pendingState = PlayerState::Idle;
        float position = 0.0f;
        float duration = 0.0f;
        float playbackRate = 1.0f;
        int loopCount = 0;
    } m_data;

    Q3DSSceneManager *m_sceneManager;
    Q3DSComponentNode *m_component = nullptr;
    QSharedPointer<Q3DSAnimationManager> m_animationManager;
    PlayerMode m_mode = PlayerMode::Viewer;
    PlayerType m_type = PlayerType::Scene;
    QVector<std::function<void()>> m_queuedCalls;

    // This class handles animation callback from animationmanager and calls setSlideTime
    friend class Q3DSSlidePositionCallback;
    friend class Q3DSSceneManager;
};

QT_END_NAMESPACE

#endif // Q3DSSLIDEPLAYER_OG_P_H
