local LD = require("design.LevelDesignLibrary")
local thisObj
local tableEntry = {}
local bFired = false
local cineNumber, checkFunction
function OnScriptLoaded(level, obj)
  thisObj = obj
  game.SubObject.Sleep(obj)
end
function OnStart(level, obj)
  if bFired then
    SafeDumpBookmarkAlert("Bookmark Already Fired. Disabling in OnStart")
    Disable()
    return
  end
  game.SubObject.SetEntityZoneHandler(obj, obj.Parent.Parent)
  local tableEntryName = thisObj:GetLuaTableAttribute("BookmarkName")
  local bookmarks = require("design.Bookmarks")
  tableEntry = bookmarks["BOOKMARK_" .. tableEntryName]
  if tableEntry == nil then
    SafeDumpBookmarkAlert("Invalid Bookmark Specified for Bookmark Zone: " .. "BOOKMARK_" .. tableEntryName .. " does not exist in Bookmarks.lua", true)
    return
  end
  local requirement = tableEntry.Requirement
  local requirementType = type(requirement)
  if requirementType == "number" then
    cineNumber = requirement
  elseif requirementType == "string" or requirementType == "function" then
    checkFunction = requirement
  end
  if cineNumber ~= nil and LD.GetEntityVariable("CompletedCineNumber") > cineNumber then
    DumpBookmarkAlert("Disabling Bookmark Zone because this is already past the cine number.")
    Disable()
    return
  end
  tableEntry.OverrideObject = thisObj:GetLuaTableAttribute("OverrideObject")
  if tableEntry.OverrideObject ~= nil and tableEntry.OverrideObject ~= "" then
    tableEntry.OverrideObject = GameObjects[tableEntry.OverrideObject].Child
  end
end
function Disable()
  bFired = true
  thisObj:Hide()
  thisObj.Parent.Parent:Hide()
end
function OnMarkerEnterZone(level, scriptObj, volumeGameObject, markerGameObject, markerId)
  if tostring(markerId) ~= tostring(3) then
    return
  end
  CheckBookmark()
end
function CheckBookmark(level, obj)
  if bFired then
    DumpBookmarkAlert("Bookmark Already Fired. Disabling in CheckBookmark")
    Disable()
    return
  end
  if checkFunction ~= nil then
    local requirementType = type(checkFunction)
    if requirementType == "string" then
      bFired = LD.ExecuteSingleCallbackAndReturn(level, obj, checkFunction)
    elseif requirementType == "function" then
      bFired = checkFunction()
    end
  elseif cineNumber == nil or LD.GetEntityVariable("CompletedCineNumber") == cineNumber then
    bFired = true
  end
  if bFired then
    if tableEntry.OnSuccess and type(tableEntry.OnSuccess) == "function" then
      tableEntry.OnSuccess()
    end
    Disable()
    DumpBookmarkAlert("Saving Official Bookmark using a Bookmark Zone.")
    game.World.StoreCheckpointAndBookmark(tableEntry)
  end
end
function OnSaveCheckpoint(level, obj)
  return {bFired = bFired}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  bFired = savedInfo.bFired
end
function GetDumpFunction(bError)
  if bError then
    return engine.Error
  else
    return engine.Print
  end
end
function DumpBookmarkAlert(msg, bError)
  if engine.IsDebug() then
    GetDumpFunction(bError)([[

--- BOOKMARK ALERT ---
 ]] .. msg .. [[

CheckpointZone: ]] .. thisObj.Parent.Parent:GetName() .. [[

LevelName: ]] .. thisObj.Level.Name .. [[

Trace: ]] .. LD.GetParentTrace(thisObj) .. [[

BookmarkPath: ]] .. tableEntry.BookmarkName .. [[

IncludeWads: ]] .. LD.ConvertTableToStringList(tableEntry.IncludeWads or {"none"}) .. [[

ExcludeWads: ]] .. LD.ConvertTableToStringList(tableEntry.ExcludeWads or {"none"}) .. [[

DiscardWads: ]] .. LD.ConvertTableToStringList(tableEntry.DiscardWads or {"none"}))
  end
end
function SafeDumpBookmarkAlert(msg, bError)
  if engine.IsDebug() then
    GetDumpFunction(bError)([[

--- BOOKMARK ALERT ---
 ]] .. msg .. [[

CheckpointZone: ]] .. thisObj.Parent.Parent:GetName() .. [[

LevelName: ]] .. thisObj.Level.Name .. [[

Trace: ]] .. LD.GetParentTrace(thisObj))
  end
end
