/*
 * Copyright(c) Live2D Inc. All rights reserved.
 *
 * Use of this source code is governed by the Live2D Open Software license
 * that can be found at http://live2d.com/eula/live2d-open-software-license-agreement_en.html.
 */

#pragma once

#include "ACubismMotion.hpp"
#include "Type/csmVector.hpp"
#include "Model/CubismUserModel.hpp"

namespace Live2D { namespace Cubism { namespace Framework {

class CubismMotion;

/**
 * @brief CubismMotionQueueManagerで再生している各モーションの管理
 *
 * CubismMotionQueueManagerで再生している各モーションの管理クラス。
 */
class CubismMotionQueueEntry
{
    friend class CubismMotionQueueManager;
    friend class ACubismMotion;
    friend class CubismMotion;

public:
    /**
     * @brief コンストラクタ
     *
     * コンストラクタ。
     */
    CubismMotionQueueEntry();

    /**
     * @brief デストラクタ
     *
     * デストラクタ。
     */
    virtual ~CubismMotionQueueEntry();

    /**
     * @brief フェードアウトの開始
     *
     * フェードアウトを開始する。
     *
     * @param[in]   fadeOutSeconds     フェードアウトにかかる時間[秒]
     * @param[in]   userTimeSeconds    デルタ時間の積算値[秒]
     */
    void        StartFadeout(csmFloat32 fadeOutSeconds, csmFloat32 userTimeSeconds);

    /**
     * @brief モーションの終了の確認
     *
     * モーションが終了したかどうか。
     *
     * @retval  true    モーションが終了した
     * @retval  false   終了していない
     */
    csmBool     IsFinished() const;

    /**
     * @brief モーションの開始の確認
     *
     * モーションが開始したかどうか。
     *
     * @retval  true    モーションが開始した
     * @retval  false   終了していない
     */
    csmBool     IsStarted() const;

    /**
     * @brief モーションの開始時刻の取得
     *
     * モーションの開始時刻を取得する。
     *
     * @return  モーションの開始時刻[秒]
     */
    csmFloat32    GetStartTime() const;

    /**
     * @brief フェードインの開始時刻の取得
     *
     * フェードインの開始時刻を取得する。
     *
     * @return  フェードインの開始時刻[秒]
     */
    csmFloat32    GetFadeInStartTime() const;

    /**
     * @brief フェードインの終了時刻の取得
     *
     * フェードインの終了時刻を取得する。
     *
     * @return  フェードインの終了時刻[秒]
     */
    csmFloat32    GetEndTime() const;

    /**
     * @brief モーションの開始時刻の設定
     *
     * モーションの開始時刻を設定する。
     *
     * @param[in]   t   モーションの開始時刻[秒]
     */
    void        SetStartTime(csmFloat32 startTime);

    /**
     * @brief フェードインの開始時刻の設定
     *
     * フェードインの開始時刻を設定する。
     *
     * @param[in]   t   フェードインの開始時刻[秒]
     */
    void        SetFadeInStartTime(csmFloat32 startTime);

    /**
     * @brief フェードインの終了時刻の設定
     *
     * フェードインの終了時刻を設定する。
     *
     * @param[in]   t   フェードインの終了時刻[秒]
     */
    void        SetEndTime(csmFloat32 endTime);

    /**
     * @brief モーションの終了の設定
     *
     * モーションの終了を設定する。
     *
     * @param[in]   f   trueならモーションの終了
     */
    void        IsFinished(csmBool f);

    /**
     * @brief モーションの開始の設定
     *
     * モーションの開始を設定する。
     *
     * @param[in]   f   trueならモーションの開始
     */
    void        IsStarted(csmBool f);

    /**
     * @brief モーションの有効性の確認
     *
     * モーションの有効・無効を取得する。
     *
     * @retval  true    モーションは有効
     * @retval  false   モーションは無効
     */
    csmBool     IsAvailable() const;

    /**
     * @brief モーションの有効性の設定
     *
     * モーションの有効・無効を設定する。
     *
     * @param[in]   v   trueならモーションは有効
     */
    void        IsAvailable(csmBool v);

    /**
     * @brief モーションの状態の設定
     *
     * モーションの状態を設定する。
     *
     * @param[in]   time    現在時刻[秒]
     * @param[in]   weight  モーションの重み
     */
    void        SetState(csmFloat32 timeSeconds, csmFloat32 weight);

    /**
     * @brief モーションの現在時刻の取得
     *
     * モーションの現在時刻を取得する。
     *
     * @return  モーションの現在時刻[秒]
     */
    csmFloat32  GetStateTime() const;

    /**
     * @brief モーションの重みの取得
     *
     * モーションの重みを取得する。
     *
     * @return  モーションの重み
     */
    csmFloat32  GetStateWeight() const;

    /**
    * @brief 最後にイベントの発火をチェックした時間を取得
    *
    * 最後にイベントの発火をチェックした時間を取得する。
    *
    * @return  最後にイベントの発火をチェックした時間[秒]
    */
    csmFloat32  GetLastCheckEventTime() const;

    /**
    * @brief 最後にイベントをチェックした時間を設定
    *
    * 最後にイベントをチェックした時間を設定する。
    *
    * @param[in]    checkTime   最後にイベントをチェックした時間[秒]
    */
    void        SetLastCheckEventTime(csmFloat32 checkTime);

private:
    csmBool         _autoDelete;                    ///< 自動削除
    ACubismMotion*  _motion;                        ///< モーション

    csmBool         _available;                     ///< 有効化フラグ
    csmBool         _finished;                      ///< 終了フラグ
    csmBool         _started;                       ///< 開始フラグ（0.9.00以降）
    csmFloat32      _startTimeSeconds;              ///<  モーション再生開始時刻[秒]
    csmFloat32      _fadeInStartTimeSeconds;        ///<  フェードイン開始時刻（ループの時は初回のみ）[秒]
    csmFloat32      _endTimeSeconds;                ///< 終了予定時刻[秒]
    csmFloat32      _stateTimeSeconds;              ///<  時刻の状態[秒]
    csmFloat32      _stateWeight;                   ///<  重みの状態
    csmFloat32      _lastEventCheckSeconds;         ///<   最終のMotion側のチェックした時間

    CubismMotionQueueEntryHandle  _motionQueueEntryHandle;        ///< インスタンスごとに一意の値を持つ識別番号
};

}}}
