#include "cas_inc_bttltrap"

const string CAS_PC_TRAP_UID = "CAS_TRAP_UID";
const string CAS_PC_ENTRY    = "CAS_TRAP_ENTRY_LOC";

// Returns TRUE if the current area blocks jump-style tools
int CAS_AreaBlocksJumpTools(object oArea, object oUser)
{
    int nNoJumpTool = GetLocalInt(oArea, "XS_NO_JUMP_TOOL");
    if (nNoJumpTool == 1)
    {
        SendMessageToPC(oUser, "The jump tool cannot be used in this area.");
        return TRUE;
    }
    return FALSE;
}

// Find a PC inside the jar interior area with matching UID
object CAS_FindOccupant(string sUID, int nJarType)
{
    object oArea = GetObjectByTag(CAS_GetJarAreaTag(nJarType));
    if (oArea == OBJECT_INVALID) return OBJECT_INVALID;

    object oObj = GetFirstObjectInArea(oArea);

    // loop vars outside
    object oNext = OBJECT_INVALID;
    string sOccUID = "";

    while (oObj != OBJECT_INVALID)
    {
        if (GetIsPC(oObj))
        {
            sOccUID = GetLocalString(oObj, CAS_PC_TRAP_UID);
            if (sOccUID == sUID)
            {
                return oObj;
            }
        }

        oNext = GetNextObjectInArea(oArea);
        oObj = oNext;
    }

    return OBJECT_INVALID;
}

void main()
{
    object oPC = GetPCSpeaker();
    if (!GetIsPC(oPC) || GetIsDM(oPC)) return;

    // The bottle used script should have cached these on the PC:
    // CAS_BT_UID, CAS_BT_JAR_TYPE, and optionally CAS_BT_PLC / CAS_BT_ITEM
    string sUID = GetLocalString(oPC, "CAS_BT_UID");
    int nJarType = GetLocalInt(oPC, "CAS_BT_JAR_TYPE");

    // Fallback: if UID not cached for some reason, try to pull from cached bottle objects
    if (sUID == "")
    {
        object oPlc = GetLocalObject(oPC, "CAS_BT_PLC");
        object oItem = GetLocalObject(oPC, "CAS_BT_ITEM");

        if (GetIsObjectValid(oPlc))
        {
            sUID = GetLocalString(oPlc, CAS_UID);
            if (nJarType == 0) nJarType = GetLocalInt(oPlc, CAS_JAR_TYPE);
        }
        else if (GetIsObjectValid(oItem))
        {
            // If item-form use is allowed, ensure UID is correct for this owner
            sUID = CAS_EnsureUIDForUser(oItem, oPC);
            if (nJarType == 0) nJarType = GetLocalInt(oItem, CAS_JAR_TYPE);
        }
    }

    if (sUID == "")
    {
        SendMessageToPC(oPC, "The bottle can't find its anchor.");
        return;
    }

    // Normalize jar type default
    if (nJarType != CAS_JAR_HONEY && nJarType != CAS_JAR_PEANUT)
    {
        nJarType = CAS_JAR_HONEY;
    }

    // Block if already trapped (optional safety)
    if (GetLocalString(oPC, CAS_PC_TRAP_UID) != "")
    {
        SendMessageToPC(oPC, "You?re already bound to a bottle-pocket space.");
        return;
    }

    // Area restrictions where they're using the bottle
    object oArea = GetArea(oPC);
    if (CAS_AreaBlocksJumpTools(oArea, oPC)) return;

    // ERF/prefix restrictions
    string sPrefix = GetStringLeft(GetResRef(oArea), 3);
    if (!CheckValidErf(sPrefix))
    {
        SendMessageToPC(oPC, "The bottle refuses to open a pocket-space here.");
        return;
    }

    // Prevent double occupancy for same UID
    if (GetIsObjectValid(CAS_FindOccupant(sUID, nJarType)))
    {
        SendMessageToPC(oPC, "Someone is already trapped in that bottle.");
        return;
    }

    // Destination waypoint by jar type
    object oWP = GetObjectByTag(CAS_GetJarWPTag(nJarType));
    if (oWP == OBJECT_INVALID)
    {
        SendMessageToPC(oPC, "Pocket-space failed to form (missing jar waypoint).");
        return;
    }

    // Save data for release / exit
    SetLocalString(oPC, CAS_PC_TRAP_UID, sUID);
    SetLocalLocation(oPC, CAS_PC_ENTRY, GetLocation(oPC));

    // Emote + jump
    AssignCommand(oPC, ActionSpeakString("*is dragged toward the bottle by a sweet, sticky vacuum?then vanishes inside!*"));
    AssignCommand(oPC, ClearAllActions());
    AssignCommand(oPC, ActionJumpToLocation(GetLocation(oWP)));
}
