#include "EnemyDuna.h"

#include "jp/ggaf/dx/actor/supporter/AlphaFader.h"
#include "jp/ggaf/dx/actor/supporter/VecDriver.h"
#include "jp/ggaf/dx/actor/supporter/SeTransmitterForActor.h"
#include "jp/ggaf/dx/model/Model.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/dx/actor/supporter/GeoDriver.h"
#include "jp/gecchi/VioletVreath/actor/effect/Blink/EffectBlink.h"

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))

enum {
    MPH_OPEN = 1,
};
enum {
    SE_EXPLOSION ,
};
enum {
    PROG_INIT   ,
    PROG_ENTRY_EFFECT,
    PROG_ENTRY_MOVE01,
    PROG_ENTRY_MOVE02,
    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,
    PROG_CLOSE ,
    PROG_BANPEI,
};

EnemyDuna::EnemyDuna(const char* prm_name) :
        VvEnemyActor<DefaultMorphMeshActor>(prm_name, "Duna_1", StatusReset(EnemyDuna)) {
    _class_name = "EnemyDuna";
    GgafDx::SeTransmitterForActor* pSeTx = getSeTransmitter();
    pSeTx->set(SE_EXPLOSION, "WAVE_EXPLOSION_001");
    effectBlendOne(); //壛嶼崌惉
    setScaleR(0.3);
    nprog_ = 0;
}

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

void EnemyDuna::initialize() {
    CollisionChecker* pChecker = getCollisionChecker();
    pChecker->createCollisionArea(1);
    pChecker->setColliAACube(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 = pMYSHIP;
    GgafDx::VecDriver* const pVecDriver = getVecDriver();
    GgafDx::GeoDriver* const pGeoDriver = getGeoDriver();
    GgafCore::Progress* const pProg = getProgress();
    if (pProg->hasJustChanged()) {
        pGeoDriver->execGravitationMvSequenceTwd(pMyShip, PX_C(3), 30, PX_C(1));
    }

    switch (pProg->get()) {
        case PROG_INIT: {
            setHitAble(false);
            setAlpha(0);
            pVecDriver->linkFaceAngByMvAng(false);
            pVecDriver->keepOnTurningFaceAngTwd(pMyShip,
                                             D_ANG(2), 0, TURN_CLOSE_TO,false);
            //pVecDriver->setMvVelo(RF_EnemyDuna_MvVelo(G_RANK));
            pVecDriver->setMvVelo(PX_C(6));
            pVecDriver->setRzRyMvAng(0, D90ANG);
            pVecDriver->setRzMvAngVelo(D_ANG(12));
            pVecDriver->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)) {
                 getAlphaFader()->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()) {
                 pVecDriver->turnRzRyMvAngTo(0, D180ANG, D_ANG(5), 0, TURN_CLOSE_TO, false);
                 pVecDriver->turnRzRyFaceAngTo(0, D180ANG, D_ANG(5), 0, TURN_CLOSE_TO, false);
             }
             if (!pVecDriver->isTurningMvAng() && !pVecDriver->isTurningFaceAng()) {
                 pVecDriver->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()) {
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv - SEMIARC_ANG,
                                        LARGE_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
             }
             if (!pVecDriver->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()) {
                 //墌屖堏摦
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv + SEMIARC_ANG,
                                        LARGE_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
             }
             if (!pVecDriver->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()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv - D180ANG,
                                        REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !pVecDriver->isTurningMvAng()) {
                 //墌屖堏摦
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv - SEMIARC_ANG,
                                        LARGE_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !pVecDriver->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()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv + D180ANG,
                                        REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !pVecDriver->isTurningMvAng()) {
                 //墌屖堏摦
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv + SEMIARC_ANG,
                                        LARGE_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !pVecDriver->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()) {
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv - SEMIARC_ANG,
                                        SMALL_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
             }
             if (!pVecDriver->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()) {
                 //墌屖堏摦
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv + SEMIARC_ANG,
                                        SMALL_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
             }
             if (!pVecDriver->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()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv - D180ANG,
                                        REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !pVecDriver->isTurningMvAng()) {
                 //墌屖堏摦
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv - SEMIARC_ANG,
                                        SMALL_SEMIARC_ANGVELO, 0, TURN_CLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !pVecDriver->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()) {
                 //傑偢奐巒忬懺偺恀棤曽岦偵岦偔
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv + D180ANG,
                                        REV_TURN_ANGVELO, 0, TURN_CLOSE_TO);
                 nprog_ = 0;
             }
             if (nprog_ == 0 && !pVecDriver->isTurningMvAng()) {
                 //墌屖堏摦
                 pVecDriver->turnRzMvAngTo(pVecDriver->_rz_mv + SEMIARC_ANG,
                                        SMALL_SEMIARC_ANGVELO, 0, TURN_COUNTERCLOCKWISE);
                 nprog_ = 1;
             }
             if (nprog_ == 1 && !pVecDriver->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;
         }
     }

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

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

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

void EnemyDuna::onInactive() {
}

void EnemyDuna::onDispatchedShot(GgafDx::FigureActor* 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() {
}
