local LD = require("design.LevelDesignLibrary")
local timers = require("level.timer")
local thisObj, vendorNPC, vendorInteract, talkInteract, thisLevel, combatActive, vendorNPCSpawner, greetingDoneTimer
local greetingCooldownTime = 2
local shopExitTimer
local shopExitCooldownTime = 10
local teleportJoint, teleportPos, teleportFacing, mapMarkerID, regionSummaryQuest
local shopIsHidden = false
local locationDiscovered, smallShopArt, smallShopArtTable
local vendorAutoEnable = true
local blockProximityAddMapMarker, workBlade, grindStone, bellow, hammer, brokHammer, sindri, workBladeGrindStone
local brokShopPropTable = {}
local sindriShopPropTable = {}
local wasJustHammering, counterSpawnRequested, vendorAtCounter, grindingNotAllowed, playerAtCounter, contextActionEnabled, contextActionObj
function OnScriptLoaded(level, obj)
  thisLevel = level
  thisObj = obj
  vendorNPCSpawner = thisObj:FindSingleGOByName("VendorSpawner")
  vendorInteract = thisObj:FindSingleGOByName("vendorInteract")
  talkInteract = thisObj:FindSingleGOByName("TalkInteract_SM")
  print("VendorNPCSspawner...", vendorNPCSpawner, vendorInteract)
  greetingDoneTimer = StartLevelTimer(greetingCooldownTime, ResetToIdle)
  greetingDoneTimer:Stop()
  shopExitTimer = StartLevelTimer(shopExitCooldownTime, ResetToIdle)
  shopExitTimer:Stop()
  if thisObj:FindLuaTableAttribute("MapMarkerName") ~= nil and thisObj:FindLuaTableAttribute("MapMarkerName") ~= "" then
    mapMarkerID = thisObj:FindLuaTableAttribute("MapMarkerName")
  end
  blockProximityAddMapMarker = thisObj:FindLuaTableAttribute("blockProximityAddMapMarker")
  grindingNotAllowed = thisObj:FindLuaTableAttribute("grindingNotAllowed")
  contextActionEnabled = thisObj:FindLuaTableAttribute("contextActionEnabled")
  contextActionObj = thisObj:FindSingleGOByName("CA_Idle")
  if thisObj:FindLuaTableAttribute("regionSummaryQuest") ~= nil and thisObj:FindLuaTableAttribute("regionSummaryQuest") ~= "" then
    regionSummaryQuest = thisObj:FindLuaTableAttribute("regionSummaryQuest")
    print("Region summary quest is..............", regionSummaryQuest)
  end
  workBlade = thisObj:FindSingleGOByName("workBlade")
  hammer = thisObj:FindSingleGOByName("sindriHammer")
  brokHammer = thisObj:FindSingleGOByName("brokHammer")
  workBladeGrindStone = thisObj:FindSingleGOByName("workBladeGrind")
  grindStone = thisObj:FindSingleGOByName("huldraGrindstone")
  bellow = thisObj:FindSingleGOByName("bellow00Prop")
  teleportJoint = thisObj:GetJointIndex("shopSync")
  teleportPos = thisObj:GetWorldJointPosition(teleportJoint)
  teleportFacing = thisObj:GetWorldJointForward(teleportJoint)
  print("teleport joint and pos and facing..", teleportJoint, teleportPos, teleportFacing)
  smallShopArt = thisObj:FindSingleGOByName("SharedShopArtAssets")
  smallShopArtTable = thisObj:FindSingleGOByName("SmallShop_Table")
  local goQuestCamera = obj:FindSingleGOByName("HuldraBrothersCamera")
  if goQuestCamera ~= nil then
    goQuestCamera.LuaObjectScript.SetCameraType("HuldraBrothersInteract_SmallTable")
  end
  game.SubObject.SetUpdateDisableDistance(obj, 25)
  local brokSpawner = obj:FindSingleGOByName("VendorSpawner")
  brokSpawner.LuaObjectScript.RegisterOnSpawnCallback(AltSpawnSync)
end
function OnFirstStart(level, obj)
  InitializeProps(grindStone)
  InitializeProps(workBlade)
  InitializeProps(workBladeGrindStone)
  InitializeProps(bellow)
  InitializeProps(hammer)
  brokHammer:Hide()
  ContextActionCheck()
end
function OnStart(level, obj)
  InitializeProps(grindStone)
  InitializeProps(workBlade)
  InitializeProps(workBladeGrindStone)
  InitializeProps(bellow)
  InitializeProps(hammer)
  brokHammer:Hide()
  ContextActionCheck()
  game.Audio.SetBanterFact("BrokInLargeShop", "False")
  game.Audio.SetBanterFact("SindriInLargeShop", "False")
end
function OnUpdate(level, obj)
  if game.Combat.GetCombatStatus() and not combatActive then
    CombatStart()
    combatActive = true
  elseif not game.Combat.GetCombatStatus() and combatActive then
    CombatExit()
    combatActive = false
  end
end
function OnSaveCheckpoint(level, obj)
  return {locationDiscovered = locationDiscovered}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  locationDiscovered = savedInfo.locationDiscovered
end
function DespawnTriggered()
  DisableVendorInteract()
  ClearTalkInteractNPC()
  InitializeProps(grindStone)
  InitializeProps(workBlade)
  InitializeProps(workBladeGrindStone)
  InitializeProps(bellow)
  InitializeProps(hammer)
  brokHammer:Hide()
end
function InitializeProps(propName)
  local animObj = propName
  if animObj ~= nil then
    animObj.Child:PlayAnimationToFrame(0, {
      Animation = "envSindriKratosIdle01"
    })
  end
end
function ExitShopCheck()
  print("Got my exit shop check")
  GetSpawnedNPC()
  if not playerAtCounter and vendorNPC ~= nil then
    if vendorAtCounter or vendorNPC:IsPlayingMove("MOV_Vendor_CounterIdle") then
      if wasJustHammering and not grindingNotAllowed then
        SendVendorToGrindStone()
        wasJustHammering = false
      elseif grindingNotAllowed then
        SendVendorToAnvil()
      else
        SendVendorToAnvil()
      end
    else
      RequestNpcMoveEvent("LookAtExit")
    end
  end
end
function EnableTalkInteract()
  talkInteract.LuaObjectScript.Enable()
end
function ClearTalkInteractNPC()
  talkInteract.LuaObjectScript.ClearTalkNPC()
end
function EnableCinematicTrigger()
  vendorInteract.LuaObjectScript.EnableCinematicTrigger()
  talkInteract.LuaObjectScript.EnableCinematicTrigger()
end
function DisableCinematicTrigger()
  vendorInteract.LuaObjectScript.DisableCinematicTrigger()
  talkInteract.LuaObjectScript.DisableCinematicTrigger()
end
function EnableCinematicTriggerTalkInteract()
  talkInteract.LuaObjectScript.EnableCinematicTrigger()
end
function DisableCinematicTriggerTalkInteract()
  talkInteract.LuaObjectScript.DisableCinematicTrigger()
end
function EnableCinematicTriggerVendorInteract()
  vendorInteract.LuaObjectScript.EnableCinematicTrigger()
end
function EnableVendorInteract()
  if vendorNPC ~= nil then
    vendorInteract.LuaObjectScript.Enable()
  end
end
function DisableVendorInteract()
  vendorInteract.LuaObjectScript.Disable()
end
function ForceShopInteract()
  vendorInteract.LuaObjectScript.StartVendorInteract()
end
function ContextActionCheck()
  if contextActionEnabled then
    print("enablign context action", contextActionObj)
    EnableShopContextAction()
  else
    print("enablign context action", contextActionObj)
    DisableShopContextAction()
  end
end
function EnableShopContextAction()
  if contextActionEnabled and contextActionObj ~= nil then
    contextActionObj.LuaObjectScript.Enable()
  end
end
function DisableShopContextAction()
  if contextActionObj ~= nil then
    contextActionObj.LuaObjectScript.Disable()
  end
end
function EnableAllShop()
  shopIsHidden = false
  if smallShopArt ~= nil then
    smallShopArt:Show()
  end
  if smallShopArtTable ~= nil then
    smallShopArtTable:Show()
  end
  grindStone:Show()
  workBlade:Show()
  thisObj:ShowCollision()
  workBladeGrindStone:Show()
  bellow:Show()
  InitializeProps(grindStone)
  InitializeProps(workBlade)
  InitializeProps(workBladeGrindStone)
  InitializeProps(bellow)
  talkInteract:Show()
end
function DisableAllShop()
  shopIsHidden = true
  if smallShopArt ~= nil then
    smallShopArt:Hide()
  end
  if smallShopArtTable ~= nil then
    smallShopArtTable:Hide()
  end
  talkInteract.LuaObjectScript.DisableInteract()
  talkInteract.LuaObjectScript.DisableQuestGiver()
  talkInteract:Hide()
  vendorInteract.LuaObjectScript.Disable()
  thisObj:HideCollision()
  bellow:Hide()
  hammer:Hide()
  brokHammer:Hide()
  workBlade:Hide()
  grindStone:Hide()
  workBladeGrindStone:Hide()
end
function TriggerShopDiscovered()
  if shopIsHidden == false and not locationDiscovered then
    if mapMarkerID ~= nil and blockProximityAddMapMarker ~= true then
      LD.SetMarkerState(mapMarkerID, 1)
      LD.UpdateMap(mapMarkerID, 0)
      locationDiscovered = true
    end
    if regionSummaryQuest ~= nil and regionSummaryQuest ~= "" then
      regionSummaryQuest = string.gsub(regionSummaryQuest, "%s+", "")
      LD.ActivateAndIncrementQuest(regionSummaryQuest)
    end
  end
end
function RequestNpcMoveEvent(eventName)
  if vendorNPC ~= nil then
    vendorNPC:TriggerMoveEvent(eventName)
  end
end
function SendVendorToTable()
  vendorAtCounter = true
  RequestNpcMoveEvent("ExitToCounter")
end
function SendVendorToGrindStone()
  vendorAtCounter = false
  RequestNpcMoveEvent("ExitToGrindStone")
end
function SendVendorToAnvil()
  vendorAtCounter = false
  RequestNpcMoveEvent("ExitToAnvil")
  wasJustHammering = true
end
function CombatStart()
  RequestNpcMoveEvent("EnterCombat")
end
function CombatExit()
  RequestNpcMoveEvent("ExitCombat")
end
function PlaySpawnSync()
end
function AltSpawnSync(brok)
  print("attemping to re-sync")
  GetSpawnedNPC()
  if vendorNPC ~= nil then
    EnableVendorInteract()
    vendorNPC:RequestInteract(thisObj)
  end
end
function EnableCorrectHammer()
  GetSpawnedNPC()
  if vendorNPC ~= nil then
    if vendorNPC:GetName() == "brok00" then
      brokHammer:Show()
      for _, desc in pairs(brokHammer.Descendants) do
        desc:Show()
      end
      hammer:Hide()
    else
      brokHammer:Hide()
      hammer:Show()
      for _, desc in pairs(hammer.Descendants) do
        desc:Show()
      end
    end
  end
end
function StartHammerSync()
  wasJustHammering = true
  vendorAtCounter = false
  GetSpawnedNPC()
  timers.StartLevelTimer(0.1, EnableCorrectHammer)
  if vendorNPC ~= nil then
    if vendorNPC:GetName() == "brok00" then
      print("Hammer is...", brokHammer)
      brokShopPropTable = {
        {
          vendorNPC,
          "BRA_VendorSpawn"
        },
        {
          grindStone.Child,
          "envBrokPos01Idle"
        },
        {
          workBlade.Child,
          "envBrokPos01Idle"
        },
        {
          brokHammer.Child,
          "envBrokPos01Idle"
        },
        {
          bellow.Child,
          "envBrokPos01Idle"
        },
        {
          workBladeGrindStone.Child,
          "envBrokPos01Idle"
        }
      }
      LD.PlayGroupSync(thisObj, brokShopPropTable, "envBrokPos01Idle", true, "shopSync")
    else
      sindri = vendorNPC
      sindriShopPropTable = {
        {
          sindri,
          "BRA_VendorSpawn"
        },
        {
          grindStone.Child,
          "envSindriPos01Idle"
        },
        {
          workBlade.Child,
          "envSindriPos01Idle"
        },
        {
          hammer.Child,
          "envSindriPos01Idle"
        },
        {
          bellow.Child,
          "envSindriPos01Idle"
        },
        {
          workBladeGrindStone.Child,
          "envSindriPos01Idle"
        }
      }
      LD.PlayGroupSync(thisObj, sindriShopPropTable, "envSindriPos01Idle", true, "shopSync")
    end
  end
end
function StartCounterRequest(npc, autoEnable)
  if npc ~= nil then
    counterSpawnRequested = true
    npc:RequestInteract(thisObj)
    vendorNPC = npc
    talkInteract.LuaObjectScript.SetTalkNpc(vendorNPC)
    if autoEnable == false then
      vendorAutoEnable = false
    else
      vendorAutoEnable = true
    end
  else
    print("spawned npc is nil")
  end
end
function StartCounterSync()
  counterSpawnRequested = false
  wasJustHammering = true
  GetSpawnedNPC()
  vendorAtCounter = true
  if vendorNPC ~= nil then
    timers.StartLevelTimer(0.1, EnableCorrectHammer)
    if vendorAutoEnable then
      EnableVendorInteract()
    end
    if vendorNPC:GetName() == "brok00" then
      brokShopPropTable = {
        {
          vendorNPC,
          "BRA_VendorCounterSpawn"
        },
        {
          grindStone.Child,
          "envBrokKratosIdle01"
        },
        {
          workBlade.Child,
          "envBrokKratosIdle01"
        },
        {
          brokHammer.Child,
          "envBrokKratosIdle01"
        },
        {
          bellow.Child,
          "envBrokKratosIdle01"
        },
        {
          workBladeGrindStone.Child,
          "envBrokKratosIdle01"
        }
      }
      LD.PlayGroupSync(thisObj, brokShopPropTable, "envBrokKratosIdle01", true, "shopSync")
    else
      sindri = vendorNPC
      sindriShopPropTable = {
        {
          sindri,
          "BRA_VendorCounterSpawn"
        },
        {
          grindStone.Child,
          "envSindriKratosIdle01"
        },
        {
          workBlade.Child,
          "envSindriKratosIdle01"
        },
        {
          hammer.Child,
          "envSindriKratosIdle01"
        },
        {
          bellow.Child,
          "envSindriKratosIdle01"
        },
        {
          workBladeGrindStone.Child,
          "envSindriKratosIdle01"
        }
      }
      LD.PlayGroupSync(thisObj, sindriShopPropTable, "envSindriKratosIdle01", true, "shopSync")
    end
  end
end
function StartGrindSyncBrok()
  wasJustHammering = false
  vendorAtCounter = false
  timers.StartLevelTimer(0.1, EnableCorrectHammer)
  if vendorNPC ~= nil then
    if vendorNPC:GetName() == "brok00" then
      brokHammer:Show()
      brokShopPropTable = {
        {
          vendorNPC,
          "BRA_VendorGrindStoneSpawn"
        },
        {
          grindStone.Child,
          "envBrokPos02Idle"
        },
        {
          workBlade.Child,
          "envBrokPos02Idle"
        },
        {
          brokHammer.Child,
          "envBrokPos02Idle"
        },
        {
          bellow.Child,
          "envBrokPos02Idle"
        },
        {
          workBladeGrindStone.Child,
          "envBrokPos02Idle"
        }
      }
      LD.PlayGroupSync(thisObj, brokShopPropTable, "envBrokPos02Idle", true, "shopSync")
    else
      sindri = vendorNPC
      sindriShopPropTable = {
        {
          sindri,
          "BRA_VendorGrindStoneSpawn"
        },
        {
          grindStone.Child,
          "envSindriPos02Idle"
        },
        {
          workBlade.Child,
          "envSindriPos02Idle"
        },
        {
          hammer.Child,
          "envSindriPos02Idle"
        },
        {
          bellow.Child,
          "envSindriPos02Idle"
        },
        {
          workBladeGrindStone.Child,
          "envSindriPos02Idle"
        }
      }
      LD.PlayGroupSync(thisObj, sindriShopPropTable, "envSindriPos02Idle", true, "shopSync")
    end
  end
end
function PassInVendorNpc(npc)
  if npc ~= nil then
    vendorNPC = npc
    print("GOT PASSED IN NPC", npc)
  end
end
function GetSpawnedNPC()
  if vendorNPC == nil then
    vendorNPC = vendorNPCSpawner.LuaObjectScript.GetLastEnemy()
    if vendorNPC ~= nil then
      vendorInteract.LuaObjectScript.SetVendorType(vendorNPC)
      talkInteract.LuaObjectScript.SetTalkNpc(vendorNPC)
    end
  else
    vendorInteract.LuaObjectScript.SetVendorType(vendorNPC)
  end
end
function OnInteractStart(level, obj, creature)
  if counterSpawnRequested then
    StartCounterSync()
  else
    StartHammerSync()
  end
end
function OnInteractAbort(level, obj, creature)
  InitializeProps(grindStone)
  InitializeProps(workBlade)
  InitializeProps(workBladeGrindStone)
  InitializeProps(bellow)
  InitializeProps(hammer)
  brokHammer:Hide()
end
function LuaHook_TriggerHammerSpark()
  GetSpawnedNPC()
  if vendorNPC:GetName() == "brok00" then
    local glowFX = game.FX.Spawn("Vendor_BladeGlow", thisLevel, {
      GameObject = thisObj,
      Joint = "hammerTempJoint",
      AutoDelete = true
    })
    local sparkFX = game.FX.Spawn("Vendor_Hammer_Sparks", thisLevel, {
      GameObject = thisObj,
      Joint = "hammerTempJoint",
      AutoDelete = true
    })
  else
    local sparkFX = game.FX.Spawn("Vendor_Hammer_Sparks_Small", thisLevel, {
      GameObject = hammer.Child,
      Joint = "linkJoint",
      AutoDelete = true
    })
    local glowFX = game.FX.Spawn("Vendor_BladeGlow", thisLevel, {
      GameObject = workBlade.Child,
      Joint = "linkJoint",
      AutoDelete = true
    })
  end
end
function LuaHook_BellowCompressed()
  local bellowFX = game.FX.Spawn("Vendor_CoalFire", thisLevel, {
    GameObject = thisObj,
    Joint = "coalFXJoint",
    AutoDelete = true
  })
end
function LuaHook_BladeInCoals()
  local bellowFX = game.FX.Spawn("Vendor_CoalSmoke", thisLevel, {
    GameObject = thisObj,
    Joint = "coalFXJoint",
    AutoDelete = true
  })
end
function LuaHook_TriggerGrindSparkL()
  local grindSparkFX = game.FX.Spawn("Vendor_Grind_Sparks", thisLevel, {
    GameObject = thisObj,
    Joint = "grindstoneJointL",
    AutoDelete = true
  })
end
function LuaHook_BladeLiftFromCoals()
  local coalFollowFX = game.FX.Spawn("Vendor_CoalLift", thisLevel, {
    GameObject = workBlade.Child,
    Joint = "linkJoint",
    Follow = true,
    AutoDelete = true
  })
end
function LuaHook_TriggerGrindSparkR()
  local grindSparkFX = game.FX.Spawn("Vendor_Grind_Sparks", thisLevel, {
    GameObject = thisObj,
    Joint = "grindstoneJointR",
    AutoDelete = true
  })
end
function LuaHook_BladeInWater()
  local bellowFX = game.FX.Spawn("Vendor_WaterSplash", thisLevel, {
    GameObject = thisObj,
    Joint = "bucketFXJoint",
    AutoDelete = true
  })
end
function LuaHook_BladeLiftFromWater()
  local waterfollowFX = game.FX.Spawn("Vendor_Water_BladeRemove", thisLevel, {
    GameObject = workBlade.Child,
    Joint = "linkJoint",
    Follow = true,
    AutoDelete = true
  })
end
function TalkInteractInitiated()
  print("Talk Interact started?")
  shopExitTimer:Stop()
  greetingDoneTimer:Stop()
  shopExitTimer:Reset()
  greetingDoneTimer:Reset()
  DisableVendorInteract()
end
function TalkInteractDone()
  timers.StartLevelTimer(1, EnableVendorInteract)
  shopExitTimer:Start()
  print("Restarting shop exit timer")
end
function TalkStarted()
  print("Talk  started?")
  ForceTalkLookAt()
  shopExitTimer:Stop()
  greetingDoneTimer:Stop()
  shopExitTimer:Reset()
  greetingDoneTimer:Reset()
end
function ResetToIdle()
  if vendorNPC ~= nil then
    ExitShopCheck()
  end
end
function TalkEnded()
  print("Restarting shop exit timer")
  shopExitTimer:Start()
  if vendorNPC ~= nil then
    vendorNPC:RemoveMarker("PlayerCounterRequest")
  end
  playerAtCounter = false
end
function GreetingEnded()
  greetingDoneTimer:Start()
end
function VendorExited()
  print("Vendor Exited")
  shopExitTimer:Start()
  playerAtCounter = false
  if vendorNPC ~= nil then
    vendorNPC:RemoveMarker("PlayerCounterRequest")
  end
end
function VendorEntered()
  if vendorNPC ~= nil then
    vendorNPC:AddMarker("PlayerCounterRequest")
  end
  playerAtCounter = true
  vendorAtCounter = true
  DisableVendorInteract()
  print("Vendor ENtered?")
  shopExitTimer:Stop()
  greetingDoneTimer:Stop()
  shopExitTimer:Reset()
  greetingDoneTimer:Reset()
  if vendorNPC == nil then
    GetSpawnedNPC()
    if vendorNPC ~= nil then
      SendVendorToTable()
    end
  else
    SendVendorToTable()
  end
end
function ForceTalkLookAt()
  if vendorNPC ~= nil then
    RequestNpcMoveEvent("LookAtEnter")
  end
end
