//
// Generated By: dol2asm
// Translation Unit: d_a_tag_camera
//

#include "rel/d/a/tag/d_a_tag_camera/d_a_tag_camera.h"
#include "cmath.h"
#include "d/a/d_a_alink.h"
#include "d/com/d_com_inf_game.h"
#include "rel/d/a/d_a_horse/d_a_horse.h"

namespace {
/* 80489A98-80489AA0 000078 0008+00 1/0 0/0 0/0 .text
 * always_true__28@unnamed@d_a_tag_camera_cpp@Fv                */
bool always_true() {
    return true;
}

/* 8048A670-8048A674 000000 0004+00 15/15 0/0 0/0 .bss Player__28@unnamed@d_a_tag_camera_cpp@ */
daAlink_c* Player;

/* 80489AA0-80489B18 000080 0078+00 1/0 0/0 0/0 .text
 * is_player_riding_horse__28@unnamed@d_a_tag_camera_cpp@Fv     */
bool is_player_riding_horse() {
    return Player->checkHorseRide() || Player->checkBoarRide();
}

/* 80489B18-80489B2C 0000F8 0014+00 1/0 0/0 0/0 .text
 * is_player_swimming__28@unnamed@d_a_tag_camera_cpp@Fv         */
bool is_player_swimming() {
    return dComIfGp_checkPlayerStatus0(0, 0x100000);
}

/* 80489B2C-80489B6C 00010C 0040+00 1/0 0/0 0/0 .text
 * is_player_riding_canoe__28@unnamed@d_a_tag_camera_cpp@Fv     */
bool is_player_riding_canoe() {
    return Player->checkCanoeRide() != 0;
}

/* 80489B6C-80489BE0 00014C 0074+00 1/0 0/0 0/0 .text
 * is_player_jumping_by_horse__28@unnamed@d_a_tag_camera_cpp@Fv */
bool is_player_jumping_by_horse() {
    daHorse_c* phorse = dComIfGp_getHorseActor();

    return Player->checkHorseRide() && phorse->checkJump();
}

/* 80489BE0-80489C04 0001C0 0024+00 1/0 0/0 0/0 .text
 * is_player_climbing__28@unnamed@d_a_tag_camera_cpp@Fv         */
bool is_player_climbing() {
    return dComIfGp_checkPlayerStatus0(0, 0x2000008) != 0;
}

/* 80489C04-80489C1C 0001E4 0018+00 1/0 0/0 0/0 .text
 * is_player_wear_magneboots__28@unnamed@d_a_tag_camera_cpp@Fv  */
bool is_player_wear_magneboots() {
    return Player->checkMagneBootsOn();
}

/* 80489C1C-80489C34 0001FC 0018+00 1/0 0/0 0/0 .text
 * is_player_wolf__28@unnamed@d_a_tag_camera_cpp@Fv             */
bool is_player_wolf() {
    return Player->i_checkNowWolf();
}

/* 80489C34-80489C6C 000214 0038+00 1/0 0/0 0/0 .text
 * is_player_pulling_chainblock__28@unnamed@d_a_tag_camera_cpp@Fv */
bool is_player_pulling_chainblock() {
    return Player->checkChainBlockPushPull();
}

/* 80489C6C-80489CAC 00024C 0040+00 1/0 0/0 0/0 .text
 * is_player_playing_spinner__28@unnamed@d_a_tag_camera_cpp@Fv  */
bool is_player_playing_spinner() {
    return Player->checkSpinnerRide() != 0;
}

/* 80489CAC-80489CE4 00028C 0038+00 1/0 0/0 0/0 .text
 * is_player_sliding_slope__28@unnamed@d_a_tag_camera_cpp@Fv    */
bool is_player_sliding_slope() {
    return Player->checkLv3Slide();
}

/* 80489CE4-80489CF8 0002C4 0014+00 2/1 0/0 0/0 .text
 * is_player_on_watersurface__28@unnamed@d_a_tag_camera_cpp@Fv  */
bool is_player_on_watersurface() {
    return dComIfGp_checkCameraAttentionStatus(0, 0x800) != 0;
}

/* 80489CF8-80489D30 0002D8 0038+00 1/0 0/0 0/0 .text
 * is_player_moving_on_spinnerrail__28@unnamed@d_a_tag_camera_cpp@Fv */
bool is_player_moving_on_spinnerrail() {
    return Player->checkSpinnerPathMove();
}

/* 80489D30-80489D5C 000310 002C+00 1/0 0/0 0/0 .text
 * is_player_gliding__28@unnamed@d_a_tag_camera_cpp@Fv          */
bool is_player_gliding() {
    return Player->checkCokkoGlide();
}

/* 80489D5C-80489D70 00033C 0014+00 1/0 0/0 0/0 .text
 * is_player_hunging_by_hookshot__28@unnamed@d_a_tag_camera_cpp@Fv */
bool is_player_hunging_by_hookshot() {
    return dComIfGp_checkPlayerStatus1(0, 0x10000) != 0;
}

/* 80489D70-80489DB0 000350 0040+00 1/0 0/0 0/0 .text
 * is_player_on_rope__28@unnamed@d_a_tag_camera_cpp@Fv          */
bool is_player_on_rope() {
    return Player->checkWolfRope() != 0;
}

/* 80489DB0-80489DE4 000390 0034+00 1/0 0/0 0/0 .text
 * is_player_using_copyrod__28@unnamed@d_a_tag_camera_cpp@Fv    */
bool is_player_using_copyrod() {
    return Player->getCopyRodCameraActor() != NULL;
}

/* 80489DE4-80489DF8 0003C4 0014+00 1/0 0/0 0/0 .text
 * is_player_hunging_wall_by_hookshot__28@unnamed@d_a_tag_camera_cpp@Fv */
bool is_player_hunging_wall_by_hookshot() {
    return dComIfGp_checkPlayerStatus1(0, 0x2000000) != 0;
}

/* 80489DF8-80489E18 0003D8 0020+00 1/0 0/0 0/0 .text
 * is_player_carried_by_cargo__28@unnamed@d_a_tag_camera_cpp@Fv */
bool is_player_carried_by_cargo() {
    return Player->checkCargoCarry();
}

/* 80489E18-80489E8C 0003F8 0074+00 1/0 0/0 0/0 .text
 * is_player_playing_rodeo__28@unnamed@d_a_tag_camera_cpp@Fv    */
bool is_player_playing_rodeo() {
    daHorse_c* phorse = dComIfGp_getHorseActor();

    return Player->checkHorseRide() && phorse->checkRodeoMode();
}

/* 80489E8C-80489EDC 00046C 0050+00 1/0 0/0 0/0 .text
 * is_player_in_water__28@unnamed@d_a_tag_camera_cpp@Fv         */
bool is_player_in_water() {
    return dComIfGp_checkPlayerStatus0(0, 0x100000) && !is_player_on_watersurface();
}

/* 80489EDC-80489F14 0004BC 0038+00 1/0 0/0 0/0 .text
 * is_player_hugging_eal__28@unnamed@d_a_tag_camera_cpp@Fv      */
bool is_player_hugging_eal() {
    return Player->checkOctaIealHang();
}
}  // namespace

/* 80489F14-80489F20 0004F4 000C+00 1/1 0/0 0/0 .text            getSwType__11daTag_Cam_cFv */
u8 daTag_Cam_c::getSwType() {
    return fopAcM_GetParam(this) & 0xF;
}

/* 80489F20-80489F2C 000500 000C+00 1/1 0/0 0/0 .text            getPrio__11daTag_Cam_cFv */
u8 daTag_Cam_c::getPrio() {
    return (fopAcM_GetParam(this) >> 4) & 0xF;
}

/* 80489F2C-80489F38 00050C 000C+00 1/1 0/0 0/0 .text            getSwBit__11daTag_Cam_cFv */
u8 daTag_Cam_c::getSwBit() {
    return (fopAcM_GetParam(this) >> 8) & 0xFF;
}

/* 80489F38-80489F44 000518 000C+00 2/2 0/0 0/0 .text            getCondition__11daTag_Cam_cFv */
u8 daTag_Cam_c::getCondition() {
    return (fopAcM_GetParam(this) >> 0x10) & 0xFF;
}

/* 80489F44-80489F50 000524 000C+00 1/1 0/0 0/0 .text            getCameraId__11daTag_Cam_cFv */
u8 daTag_Cam_c::getCameraId() {
    return (fopAcM_GetParam(this) >> 0x18) & 0xFF;
}

/* 80489F50-80489F5C 000530 000C+00 1/1 0/0 0/0 .text            getRailID__11daTag_Cam_cFv */
u8 daTag_Cam_c::getRailID() {
    return home.angle.z & 0xFF;
}

/* 80489F5C-80489F68 00053C 000C+00 2/2 0/0 0/0 .text            getAreaType__11daTag_Cam_cFv */
u16 daTag_Cam_c::getAreaType() {
    return home.angle.z & 0x100;
}

/* 80489F68-80489F74 000548 000C+00 1/1 0/0 0/0 .text            getAreaNoChk__11daTag_Cam_cFv */
u16 daTag_Cam_c::getAreaNoChk() {
    return home.angle.z & 0x200;
}

/* 8048A590-8048A59C 000000 000C+00 2/2 0/0 0/0 .rodata          @3874 */
static u8 const lit_3874[12] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

int daTag_Cam_c::create() {
    fopAcM_SetupActor(this, daTag_Cam_c);

    if (getAreaType() == 0) {
        scale.x *= 500.0f;
        scale.y *= 1000.0f;
        scale.z *= 500.0f;

        mBoundsLo.set(current.pos.x - scale.x, current.pos.y, current.pos.z - scale.z);
        mBoundsHi.set(current.pos.x + scale.x, current.pos.y + scale.y, current.pos.z + scale.z);
    } else {
        scale.x *= 1000.0f;
        scale.y *= 1000.0f;
        scale.z *= 0.0f;

        mBoundsLo.set(0.0f, current.pos.y, 0.0f);
        mBoundsHi.set(0.0f, current.pos.y + scale.y, 0.0f);
    }

    Player = daAlink_getAlinkActorClass();

    bool (*check_func[])() = {
        is_player_riding_horse,
        is_player_swimming,
        is_player_riding_canoe,
        always_true,
        is_player_jumping_by_horse,
        is_player_climbing,
        is_player_wear_magneboots,
        is_player_wolf,
        is_player_pulling_chainblock,
        is_player_playing_spinner,
        is_player_sliding_slope,
        is_player_on_watersurface,
        is_player_moving_on_spinnerrail,
        is_player_gliding,
        is_player_hunging_by_hookshot,
        is_player_on_rope,
        is_player_using_copyrod,
        is_player_hunging_wall_by_hookshot,
        is_player_carried_by_cargo,
        is_player_playing_rodeo,
        is_player_in_water,
        is_player_hugging_eal,
    };

    u8 func_index = getCondition();
    if ((int)func_index > 22) {
        func_index = 3;
    }

    mCheckFunc = check_func[func_index];
    return cPhs_COMPLEATE_e;
}

/* 80489F74-8048A378 000554 0404+00 1/1 0/0 0/0 .text            execute__11daTag_Cam_cFv */
int daTag_Cam_c::execute() {
    if (fopAcM_GetRoomNo(this) != dComIfGp_roomControl_getStayNo()) {
        return 0;
    }

    u8 sw_type = getSwType();
    u8 sw_bit = getSwBit();
    bool var_r29 = false;
    bool do_area_check = false;

    if (sw_bit != 0xFF) {
        bool is_switch_on = dComIfGs_isSwitch(sw_bit, fopAcM_GetRoomNo(this)) != 0;
        if ((sw_type != 0 && is_switch_on) || (sw_type == 0 && !is_switch_on)) {
            do_area_check = true;
        }
    } else {
        do_area_check = true;
    }

    if (do_area_check) {
        cXyz pos(dComIfGp_getLinkPlayer()->current.pos);
        if (dComIfGp_checkPlayerStatus0(0, 8)) {
            pos = dComIfGp_getLinkPlayer()->attention_info.position;
            pos.y -= 80.0f;
        }

        if (getAreaNoChk()) {
            var_r29 = true;
        } else if (getAreaType() == 0) {
            if (home.angle.y != 0) {
                mDoMtx_stack_c::transS(current.pos);
                mDoMtx_stack_c::YrotM(-home.angle.y);

                cXyz sp84 = pos - current.pos;
                mDoMtx_stack_c::multVec(&sp84, &pos);
            }

            if (mBoundsLo.x <= pos.x && pos.x <= mBoundsHi.x && mBoundsLo.y <= pos.y &&
                pos.y <= mBoundsHi.y && mBoundsLo.z <= pos.z && pos.z <= mBoundsHi.z)
            {
                var_r29 = true;
            }
        } else {
            f32 temp_f31 = current.pos.x - pos.x;
            f32 temp_f30 = current.pos.z - pos.z;
            f32 sq_dist = std::sqrt(temp_f31 * temp_f31 + temp_f30 * temp_f30);
            if (sq_dist < scale.x && mBoundsLo.y <= pos.y && pos.y <= mBoundsHi.y) {
                var_r29 = true;
            }
        }
    }

    if (var_r29) {
        u16 priority = getPrio();
        u8 condition = getCondition();
        bool set_camera = mCheckFunc();

        if (condition == 0xFF) {
            priority |= 0x8000;
        } else if (condition == 0xFA) {
            if (dCam_getBody()->CheckFlag(0x8000000)) {
                set_camera = true;
            }
        }

        if (set_camera) {
            u8 cam_id = getCameraId();
            u8 rail_id = getRailID();
            dCam_getBody()->SetTagData(this, cam_id, priority, rail_id);
        }
    }

    return 1;
}

/* 8048A378-8048A380 000958 0008+00 1/0 0/0 0/0 .text            daTag_Cam_Draw__FP11daTag_Cam_c */
static int daTag_Cam_Draw(daTag_Cam_c* i_this) {
    return 1;
}

/* 8048A380-8048A3A4 000960 0024+00 1/0 0/0 0/0 .text            daTag_Cam_Execute__FP11daTag_Cam_c
 */
static int daTag_Cam_Execute(daTag_Cam_c* i_this) {
    i_this->execute();
    return 1;
}

/* 8048A3A4-8048A3AC 000984 0008+00 1/0 0/0 0/0 .text            daTag_Cam_IsDelete__FP11daTag_Cam_c
 */
static int daTag_Cam_IsDelete(daTag_Cam_c* i_this) {
    return 1;
}

/* 8048A3AC-8048A3DC 00098C 0030+00 1/0 0/0 0/0 .text            daTag_Cam_Delete__FP11daTag_Cam_c
 */
static int daTag_Cam_Delete(daTag_Cam_c* i_this) {
    i_this->~daTag_Cam_c();
    return 1;
}

/* 8048A3DC-8048A588 0009BC 01AC+00 1/0 0/0 0/0 .text            daTag_Cam_Create__FP10fopAc_ac_c */
static int daTag_Cam_Create(fopAc_ac_c* i_this) {
    daTag_Cam_c* a_this = (daTag_Cam_c*)i_this;
    return a_this->create();
}

/* 8048A620-8048A640 -00001 0020+00 1/0 0/0 0/0 .data            l_daTag_Cam_Method */
static actor_method_class l_daTag_Cam_Method = {
    (process_method_func)daTag_Cam_Create,  (process_method_func)daTag_Cam_Delete,
    (process_method_func)daTag_Cam_Execute, (process_method_func)daTag_Cam_IsDelete,
    (process_method_func)daTag_Cam_Draw,
};

/* 8048A640-8048A670 -00001 0030+00 0/0 0/0 1/0 .data            g_profile_TAG_CAMERA */
extern actor_process_profile_definition g_profile_TAG_CAMERA = {
    fpcLy_CURRENT_e,        // mLayerID
    7,                      // mListID
    fpcPi_CURRENT_e,        // mListPrio
    PROC_TAG_CAMERA,        // mProcName
    &g_fpcLf_Method.mBase,  // sub_method
    sizeof(daTag_Cam_c),    // mSize
    0,                      // mSizeOther
    0,                      // mParameters
    &g_fopAc_Method.base,   // sub_method
    279,                    // mPriority
    &l_daTag_Cam_Method,    // sub_method
    0x00044000,             // mStatus
    fopAc_ACTOR_e,          // mActorType
    fopAc_CULLBOX_6_e,      // cullType
};
