--[ ===================================== Modify Door State ===================================== ]
--Subroutine that changes a door from closed to open or vice-versa. Note that two doors are changed:
-- the one in the location, and the one it adjoins to in a different room.

--Argument Listing:
-- 0: sLocationName - The name of the room the door is in.
-- 1: sTargetCase - "C" or "O", for closed or opened.
-- 2: sTargetDir - "N", "E", "S", "W", for the direction of the door.
-- 3: iTempVisFlag - If equal to ciDoNotModifyVisibility, visibility calculations will not take place.
-- 4: iIsPlayerOpening - If 1, the player is opening this and the door loses special lock properties.

--Arg check.
local iRequiredArgs = 5
local iArgs = LM_GetNumOfArgs()
if(iArgs < iRequiredArgs) then
	Debug_ForcePrint(fnResolvePath() .. ": Error, incorrect argument count. Got " .. iArgs .. " expected " .. iRequiredArgs .. ".\n")
	return
end

--Arg resolve.
local sLocationName     = LM_GetScriptArgument(0)
local sTargetCase       = LM_GetScriptArgument(1)
local sTargetDir        = LM_GetScriptArgument(2)
local iTempVisFlag      = tonumber(LM_GetScriptArgument(3))
local iIsPlayerOpening  = tonumber(LM_GetScriptArgument(4))
local bIgnoreVisibility = false

--[Setup]
--First, get the position of the room on the 3D map.
local fX, fY, fZ = fnGetRoomPosition(sLocationName)
local fModX = fX
local fModY = fY
local fModZ = fZ

--Determine if visibility needs to be modified.
if(iTempVisFlag == ciModifyVisibility) then
    bIgnoreVisibility = false
else
    bIgnoreVisibility = true
end

--Get the index of the room.
local iRoomIndex = fnGetRoomIndex(sLocationName)
local iDestIndex = -1

--Flags for later
local bIsSouthDoor = false
local bIsOpenState = false
local sDoorState = string.sub(sTargetCase, 1, 1)
local sLockState = string.sub(sTargetCase, 2)

--Determine the destination room.
if(sTargetDir == "N") then
    bIsSouthDoor = true
    iDestIndex = gzTextVar.zRoomList[iRoomIndex].iMoveN
elseif(sTargetDir == "E") then
    bIsSouthDoor = false
    iDestIndex = gzTextVar.zRoomList[iRoomIndex].iMoveE
elseif(sTargetDir == "S") then
    bIsSouthDoor = true
    iDestIndex = gzTextVar.zRoomList[iRoomIndex].iMoveS
elseif(sTargetDir == "W") then
    bIsSouthDoor = false
    iDestIndex = gzTextVar.zRoomList[iRoomIndex].iMoveW
end

--Open-close state. Only the first letter is checked.
if(sDoorState == "O") then bIsOpenState = true end

--[Error Check]
--No valid destination found.
if(iDestIndex == -1) then return end

--[Modify]
--Unmark the previous location, in case the player is within LOS.
if(bIgnoreVisibility == false) then
    fnUnmarkMinimapForPosition(gzTextVar.gzPlayer.sLocation)
end

--Determine which room's state to modify in the C++ code. Only the south and east doors are actually rendered in the C++
-- code, since that way the doors don't render over each other. This means that N/W cases actually modify the destination
-- room and not the source room.
if(sTargetDir == "N") then
    fModY = fModY - 1
elseif(sTargetDir == "W") then
    fModX = fModX - 1
end
            
--Change flags, set door to open.
TL_SetProperty("Set Room Door State", fModX, fModY, fModZ, bIsSouthDoor, bIsOpenState)

--If the player opens a door, it changes to "Normal".
if(iIsPlayerOpening == 1 and bIsOpenState) then
    sLockState = " Normal"
end
            
--Change internal variables. First, North.
if(sTargetDir == "N") then
    gzTextVar.zRoomList[iRoomIndex].sDoorN = sDoorState .. sLockState
    gzTextVar.zRoomList[iDestIndex].sDoorS = sDoorState .. sLockState
elseif(sTargetDir == "E") then
    gzTextVar.zRoomList[iRoomIndex].sDoorE = sDoorState .. sLockState
    gzTextVar.zRoomList[iDestIndex].sDoorW = sDoorState .. sLockState
elseif(sTargetDir == "S") then
    gzTextVar.zRoomList[iRoomIndex].sDoorS = sDoorState .. sLockState
    gzTextVar.zRoomList[iDestIndex].sDoorN = sDoorState .. sLockState
elseif(sTargetDir == "W") then
    gzTextVar.zRoomList[iRoomIndex].sDoorW = sDoorState .. sLockState
    gzTextVar.zRoomList[iDestIndex].sDoorE = sDoorState .. sLockState
end
        
--Mark if the player is in LOS.
if(bIgnoreVisibility == false) then
    fnMarkMinimapForPosition(gzTextVar.gzPlayer.sLocation)
    TL_SetProperty("Reresolve Fades")
end
