#include "MagicLvCursor.h"

#include "jp/ggaf/core/util/GgafLinkedListRing.hpp"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxAlphaFader.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxKuroko.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxScaler.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxUvFlipper.h"
#include "jp/gecchi/VioletVreath/actor/my/MagicMeter.h"
#include "jp/gecchi/VioletVreath/actor/my/MagicMeter/magic/Magic.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxKurokoMvAssistant.h"

using namespace GgafCore;
using namespace GgafDxCore;
using namespace GgafLib;
using namespace VioletVreath;


MagicLvCursor::MagicLvCursor(const char* prm_name, const char* prm_model, MagicMeter* prm_pMagicMeter, Magic* prm_pMagic) :
        DefaultBoardActor(prm_name, prm_model) {
    _class_name = "MagicLvCursor";
    pAFader_ = NEW GgafDxAlphaFader(this);
    pScaler_ = NEW GgafDxScaler(this);
    pMagicMeter_ = prm_pMagicMeter;
    pMagic_ = prm_pMagic;
    magic_index_ = pMagicMeter_->lstMagic_.indexOf(pMagic_);
    if (magic_index_ < 0) {
        throwGgafCriticalException("prm_pMagic("<<prm_pMagic->getName()<<")は"<<
                                   "MagicMeterに登録されていません。");
    }
    point_lv_ = 0;
    tmp_y_ = _y;
    tmp_alpha_ = _alpha;
    tx_ = 0;
    ty_ = 0;
    setZWriteEnable(false);
}

void MagicLvCursor::initialize() {
    setAlign(ALIGN_CENTER, VALIGN_MIDDLE);
    //MagicMeterの座標が定まってから行うこと
    _x = tx_ = pMagicMeter_->_x + (pMagicMeter_->width_ * magic_index_) + (pMagicMeter_->width_ / 2);
    _y = ty_ = pMagicMeter_->_y - (pMagicMeter_->height_*(point_lv_+1)) + (pMagicMeter_->height_ / 2);
    getUvFlipper()->exec(FLIP_ORDER_LOOP, 1);
    pScaler_->setRange(1000, 3000);
}

void MagicLvCursor::processBehavior() {
    GgafDxKuroko* const pKuroko = getKuroko();
    pKuroko->behave();
    if (pKuroko->asstMv()->hasJustFinishedSliding()) {
        //理想位置に補正
        _x = tx_;
        _y = ty_;
    }
    getUvFlipper()->behave();
    pAFader_->behave();
    pScaler_->behave();
}
void MagicLvCursor::processPreDraw() {
    //カーソル関連は
    //少し早めに薄くなる（消える）ようにした
    //基本はpAFader_、描画時のみロール同期の半透明を考慮
    float rr = pMagicMeter_->r_roll_[magic_index_];
    float alpha_r = rr * 2 - 1.0f;
    if (alpha_r < 0.0f) {
        alpha_r = 0.0f;
    }
    tmp_alpha_ = getAlpha();//退避
    setAlpha(alpha_r*tmp_alpha_*pMagicMeter_->getAlpha());
    //ここで、ロール分Y座標を補正
    tmp_y_ = _y; //退避
    _y += (1.0 * pMagicMeter_->height_ * (point_lv_+1) * (1.0 - rr));
    DefaultBoardActor::processPreDraw();

    //Y座標ロール追従処理を変えたら、MagicLvCursor003::processPreDraw() も同様の変更を！
}

void MagicLvCursor::processAfterDraw() {
    DefaultBoardActor::processAfterDraw();
    _y = tmp_y_; //復帰
    setAlpha(tmp_alpha_); //復帰
    //Y座標ロール追従処理を変えたら、MagicLvCursor003::processAfterDraw() も同様の変更を！
}

void MagicLvCursor::moveTo(int prm_lv) {
    GgafDxKuroko* const pKuroko = getKuroko();
    pKuroko->asstMv()->stopSliding();
    pKuroko->stopMv();
    point_lv_ = prm_lv;
    _x = tx_ = pMagicMeter_->_x + (pMagicMeter_->width_ * magic_index_) + (pMagicMeter_->width_ / 2);
    _y = ty_ = pMagicMeter_->_y - (pMagicMeter_->height_*(point_lv_+1)) + (pMagicMeter_->height_ / 2);
}

void MagicLvCursor::moveSmoothTo(int prm_lv, frame prm_target_frames, float prm_p1, float prm_p2) {
    GgafDxKuroko* const pKuroko = getKuroko();
    pKuroko->stopMv();
    //Y座標のロール（スライド表示）の分考慮せずにY座標のLVカーソル移動計算を行っている。
    //processPreDraw()でロール分を補正する。
    point_lv_ = prm_lv;
    tx_ = pMagicMeter_->_x + (pMagicMeter_->width_ * magic_index_) + (pMagicMeter_->width_ / 2);
    ty_ = pMagicMeter_->_y - (pMagicMeter_->height_*(point_lv_+1)) + (pMagicMeter_->height_ / 2);
    pKuroko->setMvAngTwd(tx_, ty_);
    pKuroko->asstMv()->slideByDt(UTIL::getDistance(_x, _y, tx_, ty_), (int)prm_target_frames,
                                  prm_p1, prm_p2, 0, true); //ロールを考慮せずにとりあえず移動
}

void MagicLvCursor::blink() {
    pAFader_->beat(6, 3, 0, 3, 7.5); //ピカピカ、+0.5は最後は表示終了為
    pScaler_->beat(12, 6, 0, 6, 3);
}

MagicLvCursor::~MagicLvCursor() {
    GGAF_DELETE(pAFader_);
    GGAF_DELETE(pScaler_);
}
