import * as mc from "@minecraft/server";
import * as utils from "../../utils/index";
import * as comp from "../components/index";
import { BotBase } from "../bot";
class GlobalTime {
    static get Speed() {
        return this.speed;
    }
    static set Speed(v) {
        v = utils.clamp(v, this.speedMin, this.speedMax);
        this.speed = v;
        utils.writeDynamicProperty(mc.world, 'time_flow_rate', v);
        this.Paused = false;
    }
    static get Paused() {
        return this.paused;
    }
    static set Paused(v) {
        this.paused = v;
        utils.writeDynamicProperty(mc.world, 'time_flow_paused', v);
        this.Enabled = true;
    }
    static get Enabled() {
        return this.enabled;
    }
    static set Enabled(v) {
        this.enabled = v;
        utils.writeDynamicProperty(mc.world, 'time_flow_enabled', v);
        utils.abortEvents('globalClock');
        if (this.Enabled)
            this.startClock();
    }
    static init() {
        var _a, _b, _c;
        this.speed = (_a = utils.readDynamicProperty(mc.world, 'time_flow_rate')) !== null && _a !== void 0 ? _a : this.defaultSpeed;
        this.paused = (_b = utils.readDynamicProperty(mc.world, 'time_flow_paused')) !== null && _b !== void 0 ? _b : false;
        this.enabled = (_c = utils.readDynamicProperty(mc.world, 'time_flow_enabled')) !== null && _c !== void 0 ? _c : false;
        mc.world.afterEvents.gameRuleChange.subscribe(event => {
            if (event.rule === mc.GameRule.DoDayLightCycle && !this.changing) {
                this.Enabled = false;
            }
        });
        utils.waitForEvent(1, () => {
            if (this.Enabled) {
                this.startClock();
            }
        });
    }
    static startClock() {
        this.changing = true;
        utils.overworld.runCommand('gamerule dodaylightcycle false');
        let tickRate = 0;
        switch (true) {
            case this.Speed === 0:
            case this.Paused:
                return;
            case this.Speed === this.defaultSpeed:
                utils.overworld.runCommand('gamerule dodaylightcycle true');
                return;
            case Math.abs(this.Speed) < this.defaultSpeed:
                tickRate = (this.defaultSpeed - Math.abs(this.Speed)) * 100;
            default:
                break;
        }
        this.changing = false;
        utils.waitForLoopEvent(tickRate, () => {
            utils.overworld.runCommand(`time add ${Math.ceil(this.Speed)}`);
            return false;
        }, 'globalClock');
    }
}
GlobalTime.defaultSpeed = 1;
GlobalTime.speedMax = 2048;
GlobalTime.speedMin = -2048;
GlobalTime.changing = false;
export class TimeBot extends BotBase {
    onConstructed() {
        super.onConstructed();
        this.addActorComponent(comp.BlockSnapComponent, { angle: 45 });
        utils.waitForEvent(1, () => {
            this.onGameruleChangeBinding = this.onGameruleChange.bind(this);
            mc.world.afterEvents.gameRuleChange.subscribe(this.onGameruleChangeBinding);
            this.updateTimeProperty();
        });
    }
    onInteract(player) {
        player.playSound(utils.addName("menu.bot.open"));
        this.showTimeMenu(player);
    }
    updateTimeProperty() {
        this.setProperty("time_advancing", mc.world.gameRules.doDayLightCycle || !(GlobalTime.Paused || GlobalTime.Speed === GlobalTime.defaultSpeed));
    }
    showTimeMenu(player) {
        new utils.MenuBuilder({
            type: "page_list",
            title: { translate: "ldz_240927:menu.timebot.title" },
            contents: {
                time: {
                    type: "buttons",
                    title: { translate: "ldz_240927:action.menu.time.title" },
                    backIcon: "textures/ldz/240927/ui/back",
                    icon: "textures/ldz/240927/ui/weather_clock/time",
                    contents: [
                        {
                            text: { translate: "ldz_240927:action.menu.time.stop" },
                            texture: "textures/ldz/240927/ui/weather_clock/time.pause",
                            onClick: () => { GlobalTime.Paused = true, player.playSound(utils.addName("menu.bot.confirm")), this.updateTimeProperty(); },
                            shouldHide: () => GlobalTime.Paused,
                        },
                        {
                            text: { translate: "ldz_240927:action.menu.time.resume" },
                            texture: "textures/ldz/240927/ui/weather_clock/time.resume",
                            onClick: () => { GlobalTime.Paused = false, player.playSound(utils.addName("menu.bot.confirm")), this.updateTimeProperty(); },
                            shouldHide: () => !GlobalTime.Paused,
                        },
                        {
                            text: { translate: "ldz_240927:action.menu.time.start" },
                            texture: "textures/ldz/240927/ui/weather_clock/time.start",
                            onClick: () => {
                                GlobalTime.Speed = GlobalTime.defaultSpeed;
                                player.playSound(utils.addName("menu.bot.confirm")), this.updateTimeProperty();
                            },
                        },
                        {
                            text: { translate: "ldz_240927:action.menu.time.reverse" },
                            texture: "textures/ldz/240927/ui/weather_clock/time.reverse",
                            onClick: () => { GlobalTime.Speed *= -1, player.playSound(utils.addName("menu.bot.confirm")), this.updateTimeProperty(); },
                            shouldHide: () => GlobalTime.Paused,
                        },
                        {
                            text: { translate: "ldz_240927:action.menu.time.fast" },
                            texture: "textures/ldz/240927/ui/weather_clock/time.fast",
                            onClick: () => { GlobalTime.Speed *= 2, player.playSound(utils.addName("menu.bot.confirm")), this.updateTimeProperty(); },
                            shouldHide: () => GlobalTime.Paused,
                        },
                        {
                            text: { translate: "ldz_240927:action.menu.time.slow" },
                            texture: "textures/ldz/240927/ui/weather_clock/time.slow",
                            onClick: () => { GlobalTime.Speed /= 2, player.playSound(utils.addName("menu.bot.confirm")), this.updateTimeProperty(); },
                            shouldHide: () => GlobalTime.Paused,
                        },
                    ],
                },
                day: {
                    type: "buttons",
                    title: { translate: "ldz_240927:action.menu.daytime.title" },
                    backIcon: "textures/ldz/240927/ui/back",
                    icon: "textures/ldz/240927/ui/weather_clock/daytime",
                    contents: [
                        {
                            text: { translate: "ldz_240927:action.menu.daytime.sunrise" },
                            texture: "textures/ldz/240927/ui/weather_clock/daytime.sunrise",
                            onClick: () => { mc.world.setTimeOfDay(0), player.playSound(utils.addName("menu.bot.confirm")), this.updateTimeProperty(); }
                        },
                        {
                            text: { translate: "ldz_240927:action.menu.daytime.noon" },
                            texture: "textures/ldz/240927/ui/weather_clock/daytime.noon",
                            onClick: () => { mc.world.setTimeOfDay(6000), player.playSound(utils.addName("menu.bot.confirm")), this.updateTimeProperty(); },
                        },
                        {
                            text: { translate: "ldz_240927:action.menu.daytime.sunset" },
                            texture: "textures/ldz/240927/ui/weather_clock/daytime.sunset",
                            onClick: () => { mc.world.setTimeOfDay(12000), player.playSound(utils.addName("menu.bot.confirm")), this.updateTimeProperty(); },
                        },
                        {
                            text: { translate: "ldz_240927:action.menu.daytime.midnight" },
                            texture: "textures/ldz/240927/ui/weather_clock/daytime.midnight",
                            onClick: () => { mc.world.setTimeOfDay(18000), player.playSound(utils.addName("menu.bot.confirm")), this.updateTimeProperty(); },
                        },
                    ],
                }
            }
        })
            .showMenuToPlayer(player);
    }
    onGameruleChange(event) {
        utils.mclog(`Game rule change: ${event.rule} to ${event.value}`, this.ActorId);
        if (event.rule === mc.GameRule.DoDayLightCycle) {
            this.updateTimeProperty();
        }
    }
    destructor() {
        super.destructor();
        if (this.onGameruleChangeBinding)
            mc.world.afterEvents.gameRuleChange.unsubscribe(this.onGameruleChangeBinding);
    }
}
GlobalTime.init();
utils.Actor.makeActors({ type: "ldz_240927:time_bot" }, TimeBot);
