import { system, world } from "@minecraft/server";
import * as mcui from "@minecraft/server-ui";
import StructureManager from "./StructureManager";
import CameraManager from "./CameraManager";
import FSPlayerPerms from "./fs/libs/perms/FSPlayerPerms";
import EntityManager from "./EntityManager";
import PlayerHelper from "./PlayerHelper";
import PlayerManager from "./PlayerManager";
import FSDynamicProperty from "./fs/libs/FSDynamicProperty";
import FSUtil from "./fs/FSUtil";
import FSActionFormData from "./fs/forms/ui/FSActionFormData";
import FSActionFormResponse from "./fs/forms/resps/FSActionFormResp";
import FSFormManager from "./fs/forms/FSFormManager";
import FSLocalizedString from "./fs/FSLocalizedString";
import FSMath from "./fs/FSMath";
import FSInventoryManager from "./fs/libs/FSInventoryManager";
import LockedBlock from "./entity/LockedBlock";
import FSModalFormData from "./fs/forms/ui/FSModalFormData";
import { CAMERA_COST_XP, CAN_BUY_CAMERAS_WITH_CHIPS, CAN_BUY_TURRETS_WITH_CHIPS, HUB_LEVEL_COST_CHIPS, SECURITY_CHIP_PRICE_1, SECURITY_CHIP_PRICE_16, SECURITY_CHIP_PRICE_32, SECURITY_CHIP_PRICE_64, TURRET_COST_XP } from "./fs/FSConstants";
import FSXPHelper from "./fs/FSXPHelper";
import { ALL_CRAFTING_RECIPES } from "./data/recipes";
import ShopHelper from "./ShopHelper";
import FSModalFormResponse from "./fs/forms/resps/FSModalFormResp";
import FSWorldHelper from "./fs/FSWorldHelper";
import FSPlayer from "./fs/FSPlayer";
const GO_BACK_COMMON = { translate: FSLocalizedString.localize("ui.common.button.go_back", "< Go Back", "Button to go back") };
const CLOSE_COMMON = { translate: FSLocalizedString.localize("ui.common.button.close", "Close", "Button to close the form") };
export default class FormManager {
    constructor() {
    }
    static sharedInstance() {
        if (!FormManager.instance) {
            FormManager.instance = new FormManager();
        }
        return FormManager.instance;
    }
    init() { }
    showSecurityBotOptions(entity, player) {
        const form = new mcui.ActionFormData();
        form.title({
            translate: FSLocalizedString.localize("ui.security_bot.title", "Security Bot", "The Security Bot is an NPC in the bunker.")
        });
        form.body({
            translate: FSLocalizedString.localize("ui.security_bot.body", "Hello §l%s§r! What would you like to do?", "The Security Bot is an NPC in the bunker. The %s in the string represents the player name."),
            with: [`${player.name}`]
        });
        form.button({
            translate: FSLocalizedString.localize("ui.security_bot.button.help", "I need §lhelp!", "Button to get help from Security Bot")
        });
        form.button({
            translate: FSLocalizedString.localize("ui.security_bot.button.get_tablet", "I need a §lSecurity Tablet!§r", "Button to get a Security Tablet from Security Bot")
        });
        form.button({
            translate: FSLocalizedString.localize("ui.security_bot.button.say_hi", "I just wanted to say §lhi!§r", "Button to say hi to Security Bot")
        });
        form.button({
            translate: FSLocalizedString.localize("ui.security_bot.button.remove_bot", "§4§lRemove§r Security Bot§r", "Button to remove the Security Bot")
        });
        form.button({
            translate: FSLocalizedString.localize("ui.security_bot.button.cancel", "Cancel", "Button to cancel the action")
        });
        form.show(player).then(resp => {
            if (resp.canceled) {
                return;
            }
            let selection = resp.selection || 0;
            switch (selection) {
                case 0: {
                    const msg = {
                        translate: FSLocalizedString.localize("chat.security_bot.answer.help", "Sure thing, §l%s§r! I have just dropped a super helpful book for you!", "The Security Bot is an NPC in the bunker. The %s in the string represents the player name."),
                        with: [`${player.name}`]
                    };
                    player.sendMessage(msg);
                    PlayerHelper.giveBook(player);
                    break;
                }
                case 1: {
                    const msg = {
                        translate: FSLocalizedString.localize("chat.security_bot.answer.get_tablet", "Sure thing, §l%s§r! You will find a Security Tablet in your inventory!", "The Security Bot is an NPC in the bunker. The %s in the string represents the player name."),
                        with: [`${player.name}`]
                    };
                    player.sendMessage(msg);
                    entity.runCommand(`/clear "${player.name}" fs_sbunk:tablet`);
                    entity.runCommand(`/give "${player.name}" fs_sbunk:tablet 1`);
                    player.removeTag("fs_sbunk:tablet_keep");
                    player.removeTag("fs_sbunk:tablet_droppable");
                    FSWorldHelper.replaceTablets();
                    break;
                }
                case 2: {
                    const msg = {
                        translate: FSLocalizedString.localize("chat.security_bot.answer.say_hi", "Aww, thanks §l%s§r! I really appreciate it! Have a great day!", "The Security Bot is an NPC in the bunker. The %s in the string represents the player name."),
                        with: [`${player.name}`]
                    };
                    player.sendMessage(msg);
                    break;
                }
                case 3: {
                    const msg = {
                        translate: FSLocalizedString.localize("chat.security_bot.answer.say_goodbye", "Understood. I will leave you to it! Goodbye!", "The Security Bot is an NPC in the bunker. The %s in the string represents the player name.")
                    };
                    player.sendMessage(msg);
                    const location = entity.location;
                    world.playSound("mob.endermen.portal", location);
                    for (let i = 0; i < 250; i++) {
                        const x = Math.random() * 2 - 1;
                        const y = Math.random() * 2 - 1;
                        const z = Math.random() * 2 - 1;
                        entity.dimension.spawnParticle("minecraft:mob_portal", FSMath.add(location, { x, y, z }));
                    }
                    try {
                        entity.triggerEvent("fs:pop_to_item");
                    }
                    catch (error) {
                    }
                    finally {
                        system.runTimeout(() => {
                            if (entity.isValid()) {
                                entity.remove();
                            }
                        }, 1);
                    }
                }
            }
        });
    }
    showTrainingBotOptions(entity, player) {
        const form = new mcui.ActionFormData();
        form.title({
            translate: FSLocalizedString.localize("ui.training_bot.title", "Training Bot", "The Training Bot is an NPC in the bunker.")
        });
        form.body({
            translate: FSLocalizedString.localize("ui.training_bot.body", "Hello §l%s§r! What would you like to fight?", "The Training Bot is an NPC in the bunker. The %s in the string represents the player name."),
            with: [`${player.name}`]
        });
        form.button({
            translate: FSLocalizedString.localize("ui.training_bot.button.heal", "Heal me first!", "Button to heal the player")
        });
        form.button({
            translate: FSLocalizedString.localize("ui.training_bot.button.set_spawn", "Set my Spawn Point to here!", "Button to set the player spawn point")
        });
        form.button({
            translate: FSLocalizedString.localize("ui.training_bot.button.zombies", "Zombies!", "Button to fight zombies")
        });
        form.button({
            translate: FSLocalizedString.localize("ui.training_bot.button.skeletons", "Skeletons!", "Button to fight skeletons")
        });
        form.button({
            translate: FSLocalizedString.localize("ui.training_bot.button.creepers", "Creepers!", "Button to fight creepers")
        });
        form.button({
            translate: FSLocalizedString.localize("ui.training_bot.button.cancel", "Cancel", "Button to cancel the action")
        });
        form.show(player).then(resp => {
            if (resp.canceled) {
                return;
            }
            let selection = resp.selection || 0;
            let enemy_type = "";
            switch (selection) {
                case 0: {
                    let eo = {
                        amplifier: 255,
                        showParticles: true
                    };
                    player.addEffect("instant_health", 1, eo);
                    world.sendMessage({
                        translate: FSLocalizedString.localize("chat.training_bot.message.full_health", "<Training Bot> You are now back up to §lfull health§r!", "The Training Bot is an NPC in the bunker.")
                    });
                    world.playSound("fs.sbunk.chat_ping", entity.location);
                    system.runTimeout(() => {
                        world.sendMessage({
                            translate: FSLocalizedString.localize("chat.training_bot.message.ready_to_fight_1", "<Training Bot> Are you ready to §lfight§r now? If so, §linteract with me§r again.", "The Training Bot is an NPC in the bunker.")
                        });
                        world.playSound("fs.sbunk.chat_alert", entity.location);
                    }, 40);
                    break;
                }
                case 1: {
                    let dimensionLocation = {
                        dimension: player.dimension,
                        x: entity.location.x,
                        y: entity.location.y,
                        z: entity.location.z
                    };
                    player.setSpawnPoint(dimensionLocation);
                    world.sendMessage({
                        translate: FSLocalizedString.localize("chat.training_bot.message.spawn_point", "<Training Bot> Sure thing! You will respawn here if you die during training!", "The Training Bot is an NPC in the bunker.")
                    });
                    world.playSound("fs.sbunk.chat_ping", entity.location);
                    system.runTimeout(() => {
                        world.sendMessage({
                            translate: FSLocalizedString.localize("chat.training_bot.message.ready_to_fight_2", "<Training Bot> Are you ready to §lfight§r now? If so, §linteract with me§r again.", "The Training Bot is an NPC in the bunker.")
                        });
                        world.playSound("fs.sbunk.chat_alert", entity.location);
                    }, 40);
                    break;
                }
                case 2: {
                    enemy_type = "minecraft:zombie";
                    break;
                }
                case 3: {
                    enemy_type = "minecraft:skeleton";
                    break;
                }
                case 4: {
                    enemy_type = "minecraft:creeper";
                    break;
                }
            }
            if (enemy_type !== "") {
                world.sendMessage({
                    translate: FSLocalizedString.localize("chat.training_bot.message.get_ready", "<Training Bot> Get ready!", "The Training Bot is an NPC in the bunker.")
                });
                world.playSound("fs.sbunk.chat_ping", entity.location);
                system.runTimeout(() => {
                    world.sendMessage({
                        translate: FSLocalizedString.localize("chat.training_bot.message.3", "<Training Bot> 3...", "Countdown. The Training Bot is an NPC in the bunker.")
                    });
                    world.playSound("fs.sbunk.chat_ping", entity.location);
                }, 20);
                system.runTimeout(() => {
                    world.sendMessage({
                        translate: FSLocalizedString.localize("chat.training_bot.message.2", "<Training Bot> 2...", "Countdown. The Training Bot is an NPC in the bunker.")
                    });
                    world.playSound("fs.sbunk.chat_ping", entity.location);
                }, 40);
                system.runTimeout(() => {
                    world.sendMessage({
                        translate: FSLocalizedString.localize("chat.training_bot.message.1", "<Training Bot> 1...", "Countdown. The Training Bot is an NPC in the bunker.")
                    });
                    world.playSound("fs.sbunk.chat_ping", entity.location);
                }, 60);
                system.runTimeout(() => {
                    world.sendMessage({
                        translate: FSLocalizedString.localize("chat.training_bot.message.fight", "<Training Bot> §l§cFight§r!", "Instructing to fight! The Training Bot is an NPC in the bunker.")
                    });
                    world.playSound("fs.sbunk.chat_alert", entity.location);
                    try {
                        player.dimension.spawnEntity(enemy_type, EntityManager.getLocationOffsetByRotation(entity, 1, 0, 1));
                        player.dimension.spawnEntity(enemy_type, EntityManager.getLocationOffsetByRotation(entity, -1, 0, 1));
                        player.dimension.spawnEntity(enemy_type, EntityManager.getLocationOffsetByRotation(entity, 0, 0, 1));
                    }
                    catch (error) {
                        player.sendMessage({
                            translate: FSLocalizedString.localize("chat.training_bot.message.difficulty", "<Training Bot> Unable to spawn enemies! Check your game difficulty settings.", "Error spawning mobs. The Training Bot is an NPC in the bunker.")
                        });
                    }
                }, 80);
            }
        });
    }
    showExitCameraOptions(player) {
        const form = new mcui.ActionFormData();
        form.title(FSLocalizedString.localize("ui.camera.exit.title", "Camera", "The Camera is a device in the bunker."));
        form.body(FSLocalizedString.localize("ui.camera.exit.body", "What would you like to do?", "Ask the player what they want to do in camera mode"));
        form.button(FSLocalizedString.localize("ui.camera.exit.button.stop_viewing", "Stop Viewing Camera", "Button to stop viewing the camera"));
        form.button(FSLocalizedString.localize("ui.camera.exit.button.cancel", "Cancel", "Button to cancel the action"));
        form.show(player).then(resp => {
            if (resp.canceled) {
                return;
            }
            let selection = resp.selection || 0;
            switch (selection) {
                case 0: {
                    PlayerManager.sharedInstance().resetCamera(player);
                    break;
                }
            }
        });
    }
    showRootOptions(player) {
        const lastKnownVersion = FSDynamicProperty.getNumber(world, FSUtil.namespacedString("lastVersion")) || 0;
        const shouldShowMigrationTabletMessage = FSDynamicProperty.getBoolean(world, FSUtil.namespacedString("shouldShowMigrationTabletMessage")) || false;
        player.setDynamicProperty(FSUtil.namespacedString("will_charge_xp_for_placement"), false);
        if (shouldShowMigrationTabletMessage) {
            try {
                this.showMigrationTabletMessage(player);
            }
            catch (ex) { }
        }
        else {
            var rateRequestDate = FSDynamicProperty.getNumber(world, FSUtil.namespacedString("rateRequestDate")) || 0;
            var hasSeenRateRequest = FSDynamicProperty.getBoolean(world, FSUtil.namespacedString("hasSeenRateRequest")) || false;
            if (rateRequestDate === 0) {
                const sevenDaysFromNow = new Date();
                sevenDaysFromNow.setDate(sevenDaysFromNow.getDate() + 7);
                FSDynamicProperty.setNumber(world, FSUtil.namespacedString("rateRequestDate"), sevenDaysFromNow.getTime());
                rateRequestDate = sevenDaysFromNow.getTime();
                hasSeenRateRequest = false;
            }
            const currentDate = new Date().getTime();
            const rateRequestDateObj = new Date(rateRequestDate).getTime();
            if (!hasSeenRateRequest && currentDate >= rateRequestDateObj) {
                this.showRateRequest(player);
                FSDynamicProperty.setBoolean(world, FSUtil.namespacedString("hasSeenRateRequest"), true);
            }
            else {
                this.showRootOptionsLegacy(player);
            }
        }
    }
    showRateRequest(player) {
        const form = new FSActionFormData("rate_request", false);
        form.setTitle(FSLocalizedString.localize("ui.rate_request.title", "Rate Security++ Add-On", "Title for the rate request form"));
        form.setBody(FSLocalizedString.localize("ui.rate_request.body", "Are you enjoying this Add-On?", "Body text for the rate request form"));
        form.addButton("yes", FSLocalizedString.localize("ui.rate_request.button.yes", "Yes, I love it!", "Button to rate the addon"), "textures/57digital/sbunk/icons/love.png");
        form.addButton("yes_could_improve", FSLocalizedString.localize("ui.rate_request.button.yes_could_improve", "Yes, but it could be better.", "Button to rate the addon but with suggestions"), "textures/57digital/sbunk/icons/like.png");
        form.addButton("no", FSLocalizedString.localize("ui.rate_request.button.no", "No, not really...", "Button to not rate the addon"), "textures/57digital/sbunk/icons/hate.png");
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["yes"]) {
                    this.showRateForm(player, false);
                }
                else if (formResponseData["yes_could_improve"]) {
                    this.showRateForm(player, true);
                }
                else if (formResponseData["no"]) {
                    this.showNegativeReviewOptions(player);
                }
            }
        });
    }
    showRateForm(player, saidCouldBeImproved = false) {
        FSDynamicProperty.setBoolean(player, FSUtil.namespacedString("hasSeenRateRequest"), true);
        const form = new FSActionFormData("rate_form", false);
        form.setTitle(FSLocalizedString.localize("ui.rate_form.title", "Rate Security++ Add-On", "Title for the rate form"));
        let rawText = {
            rawtext: []
        };
        if (saidCouldBeImproved) {
            rawText.rawtext.push({
                translate: FSLocalizedString.localize("ui.rate_form.body_alt", "We`re glad you are enjoying this Add-On! We would love to hear your feedback. Please rate us on the Minecraft Marketplace, and contact us on Discord if you have any suggestions or issues.", "Body text for the rate form")
            });
        }
        else {
            rawText.rawtext.push({
                translate: FSLocalizedString.localize("ui.rate_form.body", "We`re glad you love this Add-On! Please rate us on the Minecraft Marketplace to show your support.", "Body text for the rate form")
            });
        }
        form.setBody(rawText);
        form.addButton("rate", FSLocalizedString.localize("ui.rate_form.button.rate", "Rate Now", "Button to rate the addon"), "textures/57digital/sbunk/icons/rate.png");
        if (saidCouldBeImproved) {
            form.addButton("discord", FSLocalizedString.localize("ui.rate_form.button.discord", "Speak to us on Discord", "Button to speak to the developers on Discord"), "textures/57digital/sbunk/icons/discord.png");
        }
        form.addButton("later", FSLocalizedString.localize("ui.rate_form.button.later", "Maybe later...", "Button to rate the addon later"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["rate"]) {
                    this.showRatingUrl(player);
                    FSDynamicProperty.setBoolean(player, FSUtil.namespacedString("hasSeenRateRequest"), true);
                }
                else if (formResponseData["discord"]) {
                    this.showDiscordUrl(player, "showRateForm");
                }
            }
        });
    }
    showRatingUrl(player) {
        const form = new FSActionFormData("rate_url", false);
        form.setTitle(FSLocalizedString.localize("ui.rate_url.title", "Rate Security++ Add-On", "Title for the rate URL form"));
        form.setBody({
            rawtext: [
                { translate: FSLocalizedString.localize("ui.rate_url.body", "Please rate this Add-On by going to: §bhttps://bit.ly/securityrating§r", "Body text for the rate URL form. DO NOT MODIFY URL.") },
                { text: "\n\n" },
                { translate: FSLocalizedString.localize("ui.rate_url.body2", "You can also pause the game -> go to Settings -> Behavior Packs -> Active -> Click `Security++ Add-On` -> Click `View in Store` and then leave your rating. ", "Body text for the rate URL form") }
            ]
        });
        form.addButton("close", FSLocalizedString.localize("ui.rate_url.button.close", "Close", "Button to close the form"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["close"]) {
                    player.sendMessage({
                        rawtext: [{ text: "§b[!] " }, { translate: "57d_sbunk.ui.rate_url.body2" }]
                    }); 
                }
            }
        });
    }
    showDiscordUrl(player, callbackFnName) {
        const form = new FSActionFormData("discord_url", false);
        form.setTitle(FSLocalizedString.localize("ui.discord_url.title", "Security++ Add-On Discord", "Title for the discord URL form"));
        form.setBody(FSLocalizedString.localize("ui.discord_url.body", "Join our Discord server: https://bit.ly/discord57. See you inside!", "Body text for the discord URL form"));
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.discord_url.button.close", "Close", "Button to close the form"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["close"]) {
                }
                else if (formResponseData["go_back"]) {
                    if (callbackFnName === "showRateForm") {
                        this.showRateForm(player, true);
                    }
                    if (callbackFnName === "showNegativeReviewOptions") {
                        this.showNegativeReviewOptions(player);
                    }
                    if (callbackFnName === "showChangelog") {
                        this.showChangelog(player);
                    }
                    if (callbackFnName === "reportBug") {
                        this.reportBug(player);
                    }
                }
            }
        });
    }
    showNegativeReviewOptions(player) {
        FSDynamicProperty.setBoolean(player, FSUtil.namespacedString("hasSeenRateRequest"), true);
        const form = new FSActionFormData("negative_review", false);
        form.setTitle(FSLocalizedString.localize("ui.negative_review.title", "Problem with Security++", "Title for the negative review form"));
        form.setBody(FSLocalizedString.localize("ui.negative_review.body", "Noooooo! We would love to hear your thoughts on how we can improve. Please contact us on Discord or email us at support@57digital.co.uk. We will do our best to improve your experience in an update. You can scan the QR code below to quickly add us on Discord if you wish.", "Body text for the negative review form"));
        form.addButton("discord", FSLocalizedString.localize("ui.negative_review.button.discord", "Contact us on Discord", "Button to contact the developers on Discord"), "textures/57digital/sbunk/icons/discord.png");
        form.addButton("close", FSLocalizedString.localize("ui.negative_review.button.close", "Close", "Button to close the form"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["discord"]) {
                    this.showDiscordUrl(player, "showNegativeReviewOptions");
                }
            }
        });
    }
    showMigrationTabletMessage(player) {
        const form = new FSActionFormData("migration_tablet_message", false);
        form.setTitle(FSLocalizedString.localize("ui.migration_tablet.title", "Welcome to SECURITY++", "Title for the migration tablet message"));
        let rawText = {
            rawtext: []
        };
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.migration_tablet.body1", "Welcome to your §cSECURITY++§r Add-On, previously known as the Secure Bunkers Add-On!", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.migration_tablet.body2", "We`ve listened to feedback from hundreds of players like you and made this Add-On even more powerful! It`s so awesome that we even gave it a new name to show off all the new stuff!", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n"
        });
        form.setBody(rawText);
        form.addButton("continue", FSLocalizedString.localize("ui.migration_tablet.button.tell_me_more", "Tell Me More...", "Button to continue"));
        player.playSound("57d_sbunk.tech_sound");
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["continue"]) {
                    this.showChangelog(player);
                }
            }
        });
    }
    showChangelog(player, showMoreDetails = false) {
        let form = new mcui.MessageFormData();
        form.title(FSLocalizedString.localize("ui.migration_tablet.title2", "SECURITY++ Add-On Changelog", "Title for the migration tablet message"));
        let rawText = {
            rawtext: []
        };
        rawText.rawtext.push({
            text: "§l§e"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.migration_tablet.body3", "WHAT`S NEW?", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n§r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.intro", "§rWe have completely overhauled this Add-On. Here is an overview of the changes and new features:", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_0", "§cMajor Security Fixes§r: Introducing `Super Admin` mode! Give ultimate control to one player and transfer these rights easily in the `Settings` menu. We`ve fixed a critical bug where security clearances were sometimes incorrect and tightened security options to keep everything safe and secure!", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_1", "§cOP chest options§r: We heard you! Some players don’t like the OP chests in bunkers. We’ve added a toggle in the `Settings` menu to limit OP chests to creative mode.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_2", "§cUndo Enhancements§r: Undo is now even better. You can even undo the bunker you built with your Security Tablet. Custom entities/mobs that get in the way of a room placement will now be teleported away instead of being killed. We will also give you your security items back if we remove any security features before building a room.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_3", "§cLockable Chests§r: You can now add locks to your chests to protect your precious loot. They even work on Ender Chests and Trapped Chests too!", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_4", "§cPlaceable Laser Doors§r: Place anywhere in your world! Works on floors and walls. Opens when a player has the correct access level. The lasers can also be turned off with the Laser Console.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_5", "§cLaser Consoles§r: Control your manual laser doors with these handy consoles!", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_6", "§cPlaceable Elevators§r: Place elevators anywhere you like! Seamlessly travel up and down floors anywhere in your world, not just in bunkers. You can now also set an entry sound that plays when a player accesses a floor (our personal favorite is the `Welcome to this floor` song).", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_7", "§cSecret Entrances§r: Hidden chests, trees, and beds that lead to secret areas anywhere in your world.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_8", "§cSecret Walls, Doors, Floors, Trapdoors, and Stairs§r: Add secret passageways anywhere in your world! They look like regular blocks and even work with custom texture packs. Shh!", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_9", "§cPlaceable Secure Doors§r: Guard any area of your world with access-controlled doors.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_10", "§cPlaceable Computer Monitors§r: Quickly access camera menus for players with the right security clearance!", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_11", "§cPlaceable Cameras§r: Place wall, ceiling, and floor cameras to keep an eye on everything! You can place a camera anywhere in your world, not just in bunkers! With brand new models for ceiling and wall cameras.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_12", "§cRoom Customization§r: You can remove rooms and change their type. We have also added a confirmation before removing rooms and some extra heads-up messages before creating a bunker.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_13", "§cLaser Door Controls§r: Turn laser doors on/off or destroy them when you don`t need them.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_14", "§cSecurity Chips§r: Put your hard-earned XP to good use! Buy Security Chips from your tablet and craft epic security items.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_15", "§cCraftable Items§r: Now you can craft cameras, lasers, guard dogs, turrets, security doors, secret trapdoors, secret doors, secret walls, secret floors, and tablets! Some recipes require a Security Chip, which can be purchased using your Security Tablet using XP (and only admins can purchase chips!). Find out how to craft items in your Security Tablet.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_16", "§cBunker Costs§r: Bunkers now cost Security Chips, except if you are in Creative Mode.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_17", "§cCamera Improvements§r: Flip through cameras faster than ever before!", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_18", "§cEasily Remove Security Features§r: Admins can now remove any security feature (like cameras, lasers, etc.) by hitting them three times.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_19", "§cTurret Upgrades§r: Set turrets to target mobs and players by default.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_21", "§cTablet Safety§r: Choose whether your Security Tablet stays fixed in your inventory or can be dropped.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_22", "§cEntity Improvements§r: Some entities now have enhanced knockback resistance and greater health.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_23", "§cNew Icons§r: New icons in your Security Tablet now make it easier to navigate around.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_24", "§cMiscellaneous§r: Pick up and spawn hoverboards elsewhere (and easily destroy them to turn them back into an item that you can place elsewhere), add guard dogs anywhere, and craft tablets if you lose them.", "Body text for the migration tablet message")
        });
        rawText.rawtext.push({
            text: "\n\n§c* §r"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.line_25", "§cBug Fixes§r: Plus lots of bug fixes and enhancements to make your experience better!", "Body text for the migration tablet message")
        });
        if (showMoreDetails) {
            rawText.rawtext.push({
                text: "\n\n§r"
            });
            rawText.rawtext.push({
                text: "§l§e"
            });
            rawText.rawtext.push({
                translate: FSLocalizedString.localize("ui.migration_tablet.about", "ABOUT:", "Body text for the migration tablet message")
            });
            rawText.rawtext.push({
                text: "\n§r"
            });
            rawText.rawtext.push({
                translate: FSLocalizedString.localize("ui.changelog.r2.version", "You are using SECURITY++ Add-On version: §d§l%1§r.", "Body text for the migration tablet message"),
                with: {
                    rawtext: [
                        { translate: "d008d087.6db1.471c.b15c.79d24119aeb0" } 
                    ]
                }
            });
            rawText.rawtext.push({
                text: "\n\n"
            });
        }
        form.body(rawText);
        if (showMoreDetails) {
            form.button2({ translate: FSLocalizedString.localize("ui.migration_tablet.button.report_bug", "Report Bug/Suggestions", "Button to go back") });
        }
        else {
            form.button2({ translate: FSLocalizedString.localize("ui.migration_tablet.button.go_back", "§o§c<- Go Back", "Button to go back") });
        }
        if (showMoreDetails) {
            form.button1({ translate: FSLocalizedString.localize("ui.migration_tablet.button.return", "Return to Tablet Menu", "Button to close") });
        }
        else {
            form.button1({ translate: FSLocalizedString.localize("ui.migration_tablet.button.continue", "§lContinue ->", "Button to continue") });
        }
        player.playSound("57d_sbunk.computer_noise");
        form.show(player).then(resp => {
            if (resp.canceled) {
                return;
            }
            let selection = resp.selection || 0;
            switch (selection) {
                case 1: {
                    if (showMoreDetails) {
                        this.reportBug(player);
                    }
                    else {
                        this.showMigrationTabletMessage(player);
                    }
                    break;
                }
                case 0: {
                    FSDynamicProperty.setBoolean(world, FSUtil.namespacedString("shouldShowMigrationTabletMessage"), false);
                    this.showRootOptionsLegacy(player);
                    break;
                }
            }
        });
    }
    reportBug(player) {
        const form = new FSActionFormData("report_bug", false);
        form.setTitle(FSLocalizedString.localize("ui.report_bug.title", "Report a Bug", "Title for the bug report form"));
        var rawText = { rawtext: [] };
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.report_bug.body2", "Got feedback? Noticed a new bug? Want to suggest a feature? Email us: support@57digital.co.uk. It helps if you tell us which platform you are playing on, the Add-On name, the version number (which you can find below!).", "Body text for the bug report form")
        });
        rawText.rawtext.push({
            text: "\n\n"
        });
        rawText.rawtext.push({
            translate: FSLocalizedString.localize("ui.changelog.r2.reportbug.version", "You are using SECURITY++ Add-On version: §d§l%1§r.", "Body text for the migration tablet message"),
            with: {
                rawtext: [
                    { translate: "d008d087.6db1.471c.b15c.79d24119aeb0" } 
                ]
            }
        });
        form.setBody(rawText);
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("discord", FSLocalizedString.localize("ui.report_bug.button.discord", "Join our Discord", "Button to join the Discord server"), "textures/57digital/sbunk/icons/discord.png");
        form.addButton("done", FSLocalizedString.localize("ui.report_bug.button.done", "Done", "Button to submit the bug report"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["go_back"]) {
                    this.showChangelog(player, true);
                }
                else if (formResponseData["discord"]) {
                    this.showDiscordUrl(player, "reportBug");
                }
            }
        });
    }
    showRootOptionsLegacy(player) {
        if (FSDynamicProperty.getBoolean(player, "is_camera")) {
            this.showExitCameraOptions(player);
            return;
        }
        if (FSPlayerPerms.sharedInstance().conditionallyPromptForBunkerRootUserPromotion(player)) {
            return; 
        }
        FSInventoryManager.replaceItemInHand(player, "fs_sbunk:tablet", 1);
        FSWorldHelper.replaceTablets();
        FSFormManager.sharedInstance().clearStackForPlayer(player); 
        const form = new FSActionFormData("root_menu", false);
        form.setTitle(FSLocalizedString.localize("ui.root.title", "Security Tablet", "The Security Tablet is a device in the bunker."));
        form.setBody(FSLocalizedString.localize("ui.root.body", "What would you like to do?", "Ask the player what they want to do in the Security Tablet"));
        form.addButton("security_features", FSLocalizedString.localize("ui.root.button.manage_defences", "Security Features >", "Button to manage defences"), "textures/57digital/sbunk/items/tablet_defence.png");
        form.addButton("manage_cameras", FSLocalizedString.localize("ui.root.button.manage_cameras", "Cameras >", "Button to manage cameras"), "textures/57digital/sbunk/items/tablet_camera.png");
        form.addButton("manage_players", FSLocalizedString.localize("ui.root.button.manage_players", "Manage Players >", "Button to manage players"), "textures/57digital/sbunk/items/tablet_player.png");
        form.addButton("settings", FSLocalizedString.localize("ui.root.button.settings", "Settings", "Button to show settings"), "textures/57digital/sbunk/icons/settings.png");
        form.addButton("changelog", FSLocalizedString.localize("ui.root.button.whats_new", "What`s New?", "Whats new button to show changelog"), "textures/57digital/sbunk/icons/whats_new.png");
        const last_undo_id = FSDynamicProperty.getString(world, "last_undo_id");
        const admin_access = FSPlayerPerms.sharedInstance().isAdmin(player) || FSPlayerPerms.sharedInstance().isSuperAdmin(player);
        const undo_array = StructureManager.GetUndoArray();
        if (undo_array.length > 0 && admin_access) {
            form.addButton("undo_last_action", FSLocalizedString.localize("ui.root.button.undo_last_action", "Undo Last Action", "Button to undo the last action"), "textures/57digital/sbunk/icons/undo.png");
        }
        form.addButton("ping_secret_entrances", FSLocalizedString.localize("ui.root.button.ping_secret_entrances", "Ping Secret Entrances", "Button to ping secret entrances"), "textures/57digital/sbunk/items/secret_wall.png");
        if (player.hasTag("fs_sbunk_is_dev")) {
            form.addButton("dev_options", FSLocalizedString.localize("ui.root.button.dev_options", "Dev Options", "Button to show developer options"), "textures/57digital/sbunk/icons/dev.png");
        }
        form.addButton("cancel", FSLocalizedString.localize("ui.root.button.cancel", "Cancel", "Button to cancel the action"));
        player.playSound("random.pop");
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const response = resp;
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_bunker"]) {
                    this._buildBunker(player);
                }
                else if (formResponseData["manage_cameras"]) {
                    this.showCameraDialogue(player);
                }
                else if (formResponseData["manage_players"]) {
                    FSPlayerPerms.sharedInstance().showProfilesPicker(player);
                    FSInventoryManager.replaceItemInHand(player, "fs_sbunk:tablet_player", 1);
                    FSWorldHelper.replaceTablets();
                }
                else if (formResponseData["manage_defences"]) {
                    this.showDefenceOptions(player);
                }
                else if (formResponseData["buy_security_chips"]) {
                    this.showBuySecurityChips(player);
                }
                else if (formResponseData["undo_last_action"]) {
                    this.showConfirmUndo(player);
                }
                else if (formResponseData["ping_secret_entrances"]) {
                    EntityManager.pingSecretEntrances(player);
                }
                else if (formResponseData["changelog"]) {
                    this.showChangelog(player, true);
                }
                else if (formResponseData["security_features"]) {
                    this.showSecurityFeaturesMenu(player);
                }
                else if (formResponseData["help_settings"]) {
                    this.showHelpSettings(player);
                }
                else if (formResponseData["dev_options"]) {
                    this.showDevOptions(player);
                }
                else if (formResponseData["settings"]) {
                    this.showSettings(player);
                }
            }
            else {
                console.error("Invalid response type received from form!");
            }
        });
    }
    showConfirmUndo(player) {
        const form = new FSActionFormData("confirm_undo", false);
        form.setTitle(FSLocalizedString.localize("ui.confirm_undo.title", "Confirm Undo", "Confirm Undo Title."));
        form.setBody(FSLocalizedString.localize("ui.confirm_undo.body", "Are you sure you want to undo?", "Ask the player if they are sure they want to undo."));
        form.addButton("undo", FSLocalizedString.localize("ui.confirm_undo.button.undo", "Yes, Undo!", "Button to undo"), "textures/57digital/sbunk/icons/undo.png");
        form.addButton("cancel", FSLocalizedString.localize("ui.confirm_undo.button.cancel", "Cancel", "Button to cancel"));
        player.playSound("random.pop");
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const response = resp;
                const formResponseData = response.getResponseData();
                if (formResponseData["undo"]) {
                    StructureManager.Undo(player);
                }
            }
        });
    }
    showDevOptions(player) {
        const form = new FSActionFormData("dev_options", false);
        form.setTitle("Developer Options");
        form.setBody("You should only access these options if you are a developer or have been instructed to do so by the developers. Some settings may break your experience.");
        form.addButton("show_connection_log", "Connection Log");
        form.addButton("edit_profile_json", "View Profile JSON");
        form.addButton("ok", "OK");
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["show_connection_log"]) {
                    this.showConnectionLog(player);
                }
                else if (formResponseData["edit_profile_json"]) {
                    this.editProfileJson(player);
                }
            }
        });
    }
    showConnectionLog(player) {
        const form = new FSActionFormData("connection_log", false);
        form.setTitle(FSLocalizedString.localize("ui.connection_log.title", "Connection Log", "Title for the connection log form"));
        const playerJoinLog = FSDynamicProperty.getArray(world, "player_join_log") || [];
        let numberedLog = playerJoinLog.map((log, index) => `§r#${index + 1}/${playerJoinLog.length}§r ${log}`).join("\n\n");
        var rawText = {
            rawtext: [
                { text: "§c" },
                { translate: FSLocalizedString.localize("ui.connection_log.body", "START OF LOG:", "Body text for the connection log form") },
                { text: "§r\n" },
                { text: numberedLog },
                { text: "\n\n§r§c" },
                { translate: FSLocalizedString.localize("ui.connection_log.tip", "If you have been asked to send us this log, please take a screen recording/video and capture the entire log (scroll right to the top to the `START OF LOG` section)", "Tip for the connection log form") }
            ]
        };
        form.setBody(rawText);
        form.addButton("ok", FSLocalizedString.localize("ui.conn_log.button.ok", "OK", "Button to close the form"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
        });
    }
    editProfileJson(player) {
        const form = new FSActionFormData("edit_profile_json", false);
        form.setTitle("View Profile JSON");
        const PERMISSION_STORAGE_KEY = FSUtil.namespacedString("permissions.profiles");
        var profiles = world.getDynamicProperty(PERMISSION_STORAGE_KEY);
        if (profiles) {
            try {
                profiles = JSON.parse(profiles);
            }
            catch (ex) {
                profiles = {};
            }
        }
        form.setBody(JSON.stringify(profiles, null, 2));
        form.addButton("change_to_invalid", "Invalidate Profiles");
        form.addButton("ok", "OK");
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["change_to_invalid"]) {
                    const keys = Object.keys(profiles);
                    const newProfiles = {};
                    let isFirstKey = true;
                    Object.keys(profiles).forEach(key => {
                        if (isFirstKey) {
                            newProfiles["skinStandardCust"] = profiles[key];
                            profiles[key]._id = "skinStandardCust";
                            profiles[key].name = "skinStandardCust";
                            isFirstKey = false;
                        }
                        else {
                            newProfiles[key] = profiles[key];
                        }
                    });
                    world.setDynamicProperty(PERMISSION_STORAGE_KEY, JSON.stringify(newProfiles));
                    console.error("Forced profile JSON to: " + JSON.stringify(newProfiles, null, 2));
                    FSPlayerPerms.sharedInstance().forceReadPlayerProfiles();
                }
            }
        });
    }
    _buildBunker(player) {
        if (!FSPlayerPerms.sharedInstance().isAdmin(player)) {
            player.sendMessage({
                translate: FSLocalizedString.localize("ui.build_bunker.error.permission", "You do not have permission to build a bunker.", "Error message for building a bunker")
            });
            return;
        }
        const validHeight = player.location.y >= -32;
        if (!validHeight) {
            player.sendMessage({
                translate: FSLocalizedString.localize("ui.build_bunker.error.height", "You need to be higher in the world to build a bunker.", "Error message for building a bunker at a low height")
            });
            player.sendMessage({
                translate: FSLocalizedString.localize("ui.build_bunker.error.height_tip", "§cTIP: You must be at least -32 block high.§r", "Error message for building a bunker at a low height")
            });
            return;
        }
        FSInventoryManager.replaceItemInHand(player, "fs_sbunk:tablet_bunker", 1);
        FSWorldHelper.replaceTablets();
        const hasBuiltBunker = FSDynamicProperty.getBoolean(world, FSUtil.namespacedString("hasBuiltBunker")) || false;
        if (hasBuiltBunker) {
            let warningForm = new mcui.MessageFormData();
            warningForm.title(FSLocalizedString.localize("ui.add_bunker.warning.title", "Add Another Bunker?", "Title for the warning message"));
            warningForm.body({
                rawtext: [
                    {
                        translate: FSLocalizedString.localize("ui.add_bunker.warning.body.0", "§cYou already have a bunker!§r Would you like to add another?", "Body for the warning message")
                    },
                    {
                        text: "\n\n"
                    },
                    {
                        translate: FSLocalizedString.localize("ui.add_bunker.warning.body.1", "§e[!] Be careful not to create a bunker too close to your existing one!", "Body for the warning message")
                    }
                ]
            });
            warningForm.button1(FSLocalizedString.localize("ui.add_bunker.warning.button.cancel", "Cancel", "Button text to cancel the action"));
            warningForm.button2(FSLocalizedString.localize("ui.add_bunker.warning.button.pick_new_entrance", "Pick New Bunker Entrance", "Button text to pick a new entrance for the bunker"));
            warningForm.show(player).then(resp => {
                if (resp.canceled) {
                    this.showRootOptions(player);
                    return;
                }
                let selection = resp.selection || 0;
                switch (selection) {
                    case 0: {
                        this.showRootOptions(player);
                        return;
                    }
                    case 1: {
                        StructureManager.sharedInstance().showEntranceDialogue(player);
                        break;
                    }
                }
            });
        }
        else {
            StructureManager.sharedInstance().showEntranceDialogue(player);
        }
    }
    showSecurityFeaturesMenu(player) {
        const form = new FSActionFormData("security_features", false);
        form.setTitle(FSLocalizedString.localize("ui.security_features.title", "Security Features", "Title for the security features menu"));
        form.setBody(FSLocalizedString.localize("ui.security_features.body", "All security features can be used anywhere in your world!", "Info about features"));
        form.addButton("buy_security_chips", FSLocalizedString.localize("ui.security_features.buy_security_chips", "Buy Security Chips >", "Button to buy security chips"), "textures/57digital/sbunk/items/security_chip.png");
        form.addButton("add_bunker", FSLocalizedString.localize("ui.security_features.add_bunker", "Add Secure Bunker >", "Button to add a new bunker"), "textures/57digital/sbunk/items/tablet_bunker.png");
        form.addButton("add_turret", FSLocalizedString.localize("ui.security_features.add_turret", "Add Security Turret >", "Button text for adding security turret"), "textures/57digital/sbunk/items/security_turret.png");
        form.addButton("add_camera", FSLocalizedString.localize("ui.security_features.add_camera", "Add CCTV Camera >", "Button text for adding camera"), "textures/57digital/sbunk/items/camera.png");
        form.addButton("add_computer_monitor", FSLocalizedString.localize("ui.security_features.add_computer_monitor", "Add Computer Monitor >", "Button text for adding computer monitor"), "textures/57digital/sbunk/items/computer_monitor.png");
        form.addButton("add_lasers", FSLocalizedString.localize("ui.security_features.add_laser_wall", "Add Laser Doors >", "Button text for adding laser doors"), "textures/57digital/sbunk/items/laser_beam_wall.png");
        form.addButton("add_secret_entrance", FSLocalizedString.localize("ui.security_features.add_secret_entrance", "Add Secret Entrance >", "Button text for adding secret entrance"), "textures/57digital/sbunk/items/entrance_bed.png");
        form.addButton("add_lockable_chest", FSLocalizedString.localize("ui.security_features.add_lockable_chest", "Add Lockable Chest >", "Button text for adding lockable chest"), "textures/57digital/sbunk/items/lockable_chest.png");
        form.addButton("add_secure_door", FSLocalizedString.localize("ui.security_features.add_secure_door", "Add Secure Door >", "Button text for adding secure door"), "textures/57digital/sbunk/items/security_door.png");
        form.addButton("add_elevator", FSLocalizedString.localize("ui.security_features.add_elevator", "Add Elevator >", "Button text for adding elevator"), "textures/57digital/sbunk/items/elevator_placeable.png");
        form.addButton("add_dog", FSLocalizedString.localize("ui.security_features.guard_dog", "Add Guard Dog >", "Button text for adding guard dog"), "textures/57digital/sbunk/items/security_dog.png");
        form.addButton("add_secret_door", FSLocalizedString.localize("ui.security_features.add_secret_door", "Add Secret Door >", "Button text for adding secret door"), "textures/57digital/sbunk/items/secret_door.png");
        form.addButton("add_secret_wall", FSLocalizedString.localize("ui.security_features.add_secret_wall", "Add Secret Wall >", "Button text for adding secret wall"), "textures/57digital/sbunk/items/secret_wall.png");
        form.addButton("add_secret_floor", FSLocalizedString.localize("ui.security_features.add_secret_floor", "Add Secret Floor >", "Button text for adding secret floor"), "textures/57digital/sbunk/items/secret_floor.png");
        form.addButton("add_secret_stairs", FSLocalizedString.localize("ui.security_features.add_secret_stairs", "Add Secret Stairs >", "Button text for adding secret stairs"), "textures/57digital/sbunk/items/secret_stairs.png");
        form.addButton("add_secret_trapdoor", FSLocalizedString.localize("ui.security_features.add_secret_trapdoor", "Add Secret Trapdoor >", "Button text for adding secret trapdoor"), "textures/57digital/sbunk/items/secret_trapdoor.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", CLOSE_COMMON);
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["go_back"]) {
                    this.showRootOptions(player);
                }
                else if (formResponseData["close"]) {
                }
                else if (formResponseData["add_bunker"]) {
                    this._buildBunker(player);
                }
                else if (formResponseData["add_turret"]) {
                    this.showTurretInfo(player);
                }
                else if (formResponseData["add_dog"]) {
                    this.explainGuardDog(player);
                }
                else if (formResponseData["add_camera"]) {
                    this.showCameraInfo(player);
                }
                else if (formResponseData["add_computer_monitor"]) {
                    this.showComputerMonitorInfo(player);
                }
                else if (formResponseData["add_lasers"]) {
                    this.showLaserInfo(player);
                }
                else if (formResponseData["buy_security_chips"]) {
                    this.showBuySecurityChips(player);
                }
                else if (formResponseData["add_secret_entrance"]) {
                    this.showSecretEntranceInfo(player);
                }
                else if (formResponseData["add_lockable_chest"]) {
                    this.showLockableChestInfo(player);
                }
                else if (formResponseData["add_secure_door"]) {
                    this.showSecureDoorInfo(player);
                }
                else if (formResponseData["add_elevator"]) {
                    this.showElevatorInfo(player);
                }
                else if (formResponseData["add_secret_door"]) {
                    this.showSecretDoorInfo(player);
                }
                else if (formResponseData["add_secret_trapdoor"]) {
                    this.showSecretTrapdoorInfo(player);
                }
                else if (formResponseData["add_secret_floor"]) {
                    this.showSecretFloorInfo(player);
                }
                else if (formResponseData["add_secret_stairs"]) {
                    this.showSecretStairsInfo(player);
                }
                else if (formResponseData["add_secret_wall"]) {
                    this.showSecretWallInfo(player);
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showRootOptions(player);
                }
            }
        });
    }
    showCameraInfo(player) {
        const form = new FSActionFormData("new_camera_info", false);
        form.setTitle(FSLocalizedString.localize("ui.camera_info.title", "CCTV Camera", "Title for the camera info menu"));
        form.setBody({
            rawtext: [
                { translate: FSLocalizedString.localize("ui.camera_info.body", "CCTV cameras can be placed anywhere in your world. They can be used to monitor your bunker, or any location in your world!", "Info about the camera") },
                { text: "\n\n" },
                CAN_BUY_CAMERAS_WITH_CHIPS ? { translate: FSLocalizedString.localize("ui.camera_info.balance", "[You have %1 Security Chips.]", "Balance of security chips"), with: [`${FSInventoryManager.getCountOfItem(player, "57d_sbunk:security_chip")}`] } : { text: "" }
            ]
        });
        if (CAN_BUY_CAMERAS_WITH_CHIPS) {
            var addCameraRaw = { rawtext: [] };
            addCameraRaw.rawtext.push({ translate: "Add Camera" });
            addCameraRaw.rawtext.push({ text: "\n" });
            addCameraRaw.rawtext.push({ translate: FSLocalizedString.localize("camera_cost", "[Cost: x%1 Security Chip]", "Cost of placing a camera"), with: [`${CAMERA_COST_XP}`] });
            form.addButton("add_camera", addCameraRaw, "textures/57digital/sbunk/items/camera.png");
        }
        form.addButton("craft_camera", FSLocalizedString.localize("ui.camera_info.button.craft_camera", "Craft: CCTV Camera", "Button to craft a camera"), "textures/57digital/sbunk/items/camera.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.camera_info.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["craft_camera"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:camera");
                }
                else if (formResponseData["go_back"]) {
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showCameraPurchaseSuccess(player) {
        const form = new FSActionFormData("camera_purchase_success", false);
        form.setTitle(FSLocalizedString.localize("ui.camera_purchase_success.title", "CCTV Camera Purchased", "Title for the camera purchase success menu"));
        form.setBody({
            rawtext: [
                { translate: FSLocalizedString.localize("ui.camera_purchase_success.body", "§aYou have successfully purchased a CCTV Camera! You can now place it anywhere in your world.", "Success message for purchasing a camera") },
                { text: "\n\n" },
                { translate: FSLocalizedString.localize("ui.camera_purchase_success.balance", "You now have %1 Security Chip(s).", "Balance of security chips"), with: [`${FSInventoryManager.getCountOfItem(player, "57d_sbunk:security_chip")}`] }
            ]
        });
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.camera_purchase_success.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["go_back"]) {
                    this.showCameraInfo(player);
                }
            }
        });
    }
    showCameraAffordabilityErrorChips(player) {
        const shortage = FSInventoryManager.calculateItemShortage(player, "57d_sbunk:security_chip", CAMERA_COST_XP);
        world.playSound("fs.sbunk.chat_alert", player.location);
        const form = new FSActionFormData("camera_affordability_error_chips", false);
        form.setTitle(FSLocalizedString.localize("ui.camera_affordability_error_chips.title", "Not Enough Security Chips", "Title for the camera affordability error menu"));
        form.setBody({
            rawtext: [
                { text: "§c" },
                { translate: FSLocalizedString.localize("ui.camera_affordability_error.body_chips.chips", "You don`t have enough Security Chips to buy a CCTV Camera! You need %s more Security Chips. Level up and try again!", "Error message for not having a security chip to place a camera"), with: [`${shortage}`] }
            ]
        });
        form.addButton("buy_chips", FSLocalizedString.localize("ui.camera_affordability_error_chips.button.buy_chips", "Buy Security Chips", "Button to buy security chips"), "textures/57digital/sbunk/items/security_chip.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.camera_affordability_error_chips.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["buy_chips"]) {
                    this.showBuySecurityChips(player);
                }
                else if (formResponseData["go_back"]) {
                    this.showCameraInfo(player);
                }
            }
        });
    }
    showCameraAffordabilityError(player) {
        const form = new FSActionFormData("camera_affordability_error", false);
        form.setTitle(FSLocalizedString.localize("ui.camera_affordability_error.title", "Not Enough XP", "Title for the camera affordability error menu"));
        form.setBody({
            rawtext: [
                { text: "§c" },
                { translate: FSLocalizedString.localize("ui.camera_affordability_error.body", "You do not have enough XP to place a camera!", "Error message for not having enough XP to place a camera") },
                {
                    text: "\n\n§r"
                },
                {
                    translate: FSLocalizedString.localize("ui.camera_affordability_error.body.current_xp", "[Current XP: §l%s§r]", "Displays the current XP the player has."),
                    with: [`${FSXPHelper.getXP(player)}`]
                }
            ]
        });
        form.addButton("how_get_xp", FSLocalizedString.localize("ui.camera_affordability_error.button.how_get_xp", "How to Get XP", "Button to show how to get XP"), "textures/57digital/sbunk/icons/help.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.camera_affordability_error.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["how_get_xp"]) {
                    this.showHelpXP(player, "showCameraAffordabilityError");
                }
                else if (formResponseData["go_back"]) {
                    this.showCameraInfo(player);
                }
            }
        });
    }
    showTurretInfo(player) {
        const form = new FSActionFormData("new_turret_info", false);
        form.setTitle(FSLocalizedString.localize("ui.turret_info.title", "Security Turret", "Title for the turret info menu"));
        form.setBody(FSLocalizedString.localize("ui.turret_info.body", "Security turrets can be placed anywhere in your world. They will automatically attack any hostile mobs that come near them, or players that do not have the correct security clearance.", "Info about the turret"));
        if (CAN_BUY_TURRETS_WITH_CHIPS) {
            const addTurretRaw = { rawtext: [] };
            addTurretRaw.rawtext.push({ translate: "Add Turret" });
            addTurretRaw.rawtext.push({ text: "\n" });
            addTurretRaw.rawtext.push({ translate: FSLocalizedString.localize("turret_cost", "[Cost: %1 XP]", "Cost of placing a turret"), with: [`${TURRET_COST_XP}`] });
            form.addButton("add_turret", addTurretRaw, "textures/57digital/sbunk/items/security_turret.png");
        }
        form.addButton("craft_turret", FSLocalizedString.localize("ui.turret_info.button.craft_turret", "Craft: Security Turret", "Button to craft a turret"), "textures/57digital/sbunk/items/security_turret.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.turret_info.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["craft_turret"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:security_turret");
                }
                else if (formResponseData["go_back"]) {
                }
            }
        });
    }
    showTurretAffordabilityError(player) {
        const form = new FSActionFormData("turret_affordability_error", false);
        form.setTitle(FSLocalizedString.localize("ui.turret_affordability_error.title", "Not Enough XP", "Title for the turret affordability error menu"));
        form.setBody({
            rawtext: [
                { text: "§c" },
                { translate: FSLocalizedString.localize("ui.turret_affordability_error.body", "You do not have enough XP to place a turret!", "Error message for not having enough XP to place a turret") },
                {
                    text: "\n\n§r"
                },
                {
                    translate: FSLocalizedString.localize("ui.turret_affordability_error.body.current_xp", "[Current XP: §l%s§r]", "Displays the current XP the player has."),
                    with: [`${FSXPHelper.getXP(player)}`]
                }
            ]
        });
        form.addButton("how_get_xp", FSLocalizedString.localize("ui.turret_affordability_error.button.how_get_xp", "How to Get XP", "Button to show how to get XP"), "textures/57digital/sbunk/icons/help.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.turret_affordability_error.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["how_get_xp"]) {
                    this.showHelpXP(player, "showTurretAffordabilityError");
                }
                else if (formResponseData["go_back"]) {
                    this.showTurretInfo(player);
                }
            }
        });
    }
    showHelpSettings(player) {
        const form = new FSActionFormData("help_settings", false);
        form.setTitle(FSLocalizedString.localize("ui.help_settings.title", "Help & Settings", "Title for the help and settings menu"));
        form.addButton("help", FSLocalizedString.localize("ui.help_settings.help", "Help", "Button to show help"), "textures/57digital/sbunk/icons/help.png");
        form.addButton("settings", FSLocalizedString.localize("ui.help_settings.settings", "Settings", "Button to show settings"), "textures/57digital/sbunk/icons/settings.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.help_settings.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["help"]) {
                    this.showHelp(player);
                }
                else if (formResponseData["settings"]) {
                    this.showSettings(player);
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showRootOptions(player);
                }
            }
        });
    }
    showHelp(player) {
        const form = new FSActionFormData("help", false);
        form.setTitle(FSLocalizedString.localize("ui.help.title", "Help", "Title for the help menu"));
        form.setBody("TBC");
        form.addButton("close", FSLocalizedString.localize("ui.help.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showHelpSettings(player);
                }
            }
        });
    }
    showSettings(player) {
        if (!FSPlayerPerms.sharedInstance().isSuperAdmin(player, false)) {
            FSFormManager.sharedInstance().navigationControllerForPlayer(player, false).clear();
            const errorTitle = FSLocalizedString.localize("ui.settings.error.title", "Access Denied!", "Title for the settings error menu");
            const rawMessage = {
                rawtext: [
                    { text: "§c" },
                    {
                        translate: FSLocalizedString.localize("ui.settings.error.body", "You do not have permission to access the settings menu. Ask the current Super Admin (%1) to transfer Super Admin rights to you if you think this is an error.", "Error message for accessing the settings menu"),
                        with: [FSPlayerPerms.sharedInstance().getSuperAdminPlayerName()]
                    }
                ]
            };
            FormManager.sharedInstance().showErrorAlert(player, errorTitle, rawMessage);
            return false;
        }
        else {
            const form = new FSModalFormData("settings_form", false);
            form.setTitle(FSLocalizedString.localize("ui.settings.title", "Settings", "Title for the settings menu"));
            let playerNames = FSPlayerPerms.sharedInstance().getAllPlayerProfileNames();
            const superAdmin = FSPlayerPerms.sharedInstance().getSuperAdminPlayerName();
            let superAdminSelectedIndex = playerNames.indexOf(superAdmin);
            if (superAdminSelectedIndex === -1) {
                superAdminSelectedIndex = 0;
            }
            form.addDropdown("super_admin", {
                rawtext: [{ translate: FSLocalizedString.localize("ui.settings.super_admin", "Super Admin:", "Super Admin") }]
            }, playerNames, superAdminSelectedIndex, false);
            form.addToggle("keep_tablet_on_death", {
                rawtext: [{ translate: FSLocalizedString.localize("ui.settings.keep_tablet_on_death", "Prevent Security Tablet from being dropped (all players with tablets)", "Prevent Security Tablet from being dropped.") }]
            }, FSDynamicProperty.getBoolean(world, FSUtil.namespacedString("keep_tablet_on_death")) || false);
            const opChestsInCreative = FSDynamicProperty.getBoolean(world, "op_chests_in_creative") || false;
            form.addToggle("op_chests_in_creative", {
                rawtext: [{ translate: FSLocalizedString.localize("ui.settings.op_chests_in_creative", "Bunkers include overpowered chests (`OP chests`) when built in Creative Mode", "When the player is in creative mode the bunkers will include chests with overpowered loot.") }]
            }, opChestsInCreative);
            const opChestsInSurvival = FSDynamicProperty.getBoolean(world, "op_chests_in_survival") || false;
            form.addToggle("op_chests_in_survival", {
                rawtext: [{ translate: FSLocalizedString.localize("ui.settings.op_chests_in_survival", "Bunkers include overpowered chests (`OP chests`) when built in Survival Mode", "When the player is in survival mode the bunkers will include chests with overpowered loot.") }]
            }, opChestsInSurvival);
            const showSecretEntranceOutline = FSDynamicProperty.has(world, "show_secret_entrance_outline") ? FSDynamicProperty.getBoolean(world, "show_secret_entrance_outline") : true;
            form.addToggle("show_secret_entrance_outline", {
                rawtext: [{ translate: FSLocalizedString.localize("ui.settings.show_secret_entrance_outline", "Allow Secret Entrances to display an outline when they are open", "Show Secret Entrance Outline") }]
            }, showSecretEntranceOutline);
            const canPlayTurretSound = FSDynamicProperty.getBoolean(world, "can_play_turret_sound");
            form.addToggle("can_play_turret_sound", {
                rawtext: [{ translate: FSLocalizedString.localize("ui.settings.can_play_turret_sound", "Allow Security Turrets to play sounds when they attack", "Allow Security Turrets to play sounds when they attack.") }]
            }, canPlayTurretSound);
            form.push(player, false, resp => {
                if (resp.canceled) {
                    return;
                }
                if (resp instanceof FSModalFormResponse) {
                    const formResponseData = resp.getResponseData();
                    const keepTabletOnDeath = formResponseData["keep_tablet_on_death"] || false;
                    FSDynamicProperty.setBoolean(world, FSUtil.namespacedString("keep_tablet_on_death"), keepTabletOnDeath);
                    FSWorldHelper.replaceTablets();
                    const opChestsInCreative = formResponseData["op_chests_in_creative"] || false;
                    FSDynamicProperty.setBoolean(world, "op_chests_in_creative", opChestsInCreative);
                    const opChestsInSurvival = formResponseData["op_chests_in_survival"] || false;
                    FSDynamicProperty.setBoolean(world, "op_chests_in_survival", opChestsInSurvival);
                    const showSecretEntranceOutline = formResponseData["show_secret_entrance_outline"] || false;
                    FSDynamicProperty.setBoolean(world, "show_secret_entrance_outline", showSecretEntranceOutline);
                    const superAdminIndex = formResponseData["super_admin"];
                    if (superAdminSelectedIndex !== -1 && superAdminSelectedIndex !== superAdminIndex) {
                        const newSuperAdmin = playerNames[superAdminIndex];
                        FSPlayerPerms.sharedInstance().makeUserRoot(newSuperAdmin, player, "show_success");
                    }
                    const canPlayTurretSound = formResponseData["can_play_turret_sound"];
                    FSDynamicProperty.setBoolean(world, "can_play_turret_sound", canPlayTurretSound);
                    world.playSound("57d_sbunk.servo", player.location);
                    world.sendMessage({
                        translate: FSLocalizedString.localize("ui.settings.save_success", "§b[!] Settings saved successfully!", "Success message for saving settings")
                    });
                }
            });
        }
    }
    showRootUserChangeSuccess(newRootUserName, player) {
        const form = new FSActionFormData("root_user_change_success", false);
        form.setTitle(FSLocalizedString.localize("ui.root_user_change_success.title", "Super Admin Changed!", "Title for the root user change success menu"));
        form.setBody({
            rawtext: [{ translate: FSLocalizedString.localize("ui.root_user_change_success.body", "§a%s is now the Super Admin! They have the highest level of access.", "Success message for changing the root user"), with: [newRootUserName] }]
        });
        form.addButton("ok", FSLocalizedString.localize("ui.root_user_change_success.button.ok", "OK", "Button to continue"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["ok"]) {
                    this.showHelpSettings(player);
                }
            }
        });
    }
    showAccessDenied(player) {
        player.playSound("fs.sbunk.access_denied");
        FSFormManager.sharedInstance().clearStackForPlayer(player);
        const form = new FSActionFormData("access_denied_dlg", false);
        form.setTitle(FSLocalizedString.localize("ui.access_denied.title", "Access Denied", "Title for the access denied menu"));
        form.setBody({
            rawtext: [
                { text: "§c" },
                { translate: FSLocalizedString.localize("ui.access_denied.body", "You do not have permission to access this feature.", "Body for the access denied menu") },
                { text: "\n\n" },
                {
                    translate: FSLocalizedString.localize("ui.access_denied.body_tip", "If you believe this is an error, please ask the Super Admin (`%1`) to grant you admin access via their Security Tablet. If you are supposed to be the Super Admin, ask them to transfer Super Admin access to you (Security Tablet > Help & Settings > Settings > Change Super Admin).", "Tip for the access denied menu"),
                    with: [FSPlayerPerms.sharedInstance().getSuperAdminPlayerName() || "Unknown Player"]
                }
            ]
        });
        form.addButton("ok", FSLocalizedString.localize("ui.access_denied.button.ok", "OK", "Button to continue"));
        FSFormManager.sharedInstance().clearStackForPlayer(player);
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
            }
        });
    }
    showErrorAlert(player, title, message) {
        player.playSound("fs.sbunk.access_denied");
        FSFormManager.sharedInstance().clearStackForPlayer(player);
        const form = new FSActionFormData("access_denied_dlg", false);
        form.setTitle(title);
        form.setBody(message);
        form.addButton("ok", FSLocalizedString.localize("ui.general.button.ok", "OK", "Button to continue"));
        FSFormManager.sharedInstance().clearStackForPlayer(player);
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
        });
    }
    showCraftingRecipe(player, recipeId) {
        let recipe;
        const recipeData = ALL_CRAFTING_RECIPES[recipeId] || undefined;
        if (recipeData) {
            recipe = recipeData["minecraft:recipe_shaped"];
            const pattern = recipe["pattern"];
            const ingredients = recipe["key"];
            const result = recipe["result"];
            const resultingItem = result["item"];
            var colors = ["§c", "§6", "§d", "§a", "§4", "§1", "§e"];
            var colorIndex = 0;
            var keyColors = {};
            var hasSecurityChip = false;
            var rawText = { rawtext: [] };
            rawText.rawtext.push({ translate: "§e§lCRAFTING RECIPE:" });
            rawText.rawtext.push({ text: "\n§r" });
            rawText.rawtext.push({ translate: "  §8*********" });
            rawText.rawtext.push({ text: "\n§r" });
            pattern.forEach((row) => {
                rawText.rawtext.push({ text: "  §8* " });
                const rowSymbols = row.split("");
                rowSymbols.forEach((symbol) => {
                    if (symbol === "#") {
                        rawText.rawtext.push({ text: "§7- " });
                    }
                    else {
                        var color = colors[colorIndex];
                        if (keyColors[symbol]) {
                            color = keyColors[symbol];
                        }
                        else {
                            colorIndex++;
                        }
                        rawText.rawtext.push({ text: color + symbol + " " });
                        keyColors[symbol] = color;
                    }
                });
                rawText.rawtext.push({ text: "§8*" });
                rawText.rawtext.push({ text: "\n§r" });
            });
            rawText.rawtext.push({ translate: "  §8*********" });
            rawText.rawtext.push({ text: "\n§r" });
            rawText.rawtext.push({ translate: "§e§lKEY:" });
            rawText.rawtext.push({ text: "\n§r" });
            Object.keys(ingredients).forEach((key) => {
                const colorForKey = keyColors[key];
                rawText.rawtext.push({ text: "  " });
                rawText.rawtext.push({ text: colorForKey + key + ": " });
                let rawName = "item." + ingredients[key]["item"];
                if (rawName.includes("minecraft:")) {
                    rawName = rawName.replace("minecraft:", "");
                    rawName = rawName + ".name";
                    if (rawName === "item.bed.name") {
                        rawName = FSLocalizedString.localize("item.bed.name", "Bed", "Name for the bed item");
                    }
                    if (rawName === "item.glass_pane.name") {
                        rawName = FSLocalizedString.localize("item.glass_pane.name", "Glass Pane", "Name for the glass pane item");
                    }
                    if (rawName === "item.chest.name") {
                        rawName = FSLocalizedString.localize("item.chest.name", "Chest", "Name for the chest item");
                    }
                    if (rawName === "item.oak_sapling.name") {
                        rawName = FSLocalizedString.localize("item.oak_sapling.name", "Oak Sapling", "Name for the oak sapling item");
                    }
                    if (rawName === "item.cobblestone.name") {
                        rawName = FSLocalizedString.localize("item.cobblestone.name", "Cobblestone Block", "Name for the cobblestone item");
                    }
                    if (rawName === "item.iron_block.name") {
                        rawName = FSLocalizedString.localize("item.iron_block.name", "Iron Block", "Name for the iron block item");
                    }
                    if (rawName === "item.trapdoor.name") {
                        rawName = FSLocalizedString.localize("item.trapdoor.name", "Trapdoor", "Name for the trapdoor item");
                    }
                    if (rawName === "item.redstone_block.name") {
                        rawName = FSLocalizedString.localize("item.redstone_block.name", "Redstone Block", "Name for the redstone block item");
                    }
                    if (rawName === "item.glass.name") {
                        rawName = FSLocalizedString.localize("item.glass.name", "Glass Block", "Name for the glass block item");
                    }
                    if (rawName === "item.oak_stairs.name") {
                        rawName = FSLocalizedString.localize("item.oak_stairs.name", "Oak Stairs", "Name for the oak stairs item");
                    }
                }
                rawText.rawtext.push({ translate: rawName });
                if (ingredients[key]["item"] === "57d_sbunk:security_chip") {
                    hasSecurityChip = true;
                    rawText.rawtext.push({ text: "§r*" });
                }
                rawText.rawtext.push({ text: "\n§r" });
            });
            if (hasSecurityChip) {
                rawText.rawtext.push({ text: "\n§r*" });
                rawText.rawtext.push({ translate: "You can buy Security Chips from the Security Tablet." });
            }
            const form = new FSActionFormData("crafting_recipe", false);
            const itemName = `item.${resultingItem}`;
            form.setTitle({ rawtext: [{ translate: FSLocalizedString.localize("ui.crafting.recipe.title", "Recipe", "Title for the crafting recipe menu") }, { text: ": " }, { translate: itemName }] });
            form.setBody(rawText);
            form.addButton("go_back", GO_BACK_COMMON);
            form.addButton("close", FSLocalizedString.localize("ui.crafting.recipe.button.close", "Close", "Button to close"));
            form.push(player, false, resp => {
                if (resp.canceled) {
                    return;
                }
                if (resp instanceof FSActionFormResponse) {
                    const formResponseData = resp.getResponseData();
                    if (formResponseData["close"]) {
                    }
                    if (formResponseData["go_back"]) {
                        FSFormManager.sharedInstance().clearStackForPlayer(player);
                        switch (resultingItem) {
                            case "57d_sbunk:computer_monitor":
                                this.showComputerMonitorInfo(player);
                                break;
                            case "57d_sbunk:laser_floor":
                            case "57d_sbunk:laser_wall":
                            case "57d_sbunk:laser_console":
                                this.showLaserInfo(player);
                                break;
                            case "57d_sbunk:secret_entrance_bed":
                            case "57d_sbunk:secret_entrance_chest":
                            case "57d_sbunk:secret_entrance_tree":
                            case "57d_sbunk:entrance_bed":
                            case "57d_sbunk:entrance_chest":
                            case "57d_sbunk:entrance_tree":
                                this.showSecretEntranceInfo(player);
                                break;
                            case "57d_sbunk:lockable_chest":
                                this.showLockableChestInfo(player);
                                break;
                            case "57d_sbunk:security_door":
                                this.showSecureDoorInfo(player);
                                break;
                            case "57d_sbunk:elevator":
                                this.showElevatorInfo(player);
                                break;
                            case "57d_sbunk:secret_door":
                                this.showSecretDoorInfo(player);
                                break;
                            case "57d_sbunk:secret_trapdoor":
                                this.showSecretTrapdoorInfo(player);
                                break;
                            case "57d_sbunk:secret_floor":
                                this.showSecretFloorInfo(player);
                                break;
                            case "57d_sbunk:secret_stairs":
                                this.showSecretStairsInfo(player);
                                break;
                            case "57d_sbunk:secret_wall":
                                this.showSecretWallInfo(player);
                                break;
                            case "57d_sbunk:security_dog":
                                this.explainGuardDog(player);
                                break;
                            case "57d_sbunk:elevator_placeable": {
                                this.showElevatorInfo(player);
                                break;
                            }
                            case "57d_sbunk:camera":
                                this.showCameraInfo(player);
                                break;
                            case "57d_sbunk:secret_stairs":
                                this.showSecretStairsInfo(player);
                                break;
                            case "57d_sbunk:security_turret":
                                this.showTurretInfo(player);
                                break;
                            default:
                                this.showSecurityFeaturesMenu(player);
                                break;
                        }
                    }
                    else {
                        FSFormManager.sharedInstance().clearStackForPlayer(player);
                        this.showSecurityFeaturesMenu(player);
                    }
                }
            });
        }
        else {
            player.sendMessage({
                translate: FSLocalizedString.localize("ui.crafting.recipe_not_found", "Recipe not found!", "Error message for when a recipe is not found")
            });
        }
    }
    showComputerMonitorInfo(player) {
        const form = new FSActionFormData("computer_monitor_options", false);
        form.setTitle(FSLocalizedString.localize("ui.computer_monitor_options.title", "Computer Monitor", "Title for the computer monitor menu"));
        form.setBody(FSLocalizedString.localize("ui.computer_monitor_options.body", "Computer Monitors allow you to quickly access your CCTV Cameras without using your Security Tablet. You can place Computer Terminals anywhere in your world.", "Body text for the computer monitor menu"));
        form.addButton("add_computer_monitor", FSLocalizedString.localize("ui.computer_monitor_options.add_monitor", "Craft: Computer Monitor", "Button to add computer monitor"), "textures/57digital/sbunk/items/computer_monitor.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.computer_monitor_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_computer_monitor"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:computer_monitor");
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showLaserInfo(player) {
        const form = new FSActionFormData("laser_options", false);
        form.setTitle(FSLocalizedString.localize("ui.laser_options.title", "Laser Doors", "Title for the laser doors menu"));
        var rawText = { rawtext: [] };
        rawText.rawtext.push({ translate: "There are two types of laser doors: upright and sideway. Place upright lasers on the floor and sideway lasers on the walls. Your laser will automatically expand up to 6 blocks in length. You need to also add a Laser Console near your lasers to control them." });
        rawText.rawtext.push({ text: "\n\n" });
        rawText.rawtext.push({ translate: "§e§lCRAFTING RECIPES:" });
        rawText.rawtext.push({ text: "\n§r" });
        form.setBody(rawText);
        form.addButton("add_upright_laser", FSLocalizedString.localize("ui.laser_options.add_upright", "Craft: Upright Laser Wall", "Button to add upright laser"), "textures/57digital/sbunk/items/laser_beam_floor.png");
        form.addButton("add_sideway_laser", FSLocalizedString.localize("ui.laser_options.add_sideway", "Craft: Sideway Laser Wall", "Button to add upright laser"), "textures/57digital/sbunk/items/laser_beam_wall.png");
        form.addButton("add_laser_console", FSLocalizedString.localize("ui.laser_options.add_console", "Craft: Laser Console", "Button to add laser console"), "textures/57digital/sbunk/items/laser_console.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.laser_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_upright_laser"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:laser_floor");
                }
                else if (formResponseData["add_sideway_laser"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:laser_wall");
                }
                else if (formResponseData["add_laser_console"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:laser_console");
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showSecretEntranceInfo(player) {
        const form = new FSActionFormData("secret_entrance_options", false);
        form.setTitle(FSLocalizedString.localize("ui.secret_entrance_options.title", "Secret Entrance", "Title for the secret entrance menu"));
        form.setBody(FSLocalizedString.localize("ui.secret_entrance_options.body", "Choose a secret entrance to add to your world. You can place it anywhere!", "Body text for the secret entrance menu"));
        form.addButton("add_secret_bed", FSLocalizedString.localize("ui.secret_entrance_options.add_bed", "Craft: Secret Bed", "Button to add secret bed"), "textures/57digital/sbunk/items/entrance_bed.png");
        form.addButton("add_secret_chest", FSLocalizedString.localize("ui.secret_entrance_options.add_chest", "Craft: Secret Chest", "Button to add secret chest"), "textures/57digital/sbunk/items/entrance_chest.png");
        form.addButton("add_secret_tree", FSLocalizedString.localize("ui.secret_entrance_options.add_tree", "Craft: Secret Tree", "Button to add secret tree"), "textures/57digital/sbunk/items/entrance_tree.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.secret_entrance_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_secret_bed"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:entrance_bed_0");
                }
                else if (formResponseData["add_secret_chest"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:entrance_chest");
                }
                else if (formResponseData["add_secret_tree"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:entrance_tree");
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showLockableChestInfo(player) {
        const form = new FSActionFormData("lockable_chest_options", false);
        form.setTitle(FSLocalizedString.localize("ui.lockable_chest_options.title", "Lockable Chest", "Title for the lockable chest menu"));
        form.setBody(FSLocalizedString.localize("ui.lockable_chest_options.body", "You can lock a Chest by using your Security Tablet on a Chest. Only authorized players can open it! When your Chest has been locked, simply open it as usual while NOT holding your Security Tablet.", "Body text for the lockable chest menu"));
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.lockable_chest_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["go_back"]) {
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showSecureDoorInfo(player) {
        const form = new FSActionFormData("secure_door_options", false);
        form.setTitle(FSLocalizedString.localize("ui.secure_door_options.title", "Secure Door", "Title for the secure door menu"));
        form.setBody(FSLocalizedString.localize("ui.secure_door_options.body", "Place a secure door in your world. Only authorized players can open it!", "Body text for the secure door menu"));
        form.addButton("add_secure_door", FSLocalizedString.localize("ui.secure_door_options.add_door", "Craft: Secure Door", "Button to add secure door"), "textures/57digital/sbunk/items/security_door.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.secure_door_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_secure_door"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:security_door");
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showElevatorInfo(player) {
        const form = new FSActionFormData("elevator_options", false);
        form.setTitle(FSLocalizedString.localize("ui.elevator_options.title", "Elevator", "Title for the elevator menu"));
        form.setBody(FSLocalizedString.localize("ui.elevator_options.body", "Place an elevator anywhere in your world. Only authorized players can use it! Stack multiple elevators vertically to enable seamless travel between floors.", "Body text for the elevator menu"));
        form.addButton("add_elevator", FSLocalizedString.localize("ui.elevator_options.add_elevator", "Craft: Elevator", "Button to add elevator"), "textures/57digital/sbunk/items/elevator_placeable.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.elevator_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_elevator"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:elevator_placeable");
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showSecretWallInfo(player) {
        const form = new FSActionFormData("secret_wall_options", false);
        form.setTitle(FSLocalizedString.localize("ui.secret_wall_options.title", "Secret Wall", "Title for the secret wall menu"));
        form.setBody(FSLocalizedString.localize("ui.secret_wall_options.body", "Place a secret wall in your world. Only authorized players can open it! A secret wall is made from blocks - so it can not be seen!", "Body text for the secret wall menu"));
        form.addButton("add_secret_wall", FSLocalizedString.localize("ui.secret_wall_options.add_wall", "Craft: Secret Wall", "Button to add secret wall"), "textures/57digital/sbunk/items/secret_wall.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.secret_wall_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_secret_wall"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:secret_wall");
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showSecretDoorInfo(player) {
        const form = new FSActionFormData("secret_door_options", false);
        form.setTitle(FSLocalizedString.localize("ui.secret_door_options.title", "Secret Door", "Title for the secret door menu"));
        form.setBody(FSLocalizedString.localize("ui.secret_door_options.body", "Place a secret door in your world. Only authorized players can open it! A secret door is made from blocks - so it can not be seen!", "Body text for the secret door menu"));
        form.addButton("add_secret_door", FSLocalizedString.localize("ui.secret_door_options.add_door", "Craft: Secret Door", "Button to add secret door"), "textures/57digital/sbunk/items/secret_door.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.secret_door_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_secret_door"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:secret_door");
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showSecretTrapdoorInfo(player) {
        const form = new FSActionFormData("secret_trapdoor_options", false);
        form.setTitle(FSLocalizedString.localize("ui.secret_trapdoor_options.title", "Secret Trapdoor", "Title for the secret trapdoor menu"));
        form.setBody(FSLocalizedString.localize("ui.secret_trapdoor_options.body", "Place a secret trapdoor in your world. Only authorized players can open it! A secret trapdoor is made from blocks - so it can not be seen!", "Body text for the secret trapdoor menu"));
        form.addButton("add_secret_trapdoor", FSLocalizedString.localize("ui.secret_trapdoor_options.add_trapdoor", "Craft: Secret Trapdoor", "Button to add secret trapdoor"), "textures/57digital/sbunk/items/secret_trapdoor.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.secret_trapdoor_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_secret_trapdoor"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:secret_trapdoor");
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showSecretFloorInfo(player) {
        const form = new FSActionFormData("secret_floor_options", false);
        form.setTitle(FSLocalizedString.localize("ui.secret_floor_options.title", "Secret Floor", "Title for the secret floor menu"));
        form.setBody(FSLocalizedString.localize("ui.secret_floor_options.body", "Place a secret floor in your world. Only authorized players can open it! A secret floor is made from blocks - so it can not be seen!", "Body text for the secret floor menu"));
        form.addButton("add_secret_floor", FSLocalizedString.localize("ui.secret_floor_options.add_floor", "Craft: Secret Floor", "Button to add secret floor"), "textures/57digital/sbunk/items/secret_floor.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.secret_floor_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_secret_floor"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:secret_floor");
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showSecretStairsInfo(player) {
        const form = new FSActionFormData("secret_stairs_options", false);
        form.setTitle(FSLocalizedString.localize("ui.secret_stairs_options.title", "Secret Stairs", "Title for the secret stairs menu"));
        form.setBody(FSLocalizedString.localize("ui.secret_stairs_options.body", "Place secret stairs in your world. Only authorized players can open it! A secret staircase is made from blocks - so it can not be seen!", "Body text for the secret stairs menu"));
        form.addButton("add_secret_stairs", FSLocalizedString.localize("ui.secret_stairs_options.add_stairs", "Craft: Secret Stairs", "Button to add secret stairs"), "textures/57digital/sbunk/items/secret_stairs.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.secret_stairs_options.button.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["add_secret_stairs"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:secret_stairs");
                }
                else if (formResponseData["close"]) {
                }
                else {
                    FSFormManager.sharedInstance().clearStackForPlayer(player);
                    this.showSecurityFeaturesMenu(player);
                }
            }
        });
    }
    showLockedChestOptions(player, block, block_loc) {
        system.run(() => {
            const form = new mcui.ActionFormData();
            form.title(FSLocalizedString.localize("ui.locked_chest_options.title", "Locked Chest Options", "Title for locked chest options"));
            form.button(FSLocalizedString.localize("ui.locked_chest_options.add_turret", "Lock Chest", "Button text for adding security turret"));
            form.button(FSLocalizedString.localize("ui.locked_chest_options.cancel", "Cancel", "Button text for canceling"));
            form.show(player).then(resp => {
                if (resp.canceled) {
                    return;
                }
                const selection = resp.selection || 0;
                switch (selection) {
                    case 0: {
                        LockedBlock.lockBlock(block, player);
                        break;
                    }
                }
            });
        });
    }
    showDefenceOptions(player) {
        world.sendMessage("You tried to access a deprecated feature. Please update your Security++ Add-On to the latest version.");
        return;
        const form = new mcui.ActionFormData();
        form.title(FSLocalizedString.localize("ui.defence_options.title", "Defence Options", "Title for defence options"));
        form.body(FSLocalizedString.localize("ui.defence_options.body", "What would you like to do?", "Body text for defence options"));
        form.button(FSLocalizedString.localize("ui.defence_options.add_turret", "Add Security Turret", "Button text for adding security turret"), "textures/57digital/sbunk/items/security_turret.png");
        form.button(FSLocalizedString.localize("ui.defence_options.guard_dog", "Add Guard Dog", "Button text for adding guard dog"), "textures/57digital/sbunk/items/security_dog.png");
        form.button(FSLocalizedString.localize("ui.defence_options.cancel", "Cancel", "Button text for canceling"));
        form.show(player).then(resp => {
            if (resp.canceled) {
                return;
            }
            const selection = resp.selection || 0;
            switch (selection) {
                case 0: {
                    this.showSecurityTurretOptions(player);
                    break;
                }
                case 1: {
                    const error = new mcui.ActionFormData();
                    error.title(FSLocalizedString.localize("ui.guard_dog.title", "Guard Dog", "Title for guard dog"));
                    error.body(FSLocalizedString.localize("ui.guard_dog.body", "To obtain a Guard Dog you must first build a Security Room. A Guard Dog will be waiting for you inside!", "Body text for obtaining a guard dog"));
                    error.button(FSLocalizedString.localize("ui.guard_dog.close", "Close", "Button text for closing"));
                    error.show(player);
                    break;
                }
            }
        });
    }
    explainGuardDog(player) {
        const form = new FSActionFormData("guard_dog_explain", false);
        form.setTitle(FSLocalizedString.localize("ui.guard_dog.explain.title", "Guard Dog", "Title for guard dog"));
        form.setBody(FSLocalizedString.localize("ui.guard_dog.explain.body", "Guard Dogs can be found in the Security Room inside Bunkers, or you an craft them! Follow the recipe below to craft a Guard Dog.", "Body text for obtaining a guard dog"));
        form.addButton("craft_dog", FSLocalizedString.localize("ui.guard_dog.explain.craft", "Craft: Guard Dog", "Button text for crafting guard dog"), "textures/57digital/sbunk/items/security_dog.png");
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.guard_dog.explain.close", "Close", "Button text for closing"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["craft_dog"]) {
                    this.showCraftingRecipe(player, "57d_sbunk:security_dog");
                }
                else if (formResponseData["close"]) {
                }
                else if (formResponseData["go_back"]) {
                    this.showRootOptions(player);
                }
            }
        });
    }
    showBuySecurityChips(player) {
        FSFormManager.sharedInstance().clearStackForPlayer(player);
        const form = new FSActionFormData("root_menu", false);
        form.setTitle(FSLocalizedString.localize("ui.buy_security_chips.title", "Buy Security Chips", "Title for security chip shop."));
        const body = {
            rawtext: [
                {
                    translate: FSLocalizedString.localize("ui.buy_security_chips.body", "Security Chips are used in some SECURITY++ crafting recipes, or you can buy security features with them. Only admins can buy chips from this store.", "Body text for security chip shop.")
                },
                {
                    text: "\n\n"
                },
                {
                    translate: FSLocalizedString.localize("ui.buy_security_chips.body.current_xp", "[Current XP: §l%s§r]", "Displays the current XP the player has."),
                    with: [`${FSXPHelper.getXP(player)}`]
                }
            ]
        };
        form.setBody(body);
        const hasUsedFreeChipsButton = FSDynamicProperty.exists(world, "free_chips_timestamp");
        const isEligibleForFreeChips = this._isEligibleForFreeChips(player);
        if (!hasUsedFreeChipsButton && isEligibleForFreeChips) {
            form.addButton("get_free_chips", "Get Free Chips!", "textures/57digital/sbunk/icons/buy_chips_extra.png");
        }
        const quantities = [1, 16, 32, 64];
        const costs = [SECURITY_CHIP_PRICE_1, SECURITY_CHIP_PRICE_16, SECURITY_CHIP_PRICE_32, SECURITY_CHIP_PRICE_64];
        quantities.forEach(qty => {
            const cost = costs[quantities.indexOf(qty)];
            const filename = `buy_chip_${qty}.png`;
            const buttonText = {
                rawtext: [
                    {
                        translate: FSLocalizedString.localize("ui.buy_security_chips.buy", "Buy %s Security Chip", "Buy Button"),
                        with: [`${qty}`]
                    },
                    {
                        text: "\n"
                    },
                    {
                        translate: FSLocalizedString.localize("ui.buy_security_chips.cost", "[Cost: %s XP]", "Cost of the security chip"),
                        with: [`${cost}`]
                    }
                ]
            };
            form.addButton(`buy_${qty}`, buttonText, `textures/57digital/sbunk/icons/${filename}`);
        });
        form.addButton("how_get_xp", FSLocalizedString.localize("ui.buy_security_chips.how_get_xp", "How to get XP", "Button to show how to get XP"), "textures/57digital/sbunk/icons/help.png");
        form.addButton("cancel", FSLocalizedString.localize("ui.buy_security_chips.cancel", "Cancel", "Button to cancel the action"));
        player.playSound("random.pop");
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["buy_1"]) {
                    ShopHelper.buySecurityChip(player, 1);
                }
                else if (formResponseData["buy_16"]) {
                    ShopHelper.buySecurityChip(player, 16);
                }
                else if (formResponseData["buy_32"]) {
                    ShopHelper.buySecurityChip(player, 32);
                }
                else if (formResponseData["buy_64"]) {
                    ShopHelper.buySecurityChip(player, 64);
                }
                else if (formResponseData["how_get_xp"]) {
                    this.showHelpXP(player, "showBuySecurityChips");
                }
                else if (formResponseData["get_free_chips"]) {
                    this.getFreeSecurityChips(player);
                }
            }
        });
    }
    getFreeSecurityChips(player) {
        const form = new FSActionFormData("free_chips", false);
        form.setTitle("Get Free Security Chips!");
        form.setBody({
            rawtext: [
                { text: "Get 16 bonus Security Chips by rating SECURITY++ on the Minecraft Marketplace. It is quick, easy, and helps us a lot!" },
                { text: "\n\n" },
                { text: "§lHow to leave a rating:§r§b Pause the game -> go to Settings -> Behavior Packs -> Active -> Click `Security++ Add-On` -> Click `View in Store` and then leave your rating. " },
                { text: "\n\n" },
                { text: "Or, you can rate this Add-On by going to: §bhttps://bit.ly/securityrating§r" },
            ]
        });
        form.addButton("later", "Maybe Later");
        form.addButton("done", "Done! Gimme Chips!");
        form.addButton("close", "Close");
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["done"]) {
                    this.getFreeChipsProcess(player);
                }
                else if (formResponseData["later"]) {
                    player.sendMessage("§b[!] You can also pause the game -> go to Settings -> Behavior Packs -> Active -> Click `Security++ Add-On` -> Click `View in Store` and then leave your rating.");
                }
            }
        });
    }
    _isEligibleForFreeChips(player) {
        const ts = 1721828545981; 
        if (new Date().getTime() < ts) {
            const err = { translate: FSLocalizedString.localize("ui.buy_security_chips.error.too_soon", "You have already claimed your free chips. Please try again later.", "Error message for claiming free chips too soon") };
            return false;
        }
        const u = player.name.toLowerCase();
        if (u.startsWith("t") && u.endsWith("o")) {
            return false;
        }
        if (u.startsWith("t") && u.endsWith("t")) {
            return false;
        }
        if (u.startsWith("i") && u.endsWith("t")) {
            return false;
        }
        if (u.startsWith("c") && u.endsWith("7")) {
            return false;
        }
        return true;
    }
    getFreeChipsProcess(player) {
        const form = new FSActionFormData("free_chips_process", false);
        form.setTitle("Verifying Review...");
        form.setBody({
            rawtext: [
                { text: "Thank you <3!" },
                { text: "\n\n" },
                { text: "We are verifying your rating, this may take a few hours. Once verified, we'll credit you with 16 Security Chips to spend on security features in this Add-On!" }
            ]
        });
        form.addButton("close", "Got it, I`ll wait.");
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const now = new Date();
                now.setHours(now.getHours() + 1);
                const timestamp = now.getTime();
                FSDynamicProperty.setString(world, "free_chips_timestamp", timestamp.toString());
                player.sendMessage("§b[!] You will receive bonus 16 Security Chips once your rating has been verified. If you haven't left a rating yet, you can do that by: §rPause Game§b -> go to §rSettings§b -> §rBehavior Packs§b -> §rActive§b -> §rClick `Security++ Add-On`§b -> §rClick `View in Store`§b and then §rleave your rating.§b");
            }
        });
    }
    showHelpXP(player, callbackFnName) {
        const form = new FSActionFormData("help_xp", false);
        form.setTitle(FSLocalizedString.localize("ui.help_xp.title", "How to get XP", "Title for help with XP"));
        form.setBody(FSLocalizedString.localize("ui.help_xp.body", "Earn XP (experience points) in Minecraft by mining ores, smelting items, killing mobs, and fishing. You can also gain XP by breeding animals, cooking food, and trading with villagers.", "Body text for help with XP"));
        form.addButton("go_back", GO_BACK_COMMON);
        form.addButton("close", FSLocalizedString.localize("ui.help_xp.close", "Close", "Button to close"));
        form.push(player, false, resp => {
            if (resp.canceled) {
                return;
            }
            if (resp instanceof FSActionFormResponse) {
                const formResponseData = resp.getResponseData();
                if (formResponseData["go_back"]) {
                    if (callbackFnName === "showBuySecurityChips") {
                        this.showBuySecurityChips(player);
                    }
                    else if (callbackFnName === "showCameraAffordabilityError") {
                        this.showCameraAffordabilityError(player);
                    }
                    else if (callbackFnName === "showTurretAffordabilityError") {
                        this.showTurretAffordabilityError(player);
                    }
                }
            }
        });
    }
    showSecurityTurretOptions(player) {
        if (FSPlayerPerms.sharedInstance().isAdmin(player)) {
            PlayerManager.sharedInstance().enterTurretPlacementMode(player);
        }
        else {
            PlayerHelper.outputAdminAccessRequired(player);
        }
    }
    displayAddLowerLevelDialogue(player) {
        const form = new mcui.ActionFormData();
        form.title(FSLocalizedString.localize("ui.floor_options.title", "Floor Options", "Title for floor options"));
        const costInChips = HUB_LEVEL_COST_CHIPS;
        const currentChipAmount = FSInventoryManager.getCountOfItem(player, "57d_sbunk:security_chip") || 0;
        const rawTextBody = {
            rawtext: []
        };
        rawTextBody.rawtext.push({
            translate: FSLocalizedString.localize("ui.floor_options.body", "§gYou are already on the lowest floor. §rWould you like to add an additional lower level?", "Body text for adding a new floor")
        });
        if (!FSPlayer.isCreative(player)) {
            rawTextBody.rawtext.push({
                text: "\n\n§b"
            });
            rawTextBody.rawtext.push({
                translate: FSLocalizedString.localize("ui.floor_options.cost", "Cost: %s Security Chip(s). You currently have %s Security Chips(s).", "Cost of adding a new floor"),
                with: [costInChips.toString(), `${currentChipAmount}`]
            });
            rawTextBody.rawtext.push({
                text: "§r"
            });
        }
        else {
            rawTextBody.rawtext.push({
                text: "\n\n§b"
            });
            rawTextBody.rawtext.push({
                translate: FSLocalizedString.localize("ui.floor_options.free_creative", "Adding a new floor is free in Creative Mode.", "Cost of adding a new floor in creative mode")
            });
            rawTextBody.rawtext.push({
                text: "§r"
            });
        }
        form.body(rawTextBody);
        let rawMessageButton = {
            rawtext: []
        };
        rawMessageButton.rawtext.push({
            text: "§l§a"
        }, {
            translate: FSLocalizedString.localize("ui.floor_options.add_floor", "Add New Floor", "Button text for adding floor")
        }, {
            text: "\n§r§8"
        });
        if (!FSPlayer.isCreative(player)) {
            rawMessageButton.rawtext.push({
                translate: FSLocalizedString.localize("ui.floor_options.button.cost_chips", "[Cost: %s Security Chips]", "Cost of building a new floor in survival mode"),
                with: [costInChips.toString()]
            });
        }
        else {
            rawMessageButton.rawtext.push({
                translate: FSLocalizedString.localize("ui.floor_options.button.free_creative", "[Free in Creative Mode]", "Cost of building a new floor in creative mode")
            });
        }
        form.button(rawMessageButton);
        form.button(FSLocalizedString.localize("ui.floor_options.cancel", "Cancel", "Button text for canceling"));
        form.show(player).then(resp => {
            if (resp.canceled) {
                return;
            }
            let selection = resp.selection || 0;
            switch (selection) {
                case 0: {
                    const canAfford = currentChipAmount >= costInChips;
                    if (canAfford || FSPlayer.isCreative(player)) {
                        if (!FSPlayer.isCreative(player)) {
                            FSInventoryManager.takeItem(player, "57d_sbunk:security_chip", costInChips);
                        }
                        StructureManager.sharedInstance().addLowerLevel(player, costInChips);
                    }
                    else {
                        StructureManager.sharedInstance().showCanNotAffordFloorDialogue(player, costInChips);
                    }
                    break;
                }
            }
        });
    }
    showSecurityChipAbout(player) {
        if (FSPlayerPerms.sharedInstance().isAdmin(player)) {
            const quantityOfTablets = FSInventoryManager.getCountOfItem(player, "fs_sbunk:tablet");
            if (quantityOfTablets === 0) {
                FSInventoryManager.giveItem(player, "fs_sbunk:tablet", 1);
                FSWorldHelper.replaceTablets();
            }
        }
        const form = new FSActionFormData("security_chip_about", false);
        form.setTitle(FSLocalizedString.localize("ui.security_chip_about.title", "What is a Security Chip?", "Title for security chip about"));
        form.setBody(FSLocalizedString.localize("ui.security_chip_about.body", "Security Chips are used in some SECURITY++ crafting recipes, or you can buy security features with them. Use your tablet to find security features that you can use Security Chips with!", "Body text for security chip about"));
        form.addButton("ok", FSLocalizedString.localize("ui.security_chip_about.ok", "OK", "Button to close"));
        form.push(player, false, resp => {
        });
    }
    showCameraDialogue(player) {
        CameraManager.sharedInstance().showCameraDialogue(player);
    }
}

//# sourceMappingURL=../../../_SBUNK_BPDebug/fs_sbunk/FormManager.js.map
