--[ ========================================= Load Game ========================================= ]
--Script that loads the game in-stride. Unlike saving, loading takes a little longer and requires
-- extra setup. We need to create/remove indicators and adjust the C++ entities to match the Lua
-- entities. Fortunately, the majority of the under-the-hood variables are in Lua.

--Argument Listing:
-- 0: sSaveName - Name of the savefile. Do not include the extension, plase.

--Arg check.
local iRequiredArgs = 1
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 sSaveName = LM_GetScriptArgument(0)

--Don't do anything if the string is empty.
if(sString == "") then return end

--Don't load if the save does not exist. Print the five most recent savefiles made.
if(TL_Exists("Saves/" .. sSaveName .. ".tls") == false) then
    TL_SetProperty("Append", "The savefile 'Saves/" .. sSaveName .. ".tls' does not exist." .. gsDE)
    
    --Populate saves data.
    local saSavePaths = {}
    local iRecentSavesTotal = TL_GetSaveFileList("Saves/")
    
    --No saves found.
    if(iRecentSavesTotal == 0) then
        TL_SetProperty("Append", "No savefiles detected in the Saves/ directory." .. gsDE)
    
    --One savefile.
    elseif(iRecentSavesTotal == 1) then
        TL_SetProperty("Append", "Most recent savefile: " .. TL_GetProperty("Save Path At", 0) .. "." .. gsDE)
    
    --Two savefiles.
    elseif(iRecentSavesTotal == 2) then
        TL_SetProperty("Append", "Most recent savefiles: " .. TL_GetProperty("Save Path At", 0) .. " and " .. TL_GetProperty("Save Path At", 1) .. "." .. gsDE)
    
    --Three or more.
    else
    
        --String.
        local sString = "Most recent savefiles: "
    
        for i = 1, iRecentSavesTotal-1, 1 do
            
            --Get the save.
            local sPath = TL_GetProperty("Save Path At", i-1)
            
            --Append.
            sString = sString .. sPath .. ", "
        end
    
        --Last savefile.
        sString = sString .. "and " .. TL_GetProperty("Save Path At", iRecentSavesTotal-1) .. "." .. gsDE
        TL_SetProperty("Append", sString)
    end
    return
end

--Others.
local iRoom = fnGetRoomIndex(gzTextVar.gzPlayer.sLocation)
if(iRoom == -1) then return end

--[ ================================== Deconstruction Sequence ================================== ]
--[Save Flags]
local bWasFogActive = gzTextVar.bIsFogActive
local bWasDarkActive = gzTextVar.bIsDarkActive

--[Indicators]
--Removes all indicators.
TL_SetProperty("Unregister All Entity Indicators")

--[Visibility]
fnUnmarkMinimapForPosition(gzTextVar.gzPlayer.sLocation)

--[ ===================================== Loading Sequence ====================================== ]
--[Load]
--Now actually load the game.
TL_Load("Saves/" .. sSaveName .. ".tls")
TL_SetProperty("Append", "Loading 'Saves/" .. sSaveName .. ".tls'." .. gsDE)

--[ ================================== Reconstruction Sequence ================================== ]
--[Indicators]
--Replace indicators. First, the player.
local fX, fY, fZ = fnGetRoomPosition(gzTextVar.gzPlayer.sLocation)
TL_SetProperty("Register Entity Indicator", fX, fY, fZ, "Player", gzTextVar.gzPlayer.iIndicatorX, gzTextVar.gzPlayer.iIndicatorY, gzTextVar.gzPlayer.iIndicatorC)
TL_SetProperty("Set Map Focus", -fX, -fY)
TL_SetProperty("Player World Position", fX, fY, fZ)

--Rendering handler. Top floor renders the middle floor, otherwise no secondary rendering.
TL_SetProperty("Set Rendering Z Level", fZ)
if(fZ < 0) then
    TL_SetProperty("Set Under Rendering Z Level", fZ+1, 0)
else
    TL_SetProperty("Set Under Rendering Z Level", ciDoNotRenderUnder, ciDoNotRenderUnder)
end

--Now all entities.
for i = 1, gzTextVar.zEntitiesTotal, 1 do
    
    --Skip entities with no indicators.
    if(gzTextVar.zEntities[i].iIndicatorX ~= "No Indicator") then
        
        --Create the indicator.
        fX, fY, fZ = fnGetRoomPosition(gzTextVar.zEntities[i].sLocation)
        TL_SetProperty("Register Entity Indicator", fX, fY, fZ, gzTextVar.zEntities[i].sIndicatorName, gzTextVar.zEntities[i].iIndicatorX, gzTextVar.zEntities[i].iIndicatorY, gzTextVar.zEntities[i].iIndicatorC)
        
        --Hostility state. Entities should have a hostility flag.
        if(gzTextVar.zEntities[i].iIndicatorH == 1) then
            TL_SetProperty("Modify Entity Indicator Hosility", fX, fY, fZ, gzTextVar.zEntities[i].sIndicatorName, ciHostilityX_Enemy, ciHostilityY_Enemy)
        elseif(gzTextVar.zEntities[i].iIndicatorH == 2) then
            TL_SetProperty("Modify Entity Indicator Hosility", fX, fY, fZ, gzTextVar.zEntities[i].sIndicatorName, ciHostilityX_Boss, ciHostilityY_Boss)
        end

    end
end

--Now all items.
gzTextVar.bIsBuildingIndicatorInfo = true
for i = 1, gzTextVar.iRoomsTotal, 1 do
    
    --Iterate across the item list.
    for p = 1, gzTextVar.zRoomList[i].iObjectsTotal, 1 do
        
        --First pass, get the X/Y/Z of the room.
        if(p == 1) then
            fX, fY, fZ = fnGetRoomPosition(gzTextVar.zRoomList[i].sName)
        end
        
        --Call the item script to get its indicator information. If it has no indicator, it will not change the state machine vars.
        gzTextVar.iGlobalIndicatorX = -1
        gzTextVar.iGlobalIndicatorY = -1
        LM_ExecuteScript(gzTextVar.zRoomList[i].zObjects[p].sHandlerScript)
        
        --If the indicators are not -1's, spawn an indicator in the given room.
        if(gzTextVar.iGlobalIndicatorX ~= -1 and gzTextVar.iGlobalIndicatorY ~= -1) then
            
            --Create a unique name.
            local sIndicatorName = fnGenerateIndicatorName()
            gzTextVar.zRoomList[i].zObjects[p].sIndicatorName = sIndicatorName
            
            --Upload.
            TL_SetProperty("Register Entity Indicator", fX, fY, fZ, sIndicatorName, gzTextVar.iGlobalIndicatorX, gzTextVar.iGlobalIndicatorY, ciCodeItem)
        end
    end
end
gzTextVar.bIsBuildingIndicatorInfo = false

--[Combat Type]
--Set combat type.
if(gzTextVar.bIsCombatWaitMode == true) then
    TL_SetProperty("Set Combat Active Mode", false)
else
    TL_SetProperty("Set Combat Active Mode", true)
end

--[Player Stats]
--Fix skin color if it's broken.
if(gzTextVar.gzPlayer.iSkinColor == -1) then
    gzTextVar.gzPlayer.iSkinColor = 0
end

--Set player's base statistics.
TL_SetProperty("Set Player Stats", gzTextVar.gzPlayer.iHP, gzTextVar.gzPlayer.iHPMax, gzTextVar.gzPlayer.iAtp, gzTextVar.gzPlayer.iDef, gzTextVar.gzPlayer.sQuerySprite)
TL_SetProperty("Set Storage Line", 0, "Turn: " .. gzTextVar.iWorldTurns)
TL_SetProperty("Unregister Image")

--Make sure the player's portrait is their query portrait.
TL_SetProperty("Default Image", "You", gzTextVar.gzPlayer.sLayer0, ciImageLayerDefault)

--If the extra layer has something, set it.
if(gzTextVar.gzPlayer.sLayer1 ~= "Null") then
    TL_SetProperty("Default Image", "You", gzTextVar.gzPlayer.sLayer1, ciImageLayerOverlay)
else
    TL_SetProperty("Default Image", "Null", gzTextVar.gzPlayer.sLayer1, ciImageLayerOverlay)
end

--[Map]
for i = 1, #gzTextVar.gzPlayer.baMapLayers, 1 do
    TL_SetProperty("Set Layer Visible", gzTextVar.gzPlayer.baMapLayers[i][1], gzTextVar.gzPlayer.baMapLayers[i][2])
end

--[Visibility]
fnMarkMinimapForPosition(gzTextVar.gzPlayer.sLocation)
TL_SetProperty("Reresolve Fades")

--[Doors]
--Update all door indicators in the world to match their new properties. Note that the Lua doors
-- are already updated, we are only modifying the display values.
for i = 1, gzTextVar.iRoomsTotal, 1 do
    
    --Coordinates.
    local fModX = gzTextVar.zRoomList[i].fRoomX
    local fModY = gzTextVar.zRoomList[i].fRoomY
    local fModZ = gzTextVar.zRoomList[i].fRoomZ
    
    --While we're at it, decide if the room is explored or not.
    TL_SetProperty("Set Room Explored", fModX, fModY, fModZ, gzTextVar.zRoomList[i].bIsExplored)
    
    --East Door
    if(gzTextVar.zRoomList[i].sDoorE ~= nil) then
        
        --If the door is "LockKnown", then set its key indicator. Some doors can be known by default.
        if(gzTextVar.zRoomList[i].bDoorELockKnown == true) then
            
            --Get the locking state.
            local sLockState = string.sub(gzTextVar.zRoomList[i].sDoorE, 2)
                
            --Set door indicators by tile code.
            if(sLockState == " Normal") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, false, gzTextVar.iLock_None_X, gzTextVar.iLock_None_Y)
            elseif(sLockState == " Heart") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, false, gzTextVar.iLock_Heart_X, gzTextVar.iLock_Heart_Y)
            elseif(sLockState == " Club") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, false, gzTextVar.iLock_Club_X, gzTextVar.iLock_Club_Y)
            elseif(sLockState == " Diamond") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, false, gzTextVar.iLock_Diamond_X, gzTextVar.iLock_Diamond_Y)
            elseif(sLockState == " Spade") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, false, gzTextVar.iLock_Spade_X, gzTextVar.iLock_Spade_Y)
            elseif(sLockState == " Small") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, false, gzTextVar.iLock_Small_X, gzTextVar.iLock_Small_Y)
            else
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, false, gzTextVar.iLock_None_X, gzTextVar.iLock_None_Y)
            end
        
        --Otherwise, the door is marked as unknown.
        else
            TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, false, gzTextVar.iLock_None_X, gzTextVar.iLock_None_Y)
        end
        
        --Door is closed:
        if(string.sub(gzTextVar.zRoomList[i].sDoorE, 1, 1) == "C") then
            TL_SetProperty("Set Room Door State", fModX, fModY, fModZ, false, false)
         
        --Door is open:
        else
            TL_SetProperty("Set Room Door State", fModX, fModY, fModZ, false, true)
        end
    end
    
    --South Door
    if(gzTextVar.zRoomList[i].sDoorS ~= nil) then
            
        --If the door is "LockKnown", then set its key indicator. Some doors can be known by default.
        if(gzTextVar.zRoomList[i].bDoorSLockKnown == true) then
            
            --Get the locking state.
            local sLockState = string.sub(gzTextVar.zRoomList[i].sDoorS, 2)
                
            --Set door indicators by tile code.
            if(sLockState == " Normal") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, true, gzTextVar.iLock_None_X, gzTextVar.iLock_None_Y)
            elseif(sLockState == " Heart") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, true, gzTextVar.iLock_Heart_X, gzTextVar.iLock_Heart_Y)
            elseif(sLockState == " Club") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, true, gzTextVar.iLock_Club_X, gzTextVar.iLock_Club_Y)
            elseif(sLockState == " Diamond") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, true, gzTextVar.iLock_Diamond_X, gzTextVar.iLock_Diamond_Y)
            elseif(sLockState == " Spade") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, true, gzTextVar.iLock_Spade_X, gzTextVar.iLock_Spade_Y)
            elseif(sLockState == " Small") then
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, true, gzTextVar.iLock_Small_X, gzTextVar.iLock_Small_Y)
            else
                TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, true, gzTextVar.iLock_None_X, gzTextVar.iLock_None_Y)
            end
        
        --Otherwise, the door is marked as unknown.
        else
            TL_SetProperty("Set Room Door Indicator", fModX, fModY, fModZ, true, gzTextVar.iLock_None_X, gzTextVar.iLock_None_Y)
        end
        
        --Door is closed:
        if(string.sub(gzTextVar.zRoomList[i].sDoorS, 1, 1) == "C") then
            TL_SetProperty("Set Room Door State", fModX, fModY, fModZ, true, false)
        
        --Door is open.
        else
            TL_SetProperty("Set Room Door State", fModX, fModY, fModZ, true, true)
        end
    end
    
end

--[ ========================================== Overlays ========================================= ]
--Functions
local fnActivateFog = function()
    local fConstant = 0.10
    TL_SetProperty("Activate Overlays")
    TL_SetProperty("Clear Overlays")
    if(gzTextVar.gzPlayer.zWeapon ~= nil and gzTextVar.gzPlayer.zWeapon.sUniqueName == "torch") then
        TL_SetProperty("Register Overlay", "Fog0", "Root/Images/DollManor/Overlays/Fog0Big", gciOverlay_Exclusion, 0, 0, 0, 0, 200.0, 200.0)
    else
        TL_SetProperty("Register Overlay", "Fog0", "Root/Images/DollManor/Overlays/Fog0", gciOverlay_Exclusion, 0, 0, 0, 0, 200.0, 200.0)
    end
    TL_SetProperty("Register Overlay", "Fog4", "Root/Images/DollManor/Overlays/Fog4", gciOverlay_Normal,    LM_GetRandomNumber(0, 256), LM_GetRandomNumber(0, 256),  2.0 * fConstant,  1.5 * fConstant, 512.0, 512.0)
    TL_SetProperty("Register Overlay", "Fog1", "Root/Images/DollManor/Overlays/Fog1", gciOverlay_Bypass,    LM_GetRandomNumber(0, 256), LM_GetRandomNumber(0, 256), -1.5 * fConstant,  2.5 * fConstant, 512.0, 512.0)
    TL_SetProperty("Register Overlay", "Fog2", "Root/Images/DollManor/Overlays/Fog2", gciOverlay_Bypass,    LM_GetRandomNumber(0, 256), LM_GetRandomNumber(0, 256), -2.5 * fConstant, -2.5 * fConstant, 512.0, 512.0)
end
local fnActivateDark = function()
    local fConstant = 0.10
    TL_SetProperty("Activate Overlays")
    TL_SetProperty("Clear Overlays")
    if(gzTextVar.gzPlayer.zWeapon ~= nil and gzTextVar.gzPlayer.zWeapon.sUniqueName == "torch") then
        TL_SetProperty("Register Overlay", "Black0", "Root/Images/DollManor/Overlays/Black0Big", gciOverlay_Exclusion, 0, 0, 0.0, 0.0, 1000.0, 400.0)
    else
        TL_SetProperty("Register Overlay", "Black0", "Root/Images/DollManor/Overlays/Black0", gciOverlay_Exclusion, 0, 0, 0.0, 0.0, 1000.0, 400.0)
    end
    TL_SetProperty("Register Overlay", "Black1", "Root/Images/DollManor/Overlays/Black1", gciOverlay_Normal,    0, 0, 0.0, 0.0, 1000.0, 400.0)
end
local fnDeactivateOverlays = function()
    TL_SetProperty("Deactivate Overlays")
end

--If Fog was active:
if(bWasFogActive == true) then

    --And is still active, do nothing:
    if(gzTextVar.bIsFogActive == true) then

    --Otherwise, un-fog things.
    else
        --If Dark is active, clear overlays and switch to darkness.
        if(gzTextVar.bIsDarkActive == true) then
            fnActivateDark()
    
        --Otherwise, just deactivate all overlays.
        else
            fnDeactivateOverlays()
        end
    end

--If Dark was active:
elseif(bWasDarkActive == true) then

    --And is still active, do nothing:
    if(gzTextVar.bIsDarkActive == true) then

    --Otherwise, un-dark things.
    else
        --If Fog is active, clear overlays and switch to foggy.
        if(gzTextVar.bIsFogActive == true) then
            fnActivateFog()
    
        --Otherwise, just deactivate all overlays.
        else
            fnDeactivateOverlays()
        end
    end

--If neither dark or fog was active, activate whichever *is* active.
else
    if(gzTextVar.bIsFogActive == true) then
        fnActivateFog()
    elseif(gzTextVar.bIsDarkActive == true) then
        fnActivateDark()
    else
        fnDeactivateOverlays()
    end
end

--[Setup Locality Info]
fnBuildLocalityInfo()
