--[ ========================================= Room Setup ======================================== ]
--Place rooms in the room array. Don't build connectivity yet.

--Reset these back to empty.
gzTextVar.zRoomList = {}
gzTextVar.iRoomsTotal = 0
gzTextVar.saValidRandomPaths = {}
gzTextVar.iRandomPathsTotal = 0
gzTextCon.zRoomList = {}
gzTextVar.saFleeLocations = {}

--State machine variables.
local bAddToRandomPather = false

--Parse the SLF file for data. The first two are the "small" variants of the manor.
if(gzTextVar.sManorType == "Demo" or gzTextVar.sManorType == "Simple") then
    TL_SetProperty("Parse SLF", gzTextVar.sRootPath .. "Map Builder/MainFloor.slf", 0)
    TL_SetProperty("Parse SLF", gzTextVar.sRootPath .. "Map Builder/Attic.slf", -1)
    TL_SetProperty("Parse SLF", gzTextVar.sRootPath .. "Map Builder/Basement.slf", 1)
    
--This is the normal manor.
elseif(gzTextVar.sManorType == "Normal") then
    TL_SetProperty("Parse SLF", gzTextVar.sRootPath .. "Map Builder/MainFloorB1.slf", 1)
    TL_SetProperty("Parse SLF", gzTextVar.sRootPath .. "Map Builder/MainFloorM0.slf", 0)
    TL_SetProperty("Parse SLF", gzTextVar.sRootPath .. "Map Builder/MainFloorM1.slf", -1)
    TL_SetProperty("Parse SLF", gzTextVar.sRootPath .. "Map Builder/MainFloorM2.slf", -2)
    TL_SetProperty("Parse SLF", gzTextVar.sRootPath .. "Map Builder/MainFloorM3.slf", -3)

--Tutorial.
elseif(gzTextVar.sManorType == "Tutorial") then
    TL_SetProperty("Parse SLF", gzTextVar.sRootPath .. "Map Builder/FloorTutorialM0.slf", 0)
end

--Once all SLF files are parsed, build a temporary 3D world for crossloading. This must be done
-- before "Room Connectivity At" and related queries will work.
TL_SetProperty("Build Temporary World")

--[3D Array]
--Constructed from the SLF data, construct a 3D array. This is a "mirror" of the C++'s data.
gzTextVar.iRoomWst   = TL_GetProperty("Map Lft Extent") - 1
gzTextVar.iRoomEst   = TL_GetProperty("Map Rgt Extent") + 1
gzTextVar.iRoomNth   = TL_GetProperty("Map Top Extent") - 1
gzTextVar.iRoomSth   = TL_GetProperty("Map Bot Extent") + 1
gzTextVar.iLowermost = TL_GetProperty("Map ZLo Extent")
gzTextVar.iUppermost = TL_GetProperty("Map ZHi Extent")
gzTextVar.zRoomLookup = {}
for x = gzTextVar.iRoomWst, gzTextVar.iRoomEst, 1 do
    gzTextVar.zRoomLookup[x] = {}
    
    for y = gzTextVar.iRoomNth, gzTextVar.iRoomSth, 1 do
        gzTextVar.zRoomLookup[x][y] = {}
        
        for z = gzTextVar.iLowermost, gzTextVar.iUppermost, 1 do
            gzTextVar.zRoomLookup[x][y][z] = -1
        
        end
    end
end

--Debug.
--io.write("Array report:\n")
--io.write(" " .. gzTextVar.iLowermost .. "x" .. gzTextVar.iUppermost .. "\n")

--[Adder Function]
--Subroutine.
LM_ExecuteScript(fnResolvePath() .. "fnAddRoom.lua")
LM_ExecuteScript(fnResolvePath() .. "fnAddUnenterableRoom.lua")

--Given an X/Y/Z position, crossloads the room's data from the C++ to the Lua array.
local iUnenterableCount = 0
giRoomToMod = 0 --Flag indicates the last added room.
fnBuildRoom = function(fRoomX, fRoomY, fRoomZ)
    
    --Arg check.
    if(fRoomX == nil) then return end
    if(fRoomY == nil) then return end
    if(fRoomZ == nil) then return end
    
    --Skip empty rooms.
    if(TL_GetProperty("Room Exists At", fRoomX, fRoomY, fRoomZ) == false) then return end
    
    --Name, system properties.
    local sName = TL_GetProperty("Room Name At", fRoomX, fRoomY, fRoomZ)
    local sIdentity = TL_GetProperty("Room Identity At", fRoomX, fRoomY, fRoomZ)
    local bIsUnenterable = TL_GetProperty("Room Is Unenterable", fRoomX, fRoomY, fRoomZ)
    local bIsNoSee = TL_GetProperty("Room Is No See", fRoomX, fRoomY, fRoomZ)
    
    --Connectivity and Visibility
    local sConnectivity = TL_GetProperty("Room Connectivity At", fRoomX, fRoomY, fRoomZ)
    local sOpenness = TL_GetProperty("Room Openess At", fRoomX, fRoomY, fRoomZ)
    
    --Scenario Properties
    local sStrangerGrouping = TL_GetProperty("Stranger Grouping At", fRoomX, fRoomY, fRoomZ)
    
    --Unenterable, uses different algorithm.
    if(bIsUnenterable == true) then
        fnAddUnenterableRoom(sName .. iUnenterableCount, fRoomX, fRoomY, fRoomZ, sOpenness)
        iUnenterableCount = iUnenterableCount + 1
        
        --Visibility override. Unenterable rooms still follow visibility rules, but their default is "no visibility".
        -- Therefore, we switch the values a bit.
        gzTextVar.zRoomList[giRoomToMod].iVisOverrideN = TL_GetProperty("Vis Override At", fRoomX, fRoomY, fRoomZ, gzTextCon.iDirNorth)
        gzTextVar.zRoomList[giRoomToMod].iVisOverrideE = TL_GetProperty("Vis Override At", fRoomX, fRoomY, fRoomZ, gzTextCon.iDirEast)
        gzTextVar.zRoomList[giRoomToMod].iVisOverrideS = TL_GetProperty("Vis Override At", fRoomX, fRoomY, fRoomZ, gzTextCon.iDirSouth)
        gzTextVar.zRoomList[giRoomToMod].iVisOverrideW = TL_GetProperty("Vis Override At", fRoomX, fRoomY, fRoomZ, gzTextCon.iDirWest)
        
        --Vertical visibility. Defaults to 0.
        gzTextVar.zRoomList[giRoomToMod].iVisDown = TL_GetProperty("Vis Down At", fRoomX, fRoomY, fRoomZ)
        
        --Modify the "iNoVisOverride" case to "iNeverVisible".
        if(gzTextVar.zRoomList[giRoomToMod].iVisOverrideN == gzTextCon.iNoVisOverride) then gzTextVar.zRoomList[giRoomToMod].iVisOverrideN = gzTextCon.iNeverVisible end
        if(gzTextVar.zRoomList[giRoomToMod].iVisOverrideE == gzTextCon.iNoVisOverride) then gzTextVar.zRoomList[giRoomToMod].iVisOverrideE = gzTextCon.iNeverVisible end
        if(gzTextVar.zRoomList[giRoomToMod].iVisOverrideS == gzTextCon.iNoVisOverride) then gzTextVar.zRoomList[giRoomToMod].iVisOverrideS = gzTextCon.iNeverVisible end
        if(gzTextVar.zRoomList[giRoomToMod].iVisOverrideW == gzTextCon.iNoVisOverride) then gzTextVar.zRoomList[giRoomToMod].iVisOverrideW = gzTextCon.iNeverVisible end
    
    --Normal room.
    else
        --Pass this to the fnAddRoom function, which does the rest.
        fnAddRoom(sName, fRoomX, fRoomY, fRoomZ, sConnectivity, sOpenness)
        
        --Store the identity.
        gzTextVar.zRoomList[giRoomToMod].sIdentity = sIdentity
        
        --Enemies are unable to see the player in certain rooms.
        gzTextVar.zRoomList[giRoomToMod].bEnemiesCannotSee = bIsNoSee
        
        --Audio.
        local sAudioString = TL_GetProperty("Room Audio At", fRoomX, fRoomY, fRoomZ)
        for i = 1, #gzTextVar.zAudioLookups, 1 do
            if(sAudioString == gzTextVar.zAudioLookups[i][1]) then
                gzTextVar.zRoomList[giRoomToMod].zMusicVolumes = gzTextVar.zAudioLookups[i][2]
            end
        end
        
        --Door registration.
        local i = 0
        while(true) do
            
            local sDoorString = TL_GetProperty("Room Door At", fRoomX, fRoomY, fRoomZ, i)
            if(sDoorString == "Null") then
                break
            else
                if(string.sub(sDoorString, 1, 1) == "N") then
                    gzTextVar.zRoomList[giRoomToMod].sBuildDoorN = string.sub(sDoorString, 3)
                elseif(string.sub(sDoorString, 1, 1) == "E") then
                    gzTextVar.zRoomList[giRoomToMod].sBuildDoorE = string.sub(sDoorString, 3)
                elseif(sDoorString.sub(1, 1) == "S") then
                    gzTextVar.zRoomList[giRoomToMod].sBuildDoorS = sDoorString.sub(3)
                elseif(sDoorString.sub(1, 1) == "W") then
                    gzTextVar.zRoomList[giRoomToMod].sBuildDoorW = sDoorString.sub(3)
                end
            end
            i = i + 1
        end
        
        --Animation registration. Crossloads animations from the Tiled version to the final version.
        i = 0
        while(true) do
            
            local sAnimString = TL_GetProperty("Room Animation At", fRoomX, fRoomY, fRoomZ, i)
            if(sAnimString == "Null") then
                break
            else
                local iSize = #gzTextVar.zRoomList[giRoomToMod].saAnimations + 1
                gzTextVar.zRoomList[giRoomToMod].saAnimations[iSize] = sAnimString
            end
            i = i + 1
        end
        
        --Stranger Grouping.
        gzTextVar.zRoomList[giRoomToMod].sStrangerGroup = sStrangerGrouping
        if(sStrangerGrouping ~= "Null") then
            --io.write("Grouping of " .. gzTextVar.zRoomList[giRoomToMod].sName .. " was " .. gzTextVar.zRoomList[giRoomToMod].sStrangerGroup .. "\n")
        end
        
        --Visibility override. Walls can be ignored and visibility mandated by properties in Tiled.
        gzTextVar.zRoomList[giRoomToMod].iVisOverrideN = TL_GetProperty("Vis Override At", fRoomX, fRoomY, fRoomZ, gzTextCon.iDirNorth)
        gzTextVar.zRoomList[giRoomToMod].iVisOverrideE = TL_GetProperty("Vis Override At", fRoomX, fRoomY, fRoomZ, gzTextCon.iDirEast)
        gzTextVar.zRoomList[giRoomToMod].iVisOverrideS = TL_GetProperty("Vis Override At", fRoomX, fRoomY, fRoomZ, gzTextCon.iDirSouth)
        gzTextVar.zRoomList[giRoomToMod].iVisOverrideW = TL_GetProperty("Vis Override At", fRoomX, fRoomY, fRoomZ, gzTextCon.iDirWest)
        
        --Vertical visibility. Defaults to 0.
        gzTextVar.zRoomList[giRoomToMod].iVisDown = TL_GetProperty("Vis Down At", fRoomX, fRoomY, fRoomZ)
        
        --Set the animation array.
        gzTextVar.zRoomList[gzTextVar.iRoomsTotal].saAnimations = {}
    end
end

--Once the array is built, start requesting data from the C++ data. Crossload it to our 3D array.
local iCount = 0
for x = gzTextVar.iRoomWst+1, gzTextVar.iRoomEst-1, 1 do
    for y = gzTextVar.iRoomNth+1, gzTextVar.iRoomSth-1, 1 do
        for z = gzTextVar.iLowermost, gzTextVar.iUppermost, 1 do
            fnBuildRoom(x, y, z)
            iCount = iCount + 1
            if(iCount == 20) then
                LI_Interrupt()
                iCount = 0
            end
        end
    end
end

