/*
 * 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 "CubismFramework.hpp"

namespace Live2D { namespace Cubism { namespace Framework {

/**
 * @brief モーションカーブの種類
 * 
 * モーションカーブの種類。
 */
enum CubismMotionCurveTarget
{
    CubismMotionCurveTarget_Model,          ///< モデルに対して
    CubismMotionCurveTarget_Parameter,      ///< パラメータに対して
    CubismMotionCurveTarget_PartOpacity     ///< パーツの不透明度に対して
};


/**
 * @brief モーションカーブのセグメントの種類
 * 
 * モーションカーブのセグメントの種類。
 */
enum CubismMotionSegmentType
{
    CubismMotionSegmentType_Linear = 0,         ///< リニア
    CubismMotionSegmentType_Bezier = 1,         ///< ベジェ曲線
    CubismMotionSegmentType_Stepped = 2,        ///< ステップ
    CubismMotionSegmentType_InverseStepped = 3  ///< インバースステップ
};

/**
 * @brief モーションカーブの制御点
 * 
 * モーションカーブの制御点。
 */
struct CubismMotionPoint
{
    CubismMotionPoint()
        : Time(0.0f)
        , Value(0.0f)
    { }
            
    csmFloat32 Time;         ///< 時間[秒]
    csmFloat32 Value;        ///< 値
};

/**
 * @brief モーションカーブのセグメントの評価関数
 * 
 * モーションカーブのセグメントの評価関数。
 * 
 * @param[in]   points      モーションカーブの制御点リスト
 * @param[in]   time        評価する時間[秒]
 */
typedef csmFloat32 (*csmMotionSegmentEvaluationFunction)(const CubismMotionPoint* points, const csmFloat32 time);


/**
 * @brief モーションカーブのセグメント
 * 
 * モーションカーブのセグメント。
 */
struct CubismMotionSegment
{
    /**
     * @brief コンストラクタ
     * 
     * コンストラクタ。
     */
    CubismMotionSegment()
        : Evaluate(NULL)
        , BasePointIndex(0)
        , SegmentType(0)
    { }

    csmMotionSegmentEvaluationFunction Evaluate;            ///< 使用する評価関数
    csmInt32 BasePointIndex;                                ///< 最初のセグメントへのインデックス
    csmInt32 SegmentType;                                   ///< セグメントの種類
};

/**
 * @brief モーションカーブ
 * 
 * モーションカーブ。
 */
struct CubismMotionCurve
{
    CubismMotionCurve()
        : Type(CubismMotionCurveTarget_Model)
        , SegmentCount(0)
        , BaseSegmentIndex(0)
        , FadeInTime(0.0f)
        , FadeOutTime(0.0f)
    { }

    CubismMotionCurveTarget Type;               ///< カーブの種類
    CubismIdHandle Id;                               ///< カーブのID
    csmInt32 SegmentCount;                      ///< セグメントの個数
    csmInt32 BaseSegmentIndex;                  ///< 最初のセグメントのインデックス
    csmFloat32 FadeInTime;                      ///< フェードインにかかる時間[秒]
    csmFloat32 FadeOutTime;                     ///< フェードアウトにかかる時間[秒]
};

/**
* @brief イベント
*
* イベント。
*/
struct CubismMotionEvent
{
    CubismMotionEvent()
        : FireTime(0.0f)
    { }
        
    csmFloat32  FireTime;
    csmString   Value;
};

/**
 * @brief モーションデータ
 * 
 * モーションデータ。
 */
struct CubismMotionData
{
    CubismMotionData()
        : Duration(0.0f)
        , Loop(0)
        , CurveCount(0)
        , EventCount(0)
        , Fps(0.0f)
    { }

    csmFloat32 Duration;                                ///< モーションの長さ[秒]
    csmInt16 Loop;                                  ///< ループするかどうか
    csmInt16 CurveCount;                            ///< カーブの個数
    csmInt32 EventCount;                         ///< UserDataの個数
    csmFloat32 Fps;                              ///< フレームレート
    csmVector<CubismMotionCurve> Curves;                ///< カーブのリスト
    csmVector<CubismMotionSegment> Segments;            ///< セグメントのリスト
    csmVector<CubismMotionPoint> Points;                ///< ポイントのリスト
    csmVector<CubismMotionEvent> Events;          ///< イベントのリスト
};

}}}
