#include "common.hpp"

namespace Mash {
int get_attack_air_kind(u64 module_accessor, bool* replace) {
    int kind = 0;
    if (is_training_mode() && is_operation_cpu(module_accessor)) {
        if (MASH_STATE == MASH_ATTACK) {
            *replace = true;
            switch (ATTACK_STATE) {
                case MASH_NAIR:
                    kind = FIGHTER_COMMAND_ATTACK_AIR_KIND_N; break;
                case MASH_FAIR:
                    kind = FIGHTER_COMMAND_ATTACK_AIR_KIND_F; break;
                case MASH_BAIR:
                    kind = FIGHTER_COMMAND_ATTACK_AIR_KIND_B; break;
                case MASH_UPAIR:
                    kind = FIGHTER_COMMAND_ATTACK_AIR_KIND_HI; break;
                case MASH_DAIR:
                    kind = FIGHTER_COMMAND_ATTACK_AIR_KIND_LW; break;
            }
            return kind;
        }

        if (MASH_STATE == MASH_RANDOM) {
            *replace = true;
            return app::sv_math::rand(hash40("fighter"), 5) + 1;
        }
    }

    *replace = false;
    return kind;
}

int get_command_flag_cat(u64 module_accessor, int category, int orig_flag) {
    int flag = 0;
    if (is_training_mode() && is_operation_cpu(module_accessor)) {
        if (is_in_hitstun(module_accessor) || is_in_landing(module_accessor)) {
            if (MASH_STATE == MASH_AIRDODGE)
                if (category == FIGHTER_PAD_COMMAND_CATEGORY1)
                    flag |= FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE;

            if (MASH_STATE == MASH_JUMP)
                if (category == FIGHTER_PAD_COMMAND_CATEGORY1)
                    flag |= FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON;

            if (MASH_STATE == MASH_ATTACK)
                if (category == FIGHTER_PAD_COMMAND_CATEGORY1) {
                    switch (ATTACK_STATE) {
                        case MASH_NAIR:
                        case MASH_FAIR:
                        case MASH_BAIR:
                        case MASH_UPAIR:
                        case MASH_DAIR:
                            flag |= FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N;
                            break;
                        case MASH_NEUTRAL_B:
                            flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N;
                            break;
                        case MASH_SIDE_B:
                            flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S;
                            break;
                        case MASH_UP_B:
                            flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI;
                            break;
                        case MASH_DOWN_B:
                            flag |= FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW;
                            break;
                    }
                }

            if (MASH_STATE == MASH_RANDOM)
                if (category == FIGHTER_PAD_COMMAND_CATEGORY1) {
                    int situation_kind =
                        StatusModule::situation_kind(module_accessor);

                    if (situation_kind == SITUATION_KIND_AIR) {
                        const int NUM_AIR_COMMANDS = 11;
                        int random_commands[NUM_AIR_COMMANDS] = {
                            FIGHTER_PAD_CMD_CAT1_FLAG_AIR_ESCAPE,
                            FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON,
                            // one for each aerial
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
                            FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_N,
                            FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
                            FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
                            FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
                        };

                        int random_cmd_index = app::sv_math::rand(
                            hash40("fighter"), NUM_AIR_COMMANDS);

                        flag |= random_commands[random_cmd_index];
                    } else if (situation_kind == SITUATION_KIND_GROUND) {
                        const int NUM_GROUND_COMMANDS = 16;
                        int random_commands[NUM_GROUND_COMMANDS] = {
                            FIGHTER_PAD_CMD_CAT1_FLAG_JUMP_BUTTON,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_N,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S3,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI3,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW3,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_S4,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_HI4,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ATTACK_LW4,
                            FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
                            FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_S,
                            FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_HI,
                            FIGHTER_PAD_CMD_CAT1_FLAG_SPECIAL_LW,
                            FIGHTER_PAD_CMD_CAT1_FLAG_CATCH,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_F,
                            FIGHTER_PAD_CMD_CAT1_FLAG_ESCAPE_B,
                        };

                        int random_cmd_index = app::sv_math::rand(
                            hash40("fighter"), NUM_GROUND_COMMANDS);

                        flag |= random_commands[random_cmd_index];
                    }
                }
        }
    }

    return flag | orig_flag;
}
}