#include "EnemyDuna.h"

#include "jp/ggaf/dxcore/actor/supporter/GgafDxAlphaFader.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxKuroko.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxSeTransmitterForActor.h"
#include "jp/ggaf/dxcore/model/GgafDxModel.h"
#include "jp/ggaf/lib/util/CollisionChecker.h"
#include "jp/gecchi/VioletVreath/GameGlobal.h"
#include "jp/gecchi/VioletVreath/God.h"
#include "jp/gecchi/VioletVreath/scene/Spacetime/World/GameScene/MyShipScene.h"
#include "jp/gecchi/VioletVreath/util/MyStgUtil.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxAxesMover.h"

#include "jp/gecchi/VioletVreath/actor/effect/Blink/EffectBlink.h"
using namespace GgafCore;
using namespace GgafDxCore;
using namespace GgafLib;
using namespace VioletVreath;

#define REV_TURN_ANGVELO (D_ANG(30))
#define LARGE_SEMIARC_ANGVELO (D_ANG(3))
#define SMALL_SEMIARC_ANGVELO (D_ANG(6))
#define SEMIARC_ANG (D_ANG(200))
EnemyDuna::EnemyDuna(const char* prm_name) :
        DefaultMorphMeshActor(prm_name, "1/Duna", STATUS(EnemyDuna)) {
    _class_name = "EnemyDuna";
    pAFader_ = NEW GgafDxAlphaFader(this);
    pAxsMver_ = NEW GgafDxAxesMover(this);
    GgafDxSeTransmitterForActor* pSe = getSeTransmitter();
    pSe->set(SE_EXPLOSION, "WAVE_EXPLOSION_001");
    effectBlendOne(); //壛嶼崌惉
    setScaleR(0.3);
    useProgress(PROG_BANPEI);
}

void EnemyDuna::onCreateModel() {
    GgafDxModel* pModel = getModel();
    pModel->setSpecular(5.0, 1.0);
}

void EnemyDuna::initialize() {
    CollisionChecker* pChecker = getCollisionChecker();
    pChecker->createCollisionArea(1);
    pChecker->setColliAABox_Cube(0, 40000);
}

void EnemyDuna::onActive() {
    getStatus()->reset();
    getProgress()->reset(PROG_INIT);
}

void EnemyDuna::processBehavior() {
//    if (pProg->hasJustChanged()) {
//        _TRACE_("EnemyDuna::"<<pProg->getFromProgOnChange()<<"仺"<<pProg->get()<<"");
//    }

    MyShip* pMyShip = P_MYSHIP;
    GgafDxKuroko* const pKuroko = getKuroko();
    GgafProgress* const pProg = getProgress();
    if (pProg->hasJustChanged()) {
        pAxsMver_->execGravitationMvSequenceTwd(pMyShip, PX_C(3), 30, PX_C(1));
    }

    switch (pProg->get()) {
        case PROG_INIT: {
            setHitAble(false);
            setAlpha(0);
            pKuroko->linkFaceAngByMvAng(false);
            pKuroko->keepOnTurningFaceAngTwd(pMyShip,
                                             D_ANG(2), 0, TURN_CLOSE_TO,false);
            //pKuroko->setMvVelo(RF_EnemyDuna_MvVelo(G_RANK));
            pKuroko->setMvVelo(PX_C(6));
            pKuroko->setRzRyMvAng(0, D90ANG);
            pKuroko->setRzMvAngVelo(D_ANG(12));
            pKuroko->setRzMvAngAcce(D_ANG(0.05));
            setMorphWeight(0.0);
            pProg->changeNext();
            break;
        }
         case PROG_ENTRY_EFFECT: {
             EffectBlink* pEffectEntry = nullptr;
             if (pProg->hasJustChanged()) {
                 pEffectEntry = UTIL::activateEntryEffectOf(this);
             }
             static const frame frame_of_summons_begin = pEffectEntry->getFrameOfSummonsBegin();
             static const frame frame_of_entering = pEffectEntry->getSummoningFrames() + frame_of_summons_begin;
             if (pProg->hasArrivedAt(frame_of_summons_begin)) {
                 pAFader_->transitionLinearUntil(1.0, frame_of_entering);
             }
             if (pProg->hasArrivedAt(frame_of_entering)) {
                 setHitAble(true);
                 pProg->changeNext();
             }
             break;
         }
         case PROG_ENTRY_MOVE01: {
             if (pProg->hasJustChanged()) {
             }
             _x -= PX_C(10);
             if (_x < pMyShip->_x + PX_C(1000)) {
                 pProg->changeNext();
             }
             break;
         }
         case PROG_ENTRY_MOVE02: {
             if (pProg->hasJustChanged()) {
                 pKuroko->turnRzRyMvAngTo(0, D180ANG, D_ANG(5), 0, TURN_CLOSE_TO, false);
                 pKuroko->turnRzRyFaceAngTo(0, D180ANG, D_ANG(5), 0, TURN_CLOSE_TO, false);
             }
             if (!pKuroko->isTurningMvAng() && !pKuroko->isTurningFaceAng()) {
                 pKuroko->linkFaceAngByMvAng(true);
                 pProg->changeProbab(
                              0, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,
                             25, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW,
                             25, PROG_MOVE_REV_LARGE_SEMIARC_CW,
                              0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,
                              0, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,
                             25, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW,
                             25, PROG_MOVE_REV_SMALL_SEMIARC_CW,
                              0, PROG_MOVE_REV_SMALL_SEMIARC_CCW
                         );
             }
             break;
         }

         //  捈慜偺堏摦偑
         //
         //      | 仾        伀 |        |仾  伀|
         //       乢          乛    or    乢仼乛
         //         乢  仼  乛              丳
         //           丳丳丳
         //  偩偭偨応崌
         //             仺
         //           丵丵丵                         仺
         //         乛  仼  乢                       丵
         //       乛          乢                   乛仼乢
         //   仾 | 伀        仾 | 伀           仾 |伀  仾| 伀
         //   嘆             嘇                嘍      嘐
         //
         //
         //   嘋             嘊                嘒      嘑
         //   伀 | 仾        伀 |  仾          伀 |仾  伀| 仾
         //       乢          乛                   乢仼乛
         //         乢  仼  乛                       丳
         //           丳丳丳                         仺
         //             仺
         //
         //  嘆 丒丒丒 PROG_MOVE_ORDER_LARGE_SEMIARC_CW       弴曽岦丄  戝墌屖堏摦丄帪寁夞傝
         //  嘇 丒丒丒 PROG_MOVE_ORDER_LARGE_SEMIARC_CCW      弴曽岦丄  戝墌屖堏摦丄敿帪寁夞傝
         //  嘊 丒丒丒 PROG_MOVE_REV_LARGE_SEMIARC_CW         曽岦斀揮丄戝墌屖堏摦丄帪寁夞傝
         //  嘋 丒丒丒 PROG_MOVE_REV_LARGE_SEMIARC_CCW        曽岦斀揮丄戝墌屖堏摦丄敿帪寁夞傝
         //  嘍 丒丒丒 PROG_MOVE_ORDER_SMALL_SEMIARC_CW       弴曽岦丄  彫墌屖堏摦丄帪寁夞傝
         //  嘐 丒丒丒 PROG_MOVE_ORDER_SMALL_SEMIARC_CCW      弴曽岦丄  彫墌屖堏摦丄敿帪寁夞傝
         //  嘑 丒丒丒 PROG_MOVE_REV_SMALL_SEMIARC_CW         曽岦斀揮丄彫墌屖堏摦丄帪寁夞傝
         //  嘒 丒丒丒 PROG_MOVE_REV_SMALL_SEMIARC_CCW        曽岦斀揮丄彫墌屖堏摦丄敿帪寁夞傝

         case PROG_MOVE_ORDER_LARGE_SEMIARC_CW: {  //嘆
             if (pProg->hasJustChanged()) {
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv - SEMIARC_ANG,
                                        LARGE_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
             }
             if (!pKuroko->isTurningMvAng()) {
                 //嘆偺師偺摦嶌
                 pProg->changeProbab(
                               0, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                              10, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                              15, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                              15, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                         );
             }
             break;
         }

         case PROG_MOVE_ORDER_LARGE_SEMIARC_CCW: { //嘇
             if (pProg->hasJustChanged()) {
                 //墌屖堏摦
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv + SEMIARC_ANG,
                                        LARGE_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
             }
             if (!pKuroko->isTurningMvAng()) {
                 //嘇偺師偺摦嶌
                 pProg->changeProbab(
                              10, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                               0, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                              15, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                              15, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                         );
             }
             break;
         }
         case PROG_MOVE_REV_LARGE_SEMIARC_CW: {  //嘊
             if (pProg->hasJustChanged()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv - D180ANG,
                                        REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !pKuroko->isTurningMvAng()) {
                 //墌屖堏摦
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv - SEMIARC_ANG,
                                        LARGE_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !pKuroko->isTurningMvAng()) {
                 //嘊偺師偺摦嶌
                 pProg->changeProbab(
                               0, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                              10, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                              15, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                              15, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                         );
             }
             break;
         }
         case PROG_MOVE_REV_LARGE_SEMIARC_CCW: {  //嘋
             if (pProg->hasJustChanged()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv + D180ANG,
                                        REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !pKuroko->isTurningMvAng()) {
                 //墌屖堏摦
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv + SEMIARC_ANG,
                                        LARGE_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !pKuroko->isTurningMvAng()) {
                 //嘋偺師偺摦嶌
                 pProg->changeProbab(
                              10, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                               0, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                              15, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                              15, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                         );
             }
             break;
         }






         case PROG_MOVE_ORDER_SMALL_SEMIARC_CW: {  //嘍
             if (pProg->hasJustChanged()) {
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv - SEMIARC_ANG,
                                        SMALL_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
             }
             if (!pKuroko->isTurningMvAng()) {
                 //嘍偺師偺摦嶌
                 pProg->changeProbab(
                               0, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                              40, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                              30, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                               0, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                               0, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                               0, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                         );
             }
             break;
         }

         case PROG_MOVE_ORDER_SMALL_SEMIARC_CCW: { //嘐
             if (pProg->hasJustChanged()) {
                 //墌屖堏摦
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv + SEMIARC_ANG,
                                        SMALL_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
             }
             if (!pKuroko->isTurningMvAng()) {
                 //嘐偺師偺摦嶌
                 pProg->changeProbab(
                              40, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                               0, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                              30, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                               0, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                               0, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                               0, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                         );
             }
             break;
         }
         case PROG_MOVE_REV_SMALL_SEMIARC_CW: {  //嘑
             if (pProg->hasJustChanged()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv - D180ANG,
                                        REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !pKuroko->isTurningMvAng()) {
                 //墌屖堏摦
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv - SEMIARC_ANG,
                                        SMALL_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !pKuroko->isTurningMvAng()) {
                 //嘑偺師偺摦嶌
                 pProg->changeProbab(
                               0, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                              40, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                              30, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                               0, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                               0, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                               0, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                         );
             }
             break;
         }
         case PROG_MOVE_REV_SMALL_SEMIARC_CCW: {  //嘒
             if (pProg->hasJustChanged()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv + D180ANG,
                                        REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !pKuroko->isTurningMvAng()) {
                 //墌屖堏摦
                 pKuroko->turnRzMvAngTo(pKuroko->_rz_mv + SEMIARC_ANG,
                                        SMALL_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !pKuroko->isTurningMvAng()) {
                 //嘒偺師偺摦嶌
                 pProg->changeProbab(
                              40, PROG_MOVE_ORDER_LARGE_SEMIARC_CW,  //  嘆
                               0, PROG_MOVE_ORDER_LARGE_SEMIARC_CCW, //  嘇
                              30, PROG_MOVE_REV_LARGE_SEMIARC_CW,    //  嘊
                               0, PROG_MOVE_REV_LARGE_SEMIARC_CCW,   //  嘋
                              30, PROG_MOVE_ORDER_SMALL_SEMIARC_CW,  //  嘍
                               0, PROG_MOVE_ORDER_SMALL_SEMIARC_CCW, //  嘐
                               0, PROG_MOVE_REV_SMALL_SEMIARC_CW,    //  嘑
                               0, PROG_MOVE_REV_SMALL_SEMIARC_CCW    //  嘒
                         );
             }
             break;
         }

         default: {
             break;
         }
     }

    pKuroko->behave();
    pAxsMver_->behave();
    getMorpher()->behave();
    pAFader_->behave();
//_TRACE_("EnemyDuna f:"<<getBehaveingFrame()<<"  pProg="<<pProg->get()<<"   X,Y,Z="<<_x<<","<<_y<<","<<_z<<" ");
}

void EnemyDuna::processJudgement() {
    if (isOutOfSpacetime()) {
        sayonara();
    }
}

void EnemyDuna::onHit(const GgafActor* prm_pOtherActor) {
    bool was_destroyed = UTIL::performEnemyHit(this, (const GgafDxGeometricActor*)prm_pOtherActor);
    if (was_destroyed) {
        //攋夡偝傟偨帪(僗僞儈僫 <= 0)
        getSeTransmitter()->play3D(SE_EXPLOSION);
        sayonara();
    } else {
        //攋夡偝傟側偐偭偨帪(僗僞儈僫 > 0)
    }
}

void EnemyDuna::onInactive() {
}

void EnemyDuna::onDispatchedShot(GgafDxCore::GgafDxFigureActor* prm_pActor, int prm_dispatch_num, int prm_set_index, int prm_way_index) {
    prm_pActor->activateDelay(prm_way_index*5 + 1); //activate 忋彂偒丅num_fire_*5 偺 5 偲摨偠抣偵偡傞偙偲
}

EnemyDuna::~EnemyDuna() {
    GGAF_DELETE(pAFader_);
    GGAF_DELETE(pAxsMver_);
}
