/**
 * @file d_a_obj_testcube.cpp
 *
 */

#include "d/dolzel_rel.h"  // IWYU pragma: keep

#include "d/actor/d_a_obj_testcube.h"

#if DEBUG
const char* l_arcName[] = {
    "K_cube00",
    "K_cube01",
    "K_cyli00",
};

class daObjCube_HIO_c : public mDoHIO_entry_c {
public:
    daObjCube_HIO_c();
    virtual ~daObjCube_HIO_c() {}

    void genMessage(JORMContext*);

    /* 0x6 */ GXColor mColor[255];
};

daObjCube_HIO_c l_HIO;

static const GXColor l_obj_color[] = {
    {0x00, 0x00, 0x00, 0xFF}, {0x12, 0x09, 0x00, 0xFF}, {0x0c, 0x0c, 0x0c, 0xFF},
    {0x1d, 0x14, 0x03, 0xFF}, {0x06, 0x14, 0x06, 0xFF}, {0x2b, 0x20, 0x16, 0xFF},
    {0x17, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x39, 0xFF}, {0x1f, 0x2f, 0x3f, 0xFF},
    {0x3f, 0x18, 0x0d, 0xFF}, {0x00, 0x07, 0x17, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x32, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x32, 0xFF},
    {0x00, 0x32, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
    {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF}, {0x00, 0x00, 0x00, 0xFF},
};

daObjCube_HIO_c::daObjCube_HIO_c() {
    for (int i = 0; i < 255; i++) {
        mColor[i] = l_obj_color[i];
    }
}

void daObjCube_HIO_c::genMessage(JORMContext* mctx) {
    mctx->genLabel("テスト立方体", 0);

    for (int i = 0; i < 255; i++) {
        char label[256];
        sprintf(label, "名前引数<%d>のカラー\n", i);

        mctx->genLabel(label, 0);
        mctx->genSlider("r", &mColor[i].r, 0, 0xFF);
        mctx->genSlider("g", &mColor[i].g, 0, 0xFF);
        mctx->genSlider("b", &mColor[i].b, 0, 0xFF);
        mctx->genSlider("a", &mColor[i].a, 0, 0xFF);
    }
}

void daObjCube_c::getDzbName(char* i_buffer) {
    u8 arg = mNameArg;

    switch (mShape) {
    case 0:
    case 1:
        sprintf(i_buffer, "k_size_cube%02d.dzb", mNameArg);
        break;
    case 2:
        if (arg == 100) {
            arg = 0;
        }

        sprintf(i_buffer, "k_size_cyl%02d.dzb", arg);
        break;
    }
}

void daObjCube_c::getBmdName(char* i_buffer) {
    switch (mShape) {
    case 0:
    case 1:
        sprintf(i_buffer, "K_size_cube.bmd");
        break;
    case 2:
        sprintf(i_buffer, "k_size_cylinder.bmd");
        break;
    }
}

void daObjCube_c::initBaseMtx() {
    if (mShape == 2) {
        scale.z = scale.x;
    }

    setBaseMtx();
}

void daObjCube_c::setBaseMtx() {
    mDoMtx_stack_c::transS(current.pos);
    mDoMtx_stack_c::ZXYrotM(shape_angle);
    mDoMtx_stack_c::scaleM(scale);
    mpModel->setBaseTRMtx(mDoMtx_stack_c::get());
    MTXCopy(mDoMtx_stack_c::get(), mBgMtx);
}

int daObjCube_c::Create() {
    if (mNameArg == 100) {
        scale.x *= 10.0f;
        scale.y *= 10.0f;
        scale.z *= 10.0f;
    }

    initBaseMtx();
    fopAcM_SetMtx(this, mpModel->getBaseTRMtx());

    cXyz cullMin;
    cXyz cullMax;
    J3DJoint* rootJnt = mpModel->getModelData()->getJointNodePointer(0);

    cullMin.x = scale.x * rootJnt->getMin()->x;
    cullMin.y = scale.y * rootJnt->getMin()->y;
    cullMin.z = scale.z * rootJnt->getMin()->z;

    cullMax.x = scale.x * rootJnt->getMax()->x;
    cullMax.y = scale.y * rootJnt->getMax()->y;
    cullMax.z = scale.z * rootJnt->getMax()->z;

    fopAcM_setCullSizeBox(this, cullMin.x, cullMin.y, cullMin.z, cullMax.x, cullMax.y, cullMax.z);
    fopAcM_setCullSizeFar(this, 10.0f);
    return 1;
}

int daObjCube_c::CreateHeap() {
    char resName[40];
    getBmdName(resName);

    J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes(l_arcName[mShape], resName);
    JUT_ASSERT(581, modelData != NULL);
    mpModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084);
    if (mpModel == NULL) {
        return 0;
    }

    return 1;
}

int daObjCube_c::create() {
    fopAcM_ct(this, daObjCube_c);

    mShape = daObjCube_prm::getShape(this);
    mNameArg = daObjCube_prm::getNameArg(this);

    int phase_state = dComIfG_resLoad(&mPhase, l_arcName[mShape]);
    if (phase_state == cPhs_COMPLEATE_e) {
        char resName[32];
        getDzbName(resName);

        int dzb_id = dComIfG_getObjctResName2Index(l_arcName[mShape], resName);
        JUT_ASSERT(621, dzb_id != -1);

        phase_state = MoveBGCreate(l_arcName[mShape], dzb_id, NULL, 0xC10, NULL);
        if (phase_state == cPhs_ERROR_e) {
            return phase_state;
        }

        MoveBGExecute();
        l_HIO.entryHIO("テスト立方体");
    }

    return phase_state;
}

int daObjCube_c::Execute(Mtx** param_0) {
    u8 arg0 = daObjCube_prm::getArg0(this);
    u8 sw = daObjCube_prm::getSwitch(this);
    BOOL isSwitch = fopAcM_isSwitch(this, sw);

    if (sw != 0xFF) {
        if (arg0 == 0) {
            if (isSwitch) {
                if (mpBgW->ChkUsed()) {
                    if (dComIfG_Bgsp().Release(mpBgW)) {
                        OSReport_Error("テスト立方体：MoveBG解除に失敗しました\n");
                    }
                }

                field_0x5b6 = 1;
            } else {
                if (!mpBgW->ChkUsed()) {
                    if (dComIfG_Bgsp().Regist(mpBgW, this)) {
                        OSReport_Error("テスト立方体：MoveBG登録に失敗しました\n");
                    }
                }

                field_0x5b6 = 0;
            }
        } else {
            if (isSwitch) {
                if (!mpBgW->ChkUsed()) {
                    if (dComIfG_Bgsp().Regist(mpBgW, this)) {
                        OSReport_Error("テスト立方体：MoveBG登録に失敗しました\n");
                    }
                }

                field_0x5b6 = 0;
            } else {
                if (mpBgW->ChkUsed()) {
                    if (dComIfG_Bgsp().Release(mpBgW)) {
                        OSReport_Error("テスト立方体：MoveBG解除に失敗しました\n");
                    }
                }

                field_0x5b6 = 1;
            }
        }
    }

    *param_0 = &mBgMtx;
    return 1;
}

int daObjCube_c::Draw() {
    if (field_0x5b6) {
        return 1;
    }

    g_env_light.settingTevStruct(0x10, &current.pos, &tevStr);
    g_env_light.setLightTevColorType_MAJI(mpModel, &tevStr);

    u8 arg = mNameArg;
    if (arg == 100) {
        arg = 0;
    }

    J3DModelData* modelData = mpModel->getModelData();
    for (u16 i = 0; i < modelData->getMaterialNum(); i++) {
        J3DMaterial* material = modelData->getMaterialNodePointer(i);
        J3DGXColor* tevColor = material->getTevKColor(3);
        tevColor->r = l_HIO.mColor[arg].r;
        tevColor->g = l_HIO.mColor[arg].g;
        tevColor->b = l_HIO.mColor[arg].b;
        tevColor->a = l_HIO.mColor[arg].a;
    }

    dComIfGd_setListBG();
    mDoExt_modelUpdateDL(mpModel);
    dComIfGd_setList();
    return 1;
}

int daObjCube_c::Delete() {
    dComIfG_resDelete(&mPhase, l_arcName[mShape]);
    l_HIO.removeHIO();
    return 1;
}

static int daObjCube_Draw(daObjCube_c* i_this) {
    return i_this->MoveBGDraw();
}

static int daObjCube_Execute(daObjCube_c* i_this) {
    return i_this->MoveBGExecute();
}

static int daObjCube_Delete(daObjCube_c* i_this) {
    fpc_ProcID id = fopAcM_GetID(i_this);
    return i_this->MoveBGDelete();
}

static int daObjCube_Create(fopAc_ac_c* actor) {
    daObjCube_c* i_this = (daObjCube_c*)actor;
    fpc_ProcID id = fopAcM_GetID(actor);
    return i_this->create();
}

static DUSK_CONST actor_method_class l_daObjCube_Method = {
    (process_method_func)daObjCube_Create,
    (process_method_func)daObjCube_Delete,
    (process_method_func)daObjCube_Execute,
    (process_method_func)NULL,
    (process_method_func)daObjCube_Draw,
};
#endif

#if DEBUG
#define OBJCUBE_METHODS &l_daObjCube_Method
#else
#define OBJCUBE_METHODS NULL
#endif

DUSK_PROFILE actor_process_profile_definition DUSK_CONST g_profile_Obj_TestCube = {
    /* Layer ID     */ fpcLy_CURRENT_e,
    /* List ID      */ 3,
    /* List Prio    */ fpcPi_CURRENT_e,
    /* Proc Name    */ fpcNm_Obj_TestCube_e,
    /* Proc SubMtd  */ &g_fpcLf_Method.base,
    /* Size         */ sizeof(daObjCube_c),
    /* Size Other   */ 0,
    /* Parameters   */ 0,
    /* Leaf SubMtd  */ &g_fopAc_Method.base,
    /* Draw Prio    */ fpcDwPi_Obj_TestCube_e,
    /* Actor SubMtd */ OBJCUBE_METHODS,
    /* Status       */ fopAcStts_UNK_0x40000_e | fopAcStts_CULL_e,
    /* Group        */ fopAc_ACTOR_e,
    /* Cull Type    */ fopAc_CULLBOX_CUSTOM_e,
};
