local PvePhysicsUtil = {}
local ColliderArrayCapacity = 64
local OverlapSphereNonAllocParamArray, OverlapSphereNonAllocParamArrayAccess, OverlapSphereNonAllocResultArray, OverlapSphereNonAllocResultArrayAccess
local BattleColliderUtils = CS.BattleColliderUtils
local BulletColliderResultArray, BulletColliderResultArrayAccess, MonsterColliderResultArray, MonsterColliderResultArrayAccess, UnitColliderResultArray, UnitColliderResultArrayAccess, PlayerColliderResultArray, PlayerColliderResultArrayAccess
local lastCollideFrame = 0
local lastColliderUpdateFrame = 0

function PvePhysicsUtil.OverlapSphereNonAlloc(center, radius, layerMask)
  if OverlapSphereNonAllocParamArray == nil then
    OverlapSphereNonAllocParamArray = LuaCSharpArray.New(8)
    OverlapSphereNonAllocParamArrayAccess = OverlapSphereNonAllocParamArray:GetCSharpAccess()
    OverlapSphereNonAllocResultArray = LuaCSharpArray.New(ColliderArrayCapacity + 4)
    OverlapSphereNonAllocResultArrayAccess = OverlapSphereNonAllocResultArray:GetCSharpAccess()
    BattleColliderUtils.InitOverlapSphereNonAllocAccess(ColliderArrayCapacity, OverlapSphereNonAllocParamArrayAccess, OverlapSphereNonAllocResultArrayAccess)
  end
  OverlapSphereNonAllocParamArray[1] = center.x
  OverlapSphereNonAllocParamArray[2] = center.y
  OverlapSphereNonAllocParamArray[3] = center.z
  OverlapSphereNonAllocParamArray[4] = radius
  OverlapSphereNonAllocParamArray[5] = layerMask
  BattleColliderUtils.OverlapSphereNonAlloc()
  local count = OverlapSphereNonAllocResultArray[1]
  return count
end

function PvePhysicsUtil.GetOverlapSphereNonAllocResultObjId(index)
  return OverlapSphereNonAllocResultArray[index + 1] or 0
end

function PvePhysicsUtil.UpdateCollider()
  local curFrame = Time.frameCount
  if lastColliderUpdateFrame == curFrame then
    return
  end
  lastColliderUpdateFrame = curFrame
  BattleColliderUtils.UpdateCollider()
end

function PvePhysicsUtil.BulletCollider(deltaTime)
  if BulletColliderResultArray == nil then
    BulletColliderResultArray = LuaCSharpArray.New(1024)
    BulletColliderResultArrayAccess = BulletColliderResultArray:GetCSharpAccess()
    BattleColliderUtils.InitBulletColliderResultAccess(BulletColliderResultArrayAccess)
  end
  local curFrame = Time.frameCount
  if lastCollideFrame == curFrame then
    return BulletColliderResultArray
  end
  lastCollideFrame = curFrame
  local res = BattleColliderUtils.BulletColliderLuaArray(deltaTime)
  if not res then
    BulletColliderResultArray[1] = 0
  end
  return BulletColliderResultArray
end

function PvePhysicsUtil.EnterBattle(useCollider2D)
  BattleColliderUtils.EnterBattle(useCollider2D)
end

function PvePhysicsUtil.ExitBattle()
  BattleColliderUtils.ExitBattle()
end

function PvePhysicsUtil.ResizeBulletColliderResultArray(size)
  if BulletColliderResultArray ~= nil then
    BulletColliderResultArray[size] = 0
    return true
  end
  return false
end

function PvePhysicsUtil.UnInitBulletCollider()
  if BulletColliderResultArray then
    BulletColliderResultArray:DestroyCSharpAccess()
    BulletColliderResultArray = nil
    BulletColliderResultArrayAccess = nil
    BattleColliderUtils.UnInitBulletColliderResultAccess()
  end
end

function PvePhysicsUtil.MonsterCollider()
  if MonsterColliderResultArray == nil then
    MonsterColliderResultArray = LuaCSharpArray.New(1)
    MonsterColliderResultArrayAccess = MonsterColliderResultArray:GetCSharpAccess()
    BattleColliderUtils.InitMonsterColliderResultAccess(MonsterColliderResultArrayAccess)
  end
  local res = BattleColliderUtils.MonsterColliderLuaArray()
  if not res then
    MonsterColliderResultArray[1] = 0
  end
  return MonsterColliderResultArray
end

function PvePhysicsUtil.ResizeMonsterColliderResultArray(size)
  if MonsterColliderResultArray ~= nil then
    MonsterColliderResultArray[size] = 0
    return true
  end
  return false
end

function PvePhysicsUtil.UnInitMonsterCollider()
  if MonsterColliderResultArray then
    MonsterColliderResultArray:DestroyCSharpAccess()
    MonsterColliderResultArray = nil
    MonsterColliderResultArrayAccess = nil
    BattleColliderUtils.UnInitMonsterColliderResultAccess()
  end
end

function PvePhysicsUtil.UnitCollider()
  if UnitColliderResultArray == nil then
    UnitColliderResultArray = LuaCSharpArray.New(1)
    UnitColliderResultArrayAccess = UnitColliderResultArray:GetCSharpAccess()
    BattleColliderUtils.InitUnitColliderResultAccess(UnitColliderResultArrayAccess)
  end
  local res = BattleColliderUtils.UnitColliderLuaArray()
  if not res then
    UnitColliderResultArray[1] = 0
  end
  return UnitColliderResultArray
end

function PvePhysicsUtil.ResizeUnitColliderResultArray(size)
  if UnitColliderResultArray ~= nil then
    UnitColliderResultArray[size] = 0
    return true
  end
  return false
end

function PvePhysicsUtil.UnInitUnitCollider()
  if UnitColliderResultArray then
    UnitColliderResultArray:DestroyCSharpAccess()
    UnitColliderResultArray = nil
    UnitColliderResultArrayAccess = nil
    BattleColliderUtils.UnInitUnitColliderResultAccess()
  end
end

function PvePhysicsUtil.PlayerCollider()
  if PlayerColliderResultArray == nil then
    PlayerColliderResultArray = LuaCSharpArray.New(1)
    PlayerColliderResultArrayAccess = PlayerColliderResultArray:GetCSharpAccess()
    BattleColliderUtils.InitPlayerColliderResultAccess(PlayerColliderResultArrayAccess)
  end
  local res = BattleColliderUtils.PlayerColliderLuaArray()
  if not res then
    PlayerColliderResultArray[1] = 0
  end
  return PlayerColliderResultArray
end

function PvePhysicsUtil.ResetPlayerColliderData()
  BattleColliderUtils.ResetPlayerColliderData()
end

function PvePhysicsUtil.TryGetSurfingPlayerCollideZ(attackerObjId)
  return BattleColliderUtils.TryGetSurfingPlayerCollideZ(attackerObjId)
end

function PvePhysicsUtil.ResizePlayerColliderResultArray(size)
  if PlayerColliderResultArray ~= nil then
    PlayerColliderResultArray[size] = 0
    return true
  end
  return false
end

function PvePhysicsUtil.UnInitPlayerCollider()
  if PlayerColliderResultArray then
    PlayerColliderResultArray:DestroyCSharpAccess()
    PlayerColliderResultArray = nil
    PlayerColliderResultArrayAccess = nil
    BattleColliderUtils.UnInitPlayerColliderResultAccess()
  end
end

function PvePhysicsUtil.UnInit()
  PvePhysicsUtil.UnInitBulletCollider()
  PvePhysicsUtil.UnInitMonsterCollider()
  PvePhysicsUtil.UnInitUnitCollider()
  PvePhysicsUtil.UnInitPlayerCollider()
  PvePhysicsUtil.ExitBattle()
end

return ConstClass("PvePhysicsUtil", PvePhysicsUtil)
