#include "cm_world_sector_private.h"

void SV_UnlinkEntityFromWorldSector(svEntity_t *svEntity)
{
    worldSector_t *sector;
    svEntity_t *scan;
    worldSector_t *parent;
    int32_t contentsMask;

    sector = CM_LoadWorldSector(svEntity->worldSector);
    if (sector == NULL) {
        return;
    }

    svEntity->worldSector = 0;

    if (CM_LoadEntityLink(sector->entityLinkHead) == svEntity) {
        sector->entityLinkHead = svEntity->nextInWorldSector;
    } else {
        for (scan = CM_LoadEntityLink(sector->entityLinkHead);
             CM_LoadEntityLink(scan->nextInWorldSector) != svEntity;
             scan = CM_LoadEntityLink(scan->nextInWorldSector)) {
        }
        scan->nextInWorldSector = svEntity->nextInWorldSector;
    }

    while (sector->entityLinkHead == NULL &&
           sector->staticModelLinkHead == NULL &&
           CM_LoadWorldSector(sector->children[0]) == &cm_nullWorldSector &&
           CM_LoadWorldSector(sector->children[1]) == &cm_nullWorldSector) {
        sector->entityContentsMask = 0;

        parent = CM_LoadWorldSector(sector->parent);
        if (parent == NULL) {
            break;
        }

        sector->parent = CM_StoreWorldSector(cm_freeWorldSectors);
        cm_freeWorldSectors = sector;

        if (CM_LoadWorldSector(parent->children[0]) == sector) {
            parent->children[0] = CM_StoreWorldSector(&cm_nullWorldSector);
        } else {
            parent->children[1] = CM_StoreWorldSector(&cm_nullWorldSector);
        }

        sector = parent;
    }

    for (; sector != NULL; sector = CM_LoadWorldSector(sector->parent)) {
        contentsMask = CM_LoadWorldSector(sector->children[1])
                           ->entityContentsMask |
                       CM_LoadWorldSector(sector->children[0])
                           ->entityContentsMask;

        for (scan = CM_LoadEntityLink(sector->entityLinkHead); scan != NULL;
             scan = CM_LoadEntityLink(scan->nextInWorldSector)) {
            contentsMask |= SV_GEntityForSvEntity(scan)->contents;
        }

        sector->entityContentsMask = contentsMask;
    }
}
