"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GridEntityCollisionDetection = void 0;
const isaac_typescript_definitions_1 = require("isaac-typescript-definitions");
const gridEntities_1 = require("../../../functions/gridEntities");
const DefaultMap_1 = require("../../DefaultMap");
const Feature_1 = require("../../private/Feature");
const v = {
    room: {
        /** Indexed by grid entity pointer hash. */
        collidingEntitiesMap: new DefaultMap_1.DefaultMap(() => new Set()),
    },
};
class GridEntityCollisionDetection extends Feature_1.Feature {
    v = v;
    postGridEntityCollision;
    postGridEntityCustomCollision;
    customGridEntities;
    constructor(postGridEntityCollision, postGridEntityCustomCollision, customGridEntities) {
        super();
        this.callbacksUsed = [
            // 1
            [isaac_typescript_definitions_1.ModCallback.POST_UPDATE, this.postUpdate],
        ];
        this.postGridEntityCollision = postGridEntityCollision;
        this.postGridEntityCustomCollision = postGridEntityCustomCollision;
        this.customGridEntities = customGridEntities;
    }
    // ModCallback.POST_UPDATE (1)
    postUpdate = () => {
        const gridEntities = (0, gridEntities_1.getGridEntities)();
        const gridEntitiesWithCollision = gridEntities.filter((gridEntity) => gridEntity.CollisionClass !== isaac_typescript_definitions_1.GridCollisionClass.NONE);
        for (const gridEntity of gridEntitiesWithCollision) {
            const gridEntityPtrHash = GetPtrHash(gridEntity);
            const oldCollidingEntities = v.room.collidingEntitiesMap.getAndSetDefault(gridEntityPtrHash);
            // Check for new colliding entities.
            const collidingEntities = (0, gridEntities_1.getCollidingEntitiesWithGridEntity)(gridEntity);
            for (const entity of collidingEntities) {
                const entityPtrHash = GetPtrHash(entity);
                if (!oldCollidingEntities.has(entityPtrHash)) {
                    oldCollidingEntities.add(entityPtrHash);
                    const gridEntityTypeCustom = this.customGridEntities.getCustomGridEntityType(gridEntity);
                    if (gridEntityTypeCustom === undefined) {
                        this.postGridEntityCollision.fire(gridEntity, entity);
                    }
                    else {
                        this.postGridEntityCustomCollision.fire(gridEntity, gridEntityTypeCustom, entity);
                    }
                }
            }
            // Remove old colliding entities.
            const collidingEntitiesPtrHashes = collidingEntities.map((entity) => GetPtrHash(entity));
            const collidingEntitiesPtrHashSet = new Set(collidingEntitiesPtrHashes);
            for (const oldCollidingEntityPtrHash of oldCollidingEntities) {
                if (!collidingEntitiesPtrHashSet.has(oldCollidingEntityPtrHash)) {
                    oldCollidingEntities.delete(oldCollidingEntityPtrHash);
                }
            }
        }
    };
}
exports.GridEntityCollisionDetection = GridEntityCollisionDetection;
