#include "jp/ggaf/dxcore/actor/GgafDxSpriteActor.h"

#include "jp/ggaf/dxcore/exception/GgafDxCriticalException.h"
#include "jp/ggaf/dxcore/GgafDxGod.h"
#include "jp/ggaf/dxcore/util/GgafDxUtil.h"
#include "jp/ggaf/dxcore/effect/GgafDxSpriteEffect.h"
#include "jp/ggaf/dxcore/model/GgafDxSpriteModel.h"
#include "jp/ggaf/dxcore/manager/GgafDxTextureConnection.h"
#include "jp/ggaf/dxcore/actor/supporter/GgafDxUvFlipper.h"

using namespace GgafCore;
using namespace GgafDxCore;

GgafDxSpriteActor::GgafDxSpriteActor(const char* prm_name,
                                     const char* prm_model_id,
                                     const char* prm_effect_id,
                                     const char* prm_technique,
                                     GgafStatus* prm_pStat,
                                     GgafDxChecker* prm_pChecker) :

                                         GgafDxFigureActor(prm_name,
                                                           prm_model_id,
                                                           "S",
                                                           prm_effect_id,
                                                           "S",
                                                           prm_technique,
                                                           prm_pStat,
                                                           prm_pChecker),
_pSpriteModel( (GgafDxSpriteModel*)_pModel),
_pSpriteEffect( (GgafDxSpriteEffect*)_pEffect),
_pUvFlipper(NEW GgafDxUvFlipper(getModel()->getDefaultTextureConnection()->peek())) {

    _obj_class |= Obj_GgafDxSpriteActor;
    _class_name = "GgafDxSpriteActor";
    _pUvFlipper->setRotation(_pSpriteModel->_col_texture_split,
                             _pSpriteModel->_row_texture_split );
    _pUvFlipper->setActivePtn(0);
    _pUvFlipper->exec(NOT_ANIMATED, 1);

    defineRotMvWorldMatrix(UTIL::setWorldMatrix_RxRzRyMv); //デフォルトの回転×移動の変換行列
    _far_rate = -1.0f;

    _align = ALIGN_CENTER;
    _valign = VALIGN_MIDDLE;
}

void GgafDxSpriteActor::processDraw() {
    ID3DXEffect* const pID3DXEffect = _pSpriteEffect->_pID3DXEffect;
    HRESULT hr;
    if (_align == ALIGN_CENTER) {
        //do nothing
    } else if (_align == ALIGN_LEFT) {
        _matWorld._41 += PX_C(_pSpriteModel->_model_width_px*0.5f);
    } else {
        //ALIGN_RIGHT
        _matWorld._41 -= PX_C(_pSpriteModel->_model_width_px*0.5f);
    }
    if (_valign == VALIGN_MIDDLE) {
        //do nothing
    } else if (_valign == VALIGN_TOP) {
        _matWorld._42 -= PX_C(_pSpriteModel->_model_height_px*0.5f);
    } else {
        //VALIGN_BOTTOM
        _matWorld._42 += PX_C(_pSpriteModel->_model_height_px*0.5f);
    }
    hr = pID3DXEffect->SetMatrix(_pSpriteEffect->_h_matWorld, &_matWorld );
    checkDxException(hr, D3D_OK, "SetMatrix(_h_matWorld) に失敗しました。");
    hr = pID3DXEffect->SetValue(_pSpriteEffect->_h_colMaterialDiffuse, &(_paMaterial[0].Diffuse), sizeof(D3DCOLORVALUE) );
    checkDxException(hr, D3D_OK, "SetValue(_h_colMaterialDiffuse) に失敗しました。");
    hr = pID3DXEffect->SetFloat(_pSpriteEffect->_h_far_rate, _far_rate );
    checkDxException(hr, D3D_OK, "SetFloat(_h_far_rate) に失敗しました。");
    _pSpriteModel->GgafDxSpriteModel::draw(this);
}

void GgafDxSpriteActor::setAlign(GgafDxAlign prm_align, GgafDxValign prm_valign) {
    _align = prm_align;
    _valign = prm_valign;
}

void GgafDxSpriteActor::setAlign(GgafDxAlign prm_align) {
    _align = prm_align;
}

void GgafDxSpriteActor::setValign(GgafDxValign prm_valign) {
    _valign = prm_valign;
}

GgafDxSpriteActor::~GgafDxSpriteActor() {
    delete _pUvFlipper;
}
