"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ActionSetScope_1 = require("./ActionSetScope");
const Location_1 = require("../minecraft/Location");
const BlockLocation_1 = require("../minecraft/BlockLocation");
const ActionSetCatalog_1 = require("./ActionSetCatalog");
const IAction_1 = require("./IAction");
const Utilities_1 = require("../core/Utilities");
const Log_1 = require("../core/Log");
const ste_events_1 = require("ste-events");
class ActionGroup {
    data;
    _actionSet;
    actions;
    expectedContext = IAction_1.ActionContextType.general;
    _groupAction;
    _onPropertyChanged = new ste_events_1.EventDispatcher();
    get groupActionType() {
        return this.data?.groupActionType;
    }
    set groupActionType(newGat) {
        if (!this.data) {
            this.data = {
                actions: [],
            };
        }
        if (newGat !== this.data.groupActionType) {
            this._groupAction = undefined;
            this.data.groupActionType = newGat;
            this.ensureGroupAction();
        }
    }
    get onPropertyChanged() {
        return this._onPropertyChanged.asEvent();
    }
    get actionSet() {
        return this._actionSet;
    }
    set actionSet(newActionSet) {
        this._actionSet = newActionSet;
    }
    get id() {
        return this.data.id;
    }
    set id(newId) {
        this.data.id = newId;
    }
    get name() {
        return this.data.name;
    }
    set name(newName) {
        this.data.name = newName;
    }
    get typeId() {
        if (this.data.groupActionType) {
            return this.data.groupActionType;
        }
        return "group";
    }
    get canvasX() {
        return this.data.canvasX;
    }
    set canvasX(inboundX) {
        this.data.canvasX = inboundX;
    }
    get canvasY() {
        return this.data.canvasY;
    }
    set canvasY(inboundY) {
        this.data.canvasY = inboundY;
    }
    constructor(data, actionSet, doNotHydrate) {
        this.data = data;
        this._actionSet = actionSet;
        this.actions = [];
        if (!doNotHydrate) {
            this._hydrate();
        }
    }
    getScriptRequirements(options) {
        return {};
    }
    getCommandRequirements(options) {
        return {};
    }
    addScriptLines(lines, options, context, placement) { }
    addCommandLines(lines, indent, options) { }
    getProperty(id) {
        if (!Utilities_1.default.isUsableAsObjectKey(id)) {
            Log_1.default.unsupportedToken(id);
            throw new Error();
        }
        if (!this.data.groupActionData) {
            return undefined;
        }
        if (this._groupAction) {
            return this._groupAction.getProperty(id);
        }
        return this.data.groupActionData[id];
    }
    setProperty(id, value) {
        if (!Utilities_1.default.isUsableAsObjectKey(id)) {
            Log_1.default.unsupportedToken(id);
            throw new Error();
        }
        if (!this.data.groupActionData && this.data.groupActionType) {
            this.data.groupActionData = {
                type: this.data.groupActionType,
            };
        }
        if (this.groupAction) {
            this.groupAction.setProperty(id, value);
        }
    }
    ensureGroupAction() {
        if (!this._groupAction && this.data && this.data.groupActionType) {
            this._hydrateGroupAction();
        }
    }
    get groupAction() {
        if (this._groupAction) {
            return this._groupAction;
        }
        this.ensureGroupAction();
        return this._groupAction;
    }
    getBaseValue() {
        return this.data;
    }
    setBaseValue(value) {
        this.data = value;
    }
    getArgumentAsNumber(name) {
        const val = this.data[name];
        if (typeof val === "number") {
            return val;
        }
        else if (typeof val === "string") {
            return parseFloat(val);
        }
        throw new Error();
    }
    validateArgumentIsType(name, type) {
        const val = this.data[name];
        const typestr = typeof val;
        switch (type) {
            case "BlockLocation":
            case "Location":
                if (!(val instanceof Array) || val.length !== 3) {
                    throw new Error("Expected an array of 3 numbers for parameter '" + name + "'");
                }
                break;
            case "boolean":
            case "number":
            case "string":
                if (typestr !== type) {
                    throw new Error("Unexpected type mismatch: " + name + " is " + typestr + " (expected " + type + ")");
                }
                break;
        }
        return true;
    }
    _hydrate() {
        this.actions = [];
        if (this.data.actions && Array.isArray(this.data.actions)) {
            for (const dataAction of this.data.actions) {
                if (dataAction.actions) {
                    const newActionGroup = ActionSetCatalog_1.ActionSetCatalog.createActionGroup(this, dataAction);
                    this.actions.push(newActionGroup);
                }
                else if (dataAction.type) {
                    const newAction = ActionSetCatalog_1.ActionSetCatalog.createAction(this, dataAction.type, dataAction);
                    this.actions.push(newAction);
                }
            }
        }
        this._hydrateGroupAction();
    }
    _hydrateGroupAction() {
        if (this.data && this.data.groupActionType) {
            if (!this.data.groupActionData) {
                this.data.groupActionData = { type: this.data.groupActionType };
            }
            const act = ActionSetCatalog_1.ActionSetCatalog.createAction(this, this.data.groupActionType, this.data.groupActionData);
            this._groupAction = act;
        }
    }
    startRun(world, test) {
        const scope = new ActionSetScope_1.default();
        scope.test = test;
        scope.world = world;
        this.run(scope);
    }
    run(parentScope) {
        for (let i = 0; i < this.actions.length; i++) {
            const action = this.actions[i];
            action.run(parentScope);
        }
    }
    setActions(newActionList) {
        this.actions = newActionList;
        const dataArr = [];
        for (const actionOrGroup of newActionList) {
            actionOrGroup.actionSet = this.actionSet;
            dataArr.push(actionOrGroup.data);
        }
        this.data.actions = dataArr;
    }
    absolutizeLocation(location) {
        if (!this._actionSet || !this._actionSet.locationRoot) {
            return location;
        }
        return new Location_1.default(this._actionSet.locationRoot.x + location.x, this._actionSet.locationRoot.y + location.y, this._actionSet.locationRoot.z + location.z);
    }
    absolutizeBlockLocation(location) {
        if (!this._actionSet || !this._actionSet.locationRoot) {
            return location;
        }
        return new BlockLocation_1.default(Math.round(this._actionSet.locationRoot.x + location.x), Math.round(this._actionSet.locationRoot.y + location.y), Math.round(this._actionSet.locationRoot.z + location.z));
    }
    relativizeLocation(location) {
        if (!this._actionSet || !this._actionSet.locationRoot) {
            return location;
        }
        return new Location_1.default(location.x - this._actionSet.locationRoot.x, location.y - this._actionSet.locationRoot.y, location.z - this._actionSet.locationRoot.z);
    }
    relativizeBlockLocation(location) {
        if (!this._actionSet || !this._actionSet.locationRoot) {
            return location;
        }
        return new BlockLocation_1.default(Math.round(location.x - this._actionSet.locationRoot.x), Math.round(location.y - this._actionSet.locationRoot.y), Math.round(location.z - this._actionSet.locationRoot.z));
    }
    addAction(action) {
        this.actions.push(action);
        if (!this.data.actions) {
            this.data.actions = [];
        }
        this.data.actions.push(action.data);
    }
    static mergeScriptOptions(source, add) {
        source.isFunction = source.isFunction || add.isFunction;
    }
    static mergeScriptRequirements(source, add) {
        source.needsLocalOverworld = source.needsLocalOverworld || add.needsLocalOverworld;
    }
    static mergeCommandRequirements(source, add) { }
    static addLine(lines, indent, line) {
        lines.push(this.getIndentSpaces(indent) + line);
    }
    static getIndentSpaces(indent) {
        let result = "";
        for (let i = 0; i < indent; i++) {
            result += " ";
        }
        return result;
    }
    ensureLoaded() {
        if (this.data.actions) {
            for (const actionData of this.data.actions) {
                if (actionData.type) {
                    const action = ActionSetCatalog_1.ActionSetCatalog.createAction(this, actionData.type, actionData);
                    this.actions.push(action);
                }
            }
        }
    }
    removeAction(removeAction) {
        const newActionArr = [];
        for (const action of this.actions) {
            if (action !== removeAction) {
                newActionArr.push(action);
            }
        }
        this.actions = newActionArr;
    }
}
exports.default = ActionGroup;

//# sourceMappingURL=../maps/actions/ActionGroup.js.map
