local LD = require("design.LevelDesignLibrary")
local mpicon = require("ui.mpicon")
local player, thisObj, thisLevel, heroPup, sonPup, onStartEvents, completeEvents, startBranch, startBranchSon, tnfType, interactZone
local complete = false
local usingThisInteract = false
local enabled, startEnabled
local bGeoVisible = true
local bShowUIonStart = true
local puppeteerObject
function OnScriptLoaded(level, obj)
  player = game.Player.FindPlayer()
  thisObj = obj
  thisLevel = level
  interactZone = LD.CreateInteractZone_Standard_360(obj, "promptJoint")
  tnfType = obj:FindLuaTableAttribute("TNF_Type")
  startEnabled = obj:FindLuaTableAttribute("startEnabled")
  bShowUIonStart = obj:FindLuaTableAttribute("showUIonStart")
  puppeteerObject = obj:FindLuaTableAttribute("puppeteerObject")
  if puppeteerObject ~= nil and puppeteerObject ~= "" then
    puppeteerObject = level:FindSingleGameObject(tostring(puppeteerObject))
  else
    puppeteerObject = obj
  end
  if startEnabled ~= nil then
    if startEnabled then
      enabled = true
    else
      enabled = false
    end
  end
  if tnfType == "HiveRip" then
    startBranch = "BRA_TNF_HiveRipEnter"
  elseif tnfType == "HiveRip180" then
    startBranch = "BRA_TNF_HiveRipEnter180"
  elseif tnfType == "HiveRipStruggle" then
    startBranch = "BRA_TNF_New_HiveStruggleEnter"
  elseif tnfType == "Stn430_HammerFall" then
    startBranch = "BRA_HammerFall"
    startBranchSon = "BRA_HammerFall"
  elseif tnfType == "HarpoonRemove01" then
    startBranch = "BRA_ShipHarpMoment01_RemoveHarpoon"
  elseif tnfType == "HarpoonRemove02LF" then
    startBranch = "BRA_ShipHarpMoment02_LFirst_RemoveHarpoon"
  elseif tnfType == "HarpoonRemove02RF" then
    startBranch = "BRA_ShipHarpMoment02_RFirst_RemoveHarpoon"
  elseif tnfType == "HarpoonRemove02LS" then
    startBranch = "BRA_ShipHarpMoment02_LSecond_RemoveHarpoon"
  elseif tnfType == "HarpoonRemove02RS" then
    startBranch = "BRA_ShipHarpMoment02_RSecond_RemoveHarpoon"
  else
    startBranch = "BRA_TNF_New_TempleLiftStruggleEnter"
  end
  bGeoVisible = obj:FindLuaTableAttribute("GeoVisible")
  completeEvents = LD.ExtractCallbacksForEvent(level, obj, obj:FindLuaTableAttribute("Event_OnWin"))
  onStartEvents = LD.ExtractCallbacksForEvent(level, obj, obj:FindLuaTableAttribute("Event_OnStart"))
end
function OnFirstStart(level, obj)
  if bGeoVisible ~= nil then
    if bGeoVisible then
      obj:Show()
    else
      obj:Hide()
    end
  end
end
function OnStart(level, obj)
  if enabled then
    Enable()
  else
    Disable()
  end
end
function OnUseWorld(level, obj)
  if interactZone:PlayerCanInteract() then
    PerformInteraction()
  end
end
function PerformInteraction()
  if heroPup == nil then
    if bShowUIonStart then
      mpicon.level.Create(thisObj, "WORLD_INTERACT_MASHBUTTON")
    end
    usingThisInteract = true
    Disable()
    local synchJoint
    if puppeteerObject:FindJointIndex("syncJoint") ~= nil then
      synchJoint = "syncJoint"
    elseif puppeteerObject:FindJointIndex("synchJoint") ~= nil then
      synchJoint = "synchJoint"
    end
    heroPup = game.Puppeteer.NewForce(puppeteerObject, "TNF Sequence", player)
    heroPup:OnEvent(ClearPuppeteer, "kEHitReaction")
    if startBranchSon == nil then
      heroPup:Sync(startBranch, true, {}, synchJoint)
    else
      sonPup = game.Puppeteer.NewForce(puppeteerObject, "TNF Sequence", game.AI.FindSon())
      sonPup:AcceptSync()
      heroPup:Sync(startBranch, true, {
        {Slave = sonPup, Branch = startBranchSon}
      }, synchJoint)
    end
    heroPup:OnComplete(ClearPuppeteer)
    LD.ExecuteCallbacksForEvent(thisLevel, thisObj, onStartEvents, "TNF Started Events")
  end
end
function ForceInteractImmediate()
  PerformInteraction()
end
function StartSync()
  if heroPup ~= nil then
    heroPup:Clear()
    heroPup:OnEvent(ClearPuppeteer, "kEHitReaction")
    heroPup:Sync(startBranch, true, {}, "syncJoint")
    heroPup:OnComplete(ClearPuppeteer)
  end
end
function ClearPuppeteer()
  if bShowUIonStart then
    mpicon.level.Off(thisObj, "WORLD_INTERACT_MASHBUTTON")
  end
  if complete == false then
    if usingThisInteract and player:HasMarker("TnF_Win") then
      complete = true
      thisObj:Hide()
      LD.ExecuteCallbacksForEvent(thisLevel, thisObj, completeEvents, "TNF Complete Events")
    else
      Enable()
    end
  end
  usingThisInteract = false
  if heroPup ~= nil then
    heroPup:Clear()
    heroPup:DetachPuppet()
    heroPup = nil
  end
  if sonPup ~= nil then
    sonPup:Clear()
    sonPup:DetachPuppet()
    sonPup = nil
  end
end
function Reset()
  if bGeoVisible then
    thisObj:Show()
  else
    thisObj:Hide()
  end
  complete = false
  Enable()
end
function Enable()
  enabled = true
  interactZone:Enable()
end
function Disable()
  enabled = false
  interactZone:Disable()
end
function OnSaveCheckpoint(level)
  return {
    useEnabled = interactZone:IsEnabled(),
    complete = complete,
    enabled = enabled
  }
end
function OnRestoreCheckpoint(level, go, tab)
  interactZone:SetEnabled(tab.useEnabled)
  complete = tab.complete
  enabled = tab.enabled
end
