"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EntityTypeStateBuilder = void 0;
const Utilities_1 = require("../core/Utilities");
const EntityTypeComponentSetUtilities_1 = require("./EntityTypeComponentSetUtilities");
const ManagedEventActionOrActionSet_1 = require("./ManagedEventActionOrActionSet");
class EntityTypeStateBuilderContext {
    entityType;
    baseTriggers = [];
    eventsById = {};
    states = {};
    constructor(entityTypeParent) {
        this.entityType = entityTypeParent;
    }
}
class EntityTypeStateBuilder {
    static async getStates(entityType) {
        const context = new EntityTypeStateBuilderContext(entityType);
        context.baseTriggers = await EntityTypeComponentSetUtilities_1.default.getTriggers(entityType, true);
        const events = context.entityType.getEvents();
        for (const ev of events) {
            if (ev.event && ev.id) {
                const mea = new ManagedEventActionOrActionSet_1.default(ev.event);
                context.eventsById[ev.id] = mea;
            }
        }
        await EntityTypeStateBuilder.considerState(context, entityType, []);
        for (const stateId in context.states) {
            const state = context.states[stateId];
            if (!state.isLikely) {
                for (const conn of state.outboundConnections) {
                    conn.isLikely = false;
                }
            }
        }
        for (const stateId in context.states) {
            const state = context.states[stateId];
            if (state.isLikely) {
                let foundALikely = false;
                for (const conn of state.outboundConnections) {
                    if (conn.isLikely) {
                        foundALikely = true;
                    }
                }
                for (const conn of state.inboundConnections) {
                    if (conn.isLikely) {
                        foundALikely = true;
                    }
                }
                if (!foundALikely) {
                    state.isLikely = false;
                }
            }
        }
        return context.states;
    }
    static removeGroupInArray(arr, groupId) {
        const newArr = [];
        for (const str of arr) {
            if (str.substring(1) !== groupId) {
                newArr.push(str);
            }
        }
        return newArr;
    }
    static async considerState(context, componentSet, cgAddsRemoveList, inboundConnection) {
        let stateId = "";
        if (componentSet !== context.entityType) {
            stateId = componentSet.id;
        }
        stateId += "|" + cgAddsRemoveList.join("|");
        const targetState = context.states[stateId];
        if (targetState) {
            if (inboundConnection && inboundConnection.source !== targetState) {
                inboundConnection.target = targetState;
                if (inboundConnection.isLikely) {
                    targetState.isLikely = true;
                }
                targetState.inboundConnections.push(inboundConnection);
            }
            return;
        }
        const effectiveComponents = context.entityType.getEffectiveComponents(cgAddsRemoveList);
        const triggers = await EntityTypeComponentSetUtilities_1.default.getTriggers(effectiveComponents, cgAddsRemoveList.length === 0);
        const triggersByTarget = {};
        for (const trigger of triggers) {
            if (trigger.referenceId) {
                triggersByTarget[trigger.referenceId] = trigger;
            }
        }
        let stateTitle = "";
        const etTitle = Utilities_1.default.humanifyMinecraftNameRemoveNamespaces(context.entityType.id);
        const managedComponentGroups = [];
        for (const cgId of cgAddsRemoveList) {
            const cg = context.entityType.getComponentGroup(cgId.substring(1));
            let idTitle = "";
            if (cg) {
                idTitle = Utilities_1.default.humanifyMinecraftNameRemoveNamespaces(cg.id.substring(1));
            }
            else {
                idTitle = Utilities_1.default.humanifyMinecraftNameRemoveNamespaces(cgId.substring(1)) + " (missing!)";
            }
            if (cgId[0] === "+") {
                stateTitle += " +" + idTitle;
            }
            else if (cgId[0] === "-") {
                stateTitle += " -" + idTitle;
            }
        }
        stateTitle = etTitle + ": " + stateTitle;
        stateTitle = stateTitle.trim();
        const state = {
            id: stateId,
            title: stateTitle,
            isLikely: false,
            componentGroupAddRemoves: cgAddsRemoveList,
            componentGroups: managedComponentGroups,
            inboundConnections: [],
            outboundConnections: [],
        };
        context.states[stateId] = state;
        if (inboundConnection) {
            inboundConnection.target = state;
            if (inboundConnection.isLikely) {
                state.isLikely = true;
            }
            state.inboundConnections.push(inboundConnection);
        }
        for (const evId in context.eventsById) {
            const ev = context.eventsById[evId];
            if (ev) {
                let isLikely = false;
                if (triggersByTarget[evId]) {
                    isLikely = true;
                }
                const actions = ev.getPotentialActions();
                for (const action of actions) {
                    // is this an event that changes group state? if not, ignore
                    if ((action.action.addGroups && action.action.addGroups.length > 0) ||
                        (action.action.removeGroups && action.action.removeGroups.length > 0)) {
                        let newComponentGroupAddRemoves = cgAddsRemoveList.slice();
                        if (ev.removeGroups) {
                            for (const cg of ev.removeGroups) {
                                newComponentGroupAddRemoves = EntityTypeStateBuilder.removeGroupInArray(newComponentGroupAddRemoves, cg);
                                newComponentGroupAddRemoves.push("-" + cg);
                            }
                        }
                        if (ev.addGroups) {
                            for (const cg of ev.addGroups) {
                                newComponentGroupAddRemoves = EntityTypeStateBuilder.removeGroupInArray(newComponentGroupAddRemoves, cg);
                                newComponentGroupAddRemoves.push("+" + cg);
                            }
                        }
                        if (newComponentGroupAddRemoves.join("|") !== cgAddsRemoveList.join("|")) {
                            const connection = {
                                source: state,
                                triggerEventId: evId,
                                isLikely: isLikely,
                                title: Utilities_1.default.humanifyMinecraftName(evId),
                                description: action.conditionDescription,
                            };
                            state.outboundConnections.push(connection);
                            await this.considerState(context, context.entityType, newComponentGroupAddRemoves, connection);
                        }
                    }
                }
            }
        }
    }
}
exports.EntityTypeStateBuilder = EntityTypeStateBuilder;

//# sourceMappingURL=../maps/minecraft/EntityTypeStateBuilder.js.map
