/*************************************************************//**
     *
     *  @brief  生成処理を行う
     *  @param  射撃者
     *  @param  インデックス
     *  @param  情報
     *  @return 銃
     *
     ****************************************************************/
    C_BaseGun* C_OptionSmallBeamGunFactory::Create(C_Shooter* pShooter, int32_t index, void* pData)
    {
        // プレイヤーの情報を取得
        assert(JSON::C_JsonObjectManager::s_GetInstance()->GetJsonObject(ID::JSON::s_pSMALL_BEAM_OPTION));
        auto pOptionData = JSON::C_JsonObjectManager::s_GetInstance()->GetJsonObject(ID::JSON::s_pSMALL_BEAM_OPTION).get();

        auto pGun = newEx C_NormalGun(pShooter);

        auto direction = Physics::Vector3(static_cast<float>((*pOptionData)["GunDatas"][index]["Direction"][0].GetValue<JSON::Real>()),
                                          static_cast<float>((*pOptionData)["GunDatas"][index]["Direction"][1].GetValue<JSON::Real>()),
                                          static_cast<float>((*pOptionData)["GunDatas"][index]["Direction"][2].GetValue<JSON::Real>()));

        auto offsetFromShooter = Physics::Vector3(static_cast<float>((*pOptionData)["GunDatas"][index]["OffsetFromShooter"][0].GetValue<JSON::Real>()),
                                                  static_cast<float>((*pOptionData)["GunDatas"][index]["OffsetFromShooter"][1].GetValue<JSON::Real>()),
                                                  static_cast<float>((*pOptionData)["GunDatas"][index]["OffsetFromShooter"][2].GetValue<JSON::Real>()));

        pGun->SetShotLogic(newEx C_InputShotLogic((*pOptionData)["GunDatas"][index]["ShotInterval"].GetValue<JSON::Integer>()));
        pGun->SetBulletId((*pOptionData)["GunDatas"][index]["BulletId"].GetValue<JSON::String>());
        pGun->SetBulletPower(newEx C_BasePower((*pOptionData)["GunDatas"][index]["BulletPower"].GetValue<JSON::Integer>()));

        auto pMoveLogic = newEx C_RigidBodyStraightMoveLogic;

        pMoveLogic->SetDirection(direction);
        pMoveLogic->SetMovement(static_cast<float>((*pOptionData)["GunDatas"][index]["BulletMovement"].GetValue<JSON::Real>()));

        pGun->SetBulletMoveLogic(pMoveLogic);

        pGun->SetOffsetFromShooter(offsetFromShooter);
        pGun->SetDirection(direction);

        return pGun;
    }
/*************************************************************//**
 *
 *  @brief  生成処理を行う
 *  @param  なし
 *  @return 銃
 *
 ****************************************************************/
C_BaseGun* C_Stage01BossGunFactory01::Create(C_Shooter* pShooter)
{
    auto pGun = newEx C_NormalGun(pShooter);

    pGun->SetShotLogic(newEx C_EvenIntervalShotLogic(90, 30, C_EvenIntervalShotLogic::s_INFINITE_SHOT_COUNT));
    pGun->SetBulletId(GameObjectDefine::Id::s_STAGE_01_BOSS_NORMAL_BULLET);
    pGun->SetBulletPower(newEx C_BasePower(300));
    pGun->SetBulletMoveLogic(newEx C_StraightMoveLogic(0.09f, 1.0f, UtilityMath::S_Vector3<>::s_DOWN_DIRECTION));
    pGun->SetShotOffset(UtilityMath::S_Vector3<>(1.2f, -2.2f, 0.0f));
    pGun->SetAutoBulletFowardDirectionFlag(false);
    
    return pGun;
}
/*************************************************************//**
 *
 *  @brief  生成処理を行う
 *  @param  なし
 *  @return 銃
 *
 ****************************************************************/
C_BaseGun* C_Stage01BossGunFactory02::Create(C_Shooter* pShooter)
{
    auto pGun = newEx C_RapidFireGun(pShooter, 40);

    // TODO 無駄なのでなんらかで対処すること
    pGun->SetShotLogic(newEx C_ArbitraryShotLogic(1, [](){ return true; }));

    pGun->SetBulletId(GameObjectDefine::Id::s_STAGE_01_BOSS_LASER_BULLET);
    pGun->SetBulletPower(newEx C_BasePower(1000));
    pGun->SetBulletMoveLogic(newEx C_StraightMoveLogic(0.3f, 1.0f, UtilityMath::S_Vector3<>::s_DOWN_DIRECTION));
    pGun->SetShotOffset(UtilityMath::S_Vector3<>(0.0f, -2.2f, 0.0f));
    pGun->SetAutoBulletFowardDirectionFlag(false);
    
    return pGun;
}
/*************************************************************//**
 *
 *  @brief  コンストラクタ
 *  @param  ID
 *  @param  種類
 *  @param  座標
 *
 ****************************************************************/
C_Stage01Boss::C_Stage01Boss(const std::string& rId,
                             int32_t type,
                             const C_GameObject::Vector3& rPosition) : C_BaseBoss(rId, type, rPosition),

    // ステートマシーン
    upStateMachine_(std::make_unique<C_StateMachine<C_Stage01Boss>>(this))

{
    // 初期のステートを設定
    upStateMachine_->SetCurrentState(C_Stage01BossAppearanceState::s_GetInstance());

    // 各ロジックを生成
    upDirectionMoveLogic_ = std::make_unique<C_InterpolationMoveLogic>(1.0f,
                                                                       1.0f,
                                                                       Vector3::s_DOWN_DIRECTION, 
                                                                       UtilityMath::C_Easing<>::s_Linear, 
                                                                       300,
                                                                       rPosition,
                                                                       Vector3(0.0f, 4.0f, 0.0f));

    rotation_ = Vector3(0.0f, 0.0f, static_cast<float>(UtilityMath::s_PI_DIVISION2));

    upDirectionRotateLogic_ = std::make_unique<C_InterpolationRotateLogic>(1.0f,
                                                                           UtilityMath::C_Easing<>::s_Linear,
                                                                           300,
                                                                           rotation_,
                                                                           Vector3());

    auto pPlayer = C_GameObjectManager::s_GetManagementInstance().GetGameObjectsWithType(GameObjectDefine::PLAYER);
    assert(pPlayer.size() == 1);

    wpPlayer_ = std::dynamic_pointer_cast<C_BasePlayer>(pPlayer[0]);

    upMoveLogic_ = std::make_unique<C_TargetHomingMoveLogic>(1.0f, 1.0f, Vector3::s_DOWN_DIRECTION, pPlayer[0], this, true, false, 60, 100);

    C_Stage01BossGunFactory01 factory01;
    upNormalGuns_.emplace_back(factory01.Create(this));
    auto tempNormalGun = factory01.Create(this);
    tempNormalGun->SetShotOffset(UtilityMath::S_Vector3<>(-1.2f, -2.2f, 0.0f));
    upNormalGuns_.emplace_back(tempNormalGun);

    C_Stage01BossGunFactory02 factory02;
    auto tempLaserGun = factory02.Create(this);
    tempLaserGun->SetShotLogic(newEx C_ArbitraryShotLogic(1, [&]()->bool{ return dynamic_cast<C_TargetHomingMoveLogic*>(upMoveLogic_.get())->IsWaitStartFlag(); }));
    upLaserGun_.reset(tempLaserGun);

    // ヒットポイントを生成
    C_Shooter::upHitPoint_ = std::make_unique<C_DifficultyHitPoint>(1000000, GameDefine::EASY);

    // シェーダー・モデル・カメラを取得
    assert(C_ShaderManager::s_GetInstance()->GetShader(GameDefine::Id::s_pPHONG_SHADER));
    assert(C_ModelManager::s_GetManagementInstance().GetModel(GameDefine::Id::s_pSTAGE_01_BOSS_MODEL));
    assert(C_CameraManager::s_GetInstance()->GetCamera(GameDefine::Id::s_pMAIN_CAMERA));

    pShader_ = C_ShaderManager::s_GetInstance()->GetShader(GameDefine::Id::s_pPHONG_SHADER).get();
    pModel_ = C_ModelManager::s_GetManagementInstance().GetModel(GameDefine::Id::s_pSTAGE_01_BOSS_MODEL).get();
    pCamera_ = C_CameraManager::s_GetInstance()->GetCamera(GameDefine::Id::s_pMAIN_CAMERA).get();

    boundingBoxHalfWidth_ = 1.7f;
    boundingBoxHalfHeight_ = 1.7f;

    // 境界ボックスを更新 
    // TODO 演出中には更新させてはならない
    // UpdateBoundingBox();

    pColliders_.emplace_back(newEx C_CircleCollider<>(IC_Collider2D<>::Vector2(position_.x_, position_.y_), 1.7f));
}