"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNextStageType = exports.getNextStage = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const cachedClasses_1 = require("../core/cachedClasses");
const curses_1 = require("./curses");
const roomData_1 = require("./roomData");
const stage_1 = require("./stage");
/**
 * Helper function to get the stage that a trapdoor or heaven door would take the player to, based
 * on the current stage, room, and game state flags.
 *
 * If you want to account for the player having visited Repentance floors in The Ascent, use the
 * `getNextStageUsingHistory` helper function instead (from the stage history feature). Handling
 * this requires stateful tracking as the player progresses through the run.
 */
function getNextStage() {
    const level = cachedClasses_1.game.GetLevel();
    const backwardsPath = cachedClasses_1.game.GetStateFlag(isaac_typescript_definitions_1.GameStateFlag.BACKWARDS_PATH);
    const mausoleumHeartKilled = cachedClasses_1.game.GetStateFlag(isaac_typescript_definitions_1.GameStateFlag.MAUSOLEUM_HEART_KILLED);
    const stage = level.GetStage();
    const repentanceStage = (0, stage_1.onRepentanceStage)();
    const roomGridIndex = (0, roomData_1.getRoomGridIndex)();
    // First, handle the special case of being on the backwards path.
    if (backwardsPath) {
        const nextStage = stage - 1;
        return nextStage === 0 ? isaac_typescript_definitions_1.LevelStage.HOME : nextStage;
    }
    // Second, handle the special case of being in a specific off-grid room.
    switch (roomGridIndex) {
        // -8
        case isaac_typescript_definitions_1.GridRoom.BLUE_WOMB: {
            return isaac_typescript_definitions_1.LevelStage.BLUE_WOMB;
        }
        // -9
        case isaac_typescript_definitions_1.GridRoom.VOID: {
            return isaac_typescript_definitions_1.LevelStage.VOID;
        }
        // -10
        case isaac_typescript_definitions_1.GridRoom.SECRET_EXIT: {
            if (repentanceStage) {
                // e.g. From Downpour 2 to Mines 1, etc.
                return stage + 1;
            }
            if (stage === isaac_typescript_definitions_1.LevelStage.DEPTHS_2 ||
                (stage === isaac_typescript_definitions_1.LevelStage.DEPTHS_1 && (0, curses_1.hasCurse)(isaac_typescript_definitions_1.LevelCurse.LABYRINTH))) {
                // From Depths 2 to Mausoleum 2 through the strange door.
                return isaac_typescript_definitions_1.LevelStage.DEPTHS_2;
            }
            // e.g. From Basement 1 to Downpour 1, from Basement 2 to Downpour 2, etc.
            return stage;
        }
    }
    // 2
    if (repentanceStage && stage === isaac_typescript_definitions_1.LevelStage.BASEMENT_2) {
        // From Downpour 2 to Caves 2.
        return isaac_typescript_definitions_1.LevelStage.CAVES_2;
    }
    // 4
    if (repentanceStage && stage === isaac_typescript_definitions_1.LevelStage.CAVES_2) {
        // From Mines 2 to Depths 2.
        return isaac_typescript_definitions_1.LevelStage.DEPTHS_2;
    }
    // 6
    if (repentanceStage && stage === isaac_typescript_definitions_1.LevelStage.DEPTHS_2) {
        if (mausoleumHeartKilled) {
            // From Mausoleum 2 to Corpse 1.
            return isaac_typescript_definitions_1.LevelStage.WOMB_1;
        }
        // From Mausoleum 2 to Womb 2.
        return isaac_typescript_definitions_1.LevelStage.WOMB_2;
    }
    // 8
    if (stage === isaac_typescript_definitions_1.LevelStage.WOMB_2) {
        // From Womb 2 to Sheol or Cathedral.
        return isaac_typescript_definitions_1.LevelStage.SHEOL_CATHEDRAL;
    }
    // 11
    if (stage === isaac_typescript_definitions_1.LevelStage.DARK_ROOM_CHEST) {
        // - The Chest goes to The Chest.
        // - The Dark Room goes to the Dark Room.
        return isaac_typescript_definitions_1.LevelStage.DARK_ROOM_CHEST;
    }
    // 12
    if (stage === isaac_typescript_definitions_1.LevelStage.VOID) {
        // The Void goes to The Void.
        return isaac_typescript_definitions_1.LevelStage.VOID;
    }
    // By default, go to the next floor.
    return stage + 1;
}
exports.getNextStage = getNextStage;
/**
 * Helper function to get the stage type that a trapdoor or heaven door would take the player to,
 * based on the current stage, room, and game state flags.
 *
 * If you want to account for previous floors visited on The Ascent, use the
 * `getNextStageTypeUsingHistory` helper function instead (from the stage history feature). Handling
 * this requires stateful tracking as the player progresses through the run.
 *
 * @param upwards Whether the player should go up to Cathedral in the case of being on Womb 2.
 *                Default is false.
 */
function getNextStageType(upwards = false) {
    const backwardsPath = cachedClasses_1.game.GetStateFlag(isaac_typescript_definitions_1.GameStateFlag.BACKWARDS_PATH);
    const mausoleumHeartKilled = cachedClasses_1.game.GetStateFlag(isaac_typescript_definitions_1.GameStateFlag.MAUSOLEUM_HEART_KILLED);
    const level = cachedClasses_1.game.GetLevel();
    const stage = level.GetStage();
    const stageType = level.GetStageType();
    const repentanceStage = (0, stage_1.onRepentanceStage)();
    const roomGridIndex = (0, roomData_1.getRoomGridIndex)();
    const nextStage = getNextStage();
    // First, handle the special case of being on the backwards path.
    if (backwardsPath) {
        return (0, stage_1.calculateStageType)(nextStage);
    }
    // Second, handle the special case of being in a specific off-grid room.
    if (roomGridIndex === isaac_typescript_definitions_1.GridRoom.SECRET_EXIT) {
        return (0, stage_1.calculateStageTypeRepentance)(nextStage);
    }
    if (repentanceStage &&
        (stage === isaac_typescript_definitions_1.LevelStage.BASEMENT_1 || // 1
            stage === isaac_typescript_definitions_1.LevelStage.CAVES_1 || // 3
            stage === isaac_typescript_definitions_1.LevelStage.DEPTHS_1 || // 5
            stage === isaac_typescript_definitions_1.LevelStage.WOMB_1) // 7
    ) {
        return (0, stage_1.calculateStageTypeRepentance)(nextStage);
    }
    if (repentanceStage &&
        stage === isaac_typescript_definitions_1.LevelStage.DEPTHS_2 &&
        mausoleumHeartKilled) {
        return (0, stage_1.calculateStageTypeRepentance)(nextStage);
    }
    // 9
    if (nextStage === isaac_typescript_definitions_1.LevelStage.BLUE_WOMB) {
        // Blue Womb does not have any alternate floors.
        return isaac_typescript_definitions_1.StageType.ORIGINAL;
    }
    // 10
    if (nextStage === isaac_typescript_definitions_1.LevelStage.SHEOL_CATHEDRAL) {
        if (upwards) {
            // Go to Cathedral (10.1).
            return isaac_typescript_definitions_1.StageType.WRATH_OF_THE_LAMB;
        }
        // Go to Sheol (10.0).
        return isaac_typescript_definitions_1.StageType.ORIGINAL;
    }
    // 11
    if (nextStage === isaac_typescript_definitions_1.LevelStage.DARK_ROOM_CHEST) {
        if (stageType === isaac_typescript_definitions_1.StageType.ORIGINAL) {
            // Sheol (10.0) goes to the Dark Room (11.0).
            return isaac_typescript_definitions_1.StageType.ORIGINAL;
        }
        // Cathedral (10.1) goes to The Chest (11.1).
        return isaac_typescript_definitions_1.StageType.WRATH_OF_THE_LAMB;
    }
    // 12
    if (nextStage === isaac_typescript_definitions_1.LevelStage.VOID) {
        // The Void does not have any alternate floors.
        return isaac_typescript_definitions_1.StageType.ORIGINAL;
    }
    // 13
    if (nextStage === isaac_typescript_definitions_1.LevelStage.HOME) {
        // Home does not have any alternate floors.
        return isaac_typescript_definitions_1.StageType.ORIGINAL;
    }
    return (0, stage_1.calculateStageType)(nextStage);
}
exports.getNextStageType = getNextStageType;
