"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getRandomBossRoomFromPool = exports.getRandomCustomStageRoom = void 0;
const array_1 = require("../../../../functions/array");
const log_1 = require("../../../../functions/log");
const random_1 = require("../../../../functions/random");
/**
 * Helper function to get a random custom stage room from an array of custom stage rooms.
 *
 * Note that this function does not simply choose a random element in the provided array; it will
 * properly account for each room weight using the algorithm from:
 * https://stackoverflow.com/questions/1761626/weighted-random-numbers
 */
function getRandomCustomStageRoom(roomsMetadata, seedOrRNG, verbose = false) {
    const totalWeight = getTotalWeightOfCustomStageRooms(roomsMetadata);
    if (verbose) {
        (0, log_1.log)(`Total weight of the custom stage rooms provided: ${totalWeight}`);
    }
    const chosenWeight = (0, random_1.getRandomFloat)(0, totalWeight, seedOrRNG);
    if (verbose) {
        (0, log_1.log)(`Randomly chose weight for custom stage room: ${chosenWeight}`);
    }
    return getCustomStageRoomWithChosenWeight(roomsMetadata, chosenWeight);
}
exports.getRandomCustomStageRoom = getRandomCustomStageRoom;
function getTotalWeightOfCustomStageRooms(roomsMetadata) {
    const weights = roomsMetadata.map((roomMetadata) => roomMetadata.weight);
    return (0, array_1.sumArray)(weights);
}
function getCustomStageRoomWithChosenWeight(roomsMetadata, chosenWeight) {
    for (const roomMetadata of roomsMetadata) {
        if (chosenWeight < roomMetadata.weight) {
            return roomMetadata;
        }
        chosenWeight -= roomMetadata.weight;
    }
    error(`Failed to get a custom stage room with chosen weight: ${chosenWeight}`);
}
function getRandomBossRoomFromPool(roomsMetadata, bossPool, seedOrRNG, verbose = false) {
    const totalWeight = getTotalWeightOfBossPool(bossPool);
    if (verbose) {
        (0, log_1.log)(`Total weight of the custom stage boss pool provided: ${totalWeight}`);
    }
    const chosenWeight = (0, random_1.getRandomFloat)(0, totalWeight, seedOrRNG);
    if (verbose) {
        (0, log_1.log)(`Randomly chose weight for custom stage boss pool: ${chosenWeight}`);
    }
    const bossEntry = getBossEntryWithChosenWeight(bossPool, chosenWeight);
    const roomsMetadataForBoss = roomsMetadata.filter((roomMetadata) => roomMetadata.subType === bossEntry.subType);
    return getRandomCustomStageRoom(roomsMetadataForBoss, seedOrRNG, verbose);
}
exports.getRandomBossRoomFromPool = getRandomBossRoomFromPool;
function getTotalWeightOfBossPool(bossPool) {
    const weights = bossPool.map((bossEntry) => bossEntry.weight);
    return (0, array_1.sumArray)(weights);
}
function getBossEntryWithChosenWeight(bossPool, chosenWeight) {
    for (const bossEntry of bossPool) {
        if (chosenWeight < bossEntry.weight) {
            return bossEntry;
        }
        chosenWeight -= bossEntry.weight;
    }
    error(`Failed to get a custom stage boss entry with chosen weight: ${chosenWeight}`);
}
