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

namespace Live2D { namespace Cubism { namespace Framework {

class CubismModel;
struct CubismPhysicsRig;

/**
 * @brief 物理演算クラス
 * 
 * 物理演算のクラス。
 */
class CubismPhysics
{
public:
    /**
     * @brief オプション
     * 
     * 物理演算のオプション。
     */
    struct Options
    {
        CubismVector2 Gravity;          ///< 重力方向
        CubismVector2 Wind;             ///< 風の方向
    };

    /**
     * @brief インスタンスの作成
     * 
     * インスタンスを作成する。
     * 
     * @param[in]   buffer      physics3.jsonが読み込まれいるバッファ
     * @param[in]   size        バッファのサイズ
     * @return  作成されたインスタンス
     */
    static CubismPhysics* Create(const csmByte* buffer, csmSizeInt size);

    /**
     * @brief インスタンスの破棄
     * 
     * インスタンスを破棄する。
     * 
     * @param[in]   physics     破棄するインスタンス
     */
    static void Delete(CubismPhysics* physics);

    /**
     * @brief 物理演算の評価
     * 
     * 物理演算を評価する。
     * 
     * @param[in]   model               物理演算の結果を適用するモデル
     * @param[in]   deltaTimeSeconds    デルタ時間[秒]
     */
    void Evaluate(CubismModel* model, csmFloat32 deltaTimeSeconds);

    /**
     * @brief オプションの設定
     * 
     * オプションを設定する。
     * 
     * @param[in]   options     オプション
     */
    void SetOptions(const Options& options);

    /**
     * @brief オプションの取得
     * 
     * オプションを取得する。
     * 
     * @return オプション
     */
    const Options& GetOptions() const;


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

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

    // Prevention of copy Constructor
    CubismPhysics(const CubismPhysics&);
    CubismPhysics& operator=(const CubismPhysics&);

    /**
     * @brief physics3.jsonのパース
     * 
     * physics3.jsonをパースする。
     * 
     * @param[in]   physicsJson     physics3.jsonが読み込まれいるバッファ
     * @param[in]   size            バッファのサイズ
     */
    void Parse(const csmByte* physicsJson, csmSizeInt size);

    /**
     * @brief 初期化
     * 
     * 初期化する。
     */
    void Initialize();

    CubismPhysicsRig*   _physicsRig;          ///< 物理演算のデータ
    Options             _options;             ///< オプション
};

}}}
