"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isaacAPIClassEquals = exports.isTear = exports.isTNT = exports.isSpikes = exports.isRock = exports.isProjectile = exports.isPressurePlate = exports.isPoop = exports.isPlayer = exports.isPit = exports.isPickup = exports.isNPC = exports.isLaser = exports.isKnife = exports.isIsaacAPIClassOfType = exports.isIsaacAPIClass = exports.isGridEntity = exports.isFamiliar = exports.isEntity = exports.isEffect = exports.isDoor = exports.isBomb = exports.getIsaacAPIClassName = void 0;
const string_1 = require("./string");
const types_1 = require("./types");
/**
 * Helper function to get the name of a class from the Isaac API. This is contained within the
 * "__type" metatable key.
 *
 * For example, a `Vector` class is has a name of "Vector".
 *
 * Returns undefined if the object is not of type `userdata` or if the "__type" metatable key does
 * not exist.
 *
 * In some cases, Isaac classes can be a read-only. If this is the case, the "__type" field will be
 * prepended with "const ". This function will always strip this prefix, if it exists. For example,
 * the class name returned for "const Vector" will be "Vector".
 */
function getIsaacAPIClassName(object) {
    if (!(0, types_1.isUserdata)(object)) {
        return undefined;
    }
    const metatable = getmetatable(object);
    if (metatable === undefined) {
        return undefined;
    }
    const classType = metatable.get("__type");
    if (!(0, types_1.isString)(classType)) {
        return undefined;
    }
    return (0, string_1.trimPrefix)(classType, "const ");
}
exports.getIsaacAPIClassName = getIsaacAPIClassName;
/** Helper function to detect if a variable is of type `EntityBomb`. */
function isBomb(variable) {
    return getIsaacAPIClassName(variable) === "EntityBomb";
}
exports.isBomb = isBomb;
/** Helper function to detect if a variable is of type `GridEntityDoor`. */
function isDoor(variable) {
    return getIsaacAPIClassName(variable) === "GridEntityDoor";
}
exports.isDoor = isDoor;
/** Helper function to detect if a variable is of type `EntityEffect`. */
function isEffect(variable) {
    return getIsaacAPIClassName(variable) === "EntityEffect";
}
exports.isEffect = isEffect;
/**
 * Helper function to detect if a variable is of type `Entity`. This will return false for child
 * classes such as `EntityPlayer` or `EntityTear`.
 */
function isEntity(variable) {
    return getIsaacAPIClassName(variable) === "Entity";
}
exports.isEntity = isEntity;
/** Helper function to detect if a variable is of type `EntityFamiliar`. */
function isFamiliar(variable) {
    return getIsaacAPIClassName(variable) === "EntityEffect";
}
exports.isFamiliar = isFamiliar;
/** Helper function to detect if a variable is of type `GridEntity`. */
function isGridEntity(variable) {
    return getIsaacAPIClassName(variable) === "GridEntity";
}
exports.isGridEntity = isGridEntity;
/**
 * Helper function to check if something is an instantiated class from the Isaac API. (All classes
 * from the Isaac API have a type of "userdata" in Lua with a metatable key of "__type" equal to the
 * name of the class.)
 */
function isIsaacAPIClass(object) {
    const isaacAPIClassType = getIsaacAPIClassName(object);
    return isaacAPIClassType !== undefined;
}
exports.isIsaacAPIClass = isIsaacAPIClass;
function isIsaacAPIClassOfType(object, classType) {
    const isaacAPIClassType = getIsaacAPIClassName(object);
    return (isaacAPIClassType === classType ||
        isaacAPIClassType === `const ${classType}`);
}
exports.isIsaacAPIClassOfType = isIsaacAPIClassOfType;
/** Helper function to detect if a variable is of type `EntityKnife`. */
function isKnife(variable) {
    return getIsaacAPIClassName(variable) === "EntityKnife";
}
exports.isKnife = isKnife;
/** Helper function to detect if a variable is of type `EntityLaser`. */
function isLaser(variable) {
    return getIsaacAPIClassName(variable) === "EntityLaser";
}
exports.isLaser = isLaser;
/** Helper function to detect if a variable is of type `EntityNPC`. */
function isNPC(variable) {
    return getIsaacAPIClassName(variable) === "EntityNPC";
}
exports.isNPC = isNPC;
/** Helper function to detect if a variable is of type `EntityPickup`. */
function isPickup(variable) {
    return getIsaacAPIClassName(variable) === "EntityPickup";
}
exports.isPickup = isPickup;
/** Helper function to detect if a variable is of type `GridEntityPit`. */
function isPit(variable) {
    return getIsaacAPIClassName(variable) === "GridEntityPit";
}
exports.isPit = isPit;
/** Helper function to detect if a variable is of type `EntityPlayer`. */
function isPlayer(variable) {
    return getIsaacAPIClassName(variable) === "EntityPlayer";
}
exports.isPlayer = isPlayer;
/** Helper function to detect if a variable is of type `GridEntityPoop`. */
function isPoop(variable) {
    return getIsaacAPIClassName(variable) === "GridEntityPoop";
}
exports.isPoop = isPoop;
/** Helper function to detect if a variable is of type `GridEntityPressurePlate`. */
function isPressurePlate(variable) {
    return getIsaacAPIClassName(variable) === "GridEntityPressurePlate";
}
exports.isPressurePlate = isPressurePlate;
/** Helper function to detect if a variable is of type `EntityProjectile`. */
function isProjectile(variable) {
    return getIsaacAPIClassName(variable) === "EntityProjectile";
}
exports.isProjectile = isProjectile;
/** Helper function to detect if a variable is of type `GridEntityRock`. */
function isRock(variable) {
    return getIsaacAPIClassName(variable) === "GridEntityRock";
}
exports.isRock = isRock;
/** Helper function to detect if a variable is of type `GridEntitySpikes`. */
function isSpikes(variable) {
    return getIsaacAPIClassName(variable) === "GridEntitySpikes";
}
exports.isSpikes = isSpikes;
/** Helper function to detect if a variable is of type `GridEntityTNT`. */
function isTNT(variable) {
    return getIsaacAPIClassName(variable) === "GridEntityTNT";
}
exports.isTNT = isTNT;
/** Helper function to detect if a variable is of type `EntityTear`. */
function isTear(variable) {
    return getIsaacAPIClassName(variable) === "EntityTear";
}
exports.isTear = isTear;
/**
 * Helper function to check if an instantiated Isaac API class is equal to another one of the same
 * type. You must provide the list of keys to check for.
 */
function isaacAPIClassEquals(object1, object2, keys) {
    const table1 = object1;
    const table2 = object2;
    return keys.every((key) => table1.get(key) === table2.get(key));
}
exports.isaacAPIClassEquals = isaacAPIClassEquals;
