local class = require("core.class")
local levelmonitor = require("level.levelmonitor")
local collisionCheck = require("camera.collisioncheck")
local LookAtMonitor = class.Class("LookAtMonitor", levelmonitor.LevelMonitor)
local callLookAtPctChangedCallback
function LookAtMonitor:OnLookAt(fn, ...)
  self:OnValue(true, callLookAtPctChangedCallback, self, fn, ...)
end
function LookAtMonitor:OnLookAway(fn, ...)
  self:OnValue(false, callLookAtPctChangedCallback, self, fn, ...)
end
function LookAtMonitor:SetMinPercentFromScreenEdge(pct)
  self.onScreenPct = pct / 100
end
function LookAtMonitor:SetObstructable(isObstructable)
  self.obstructable = isObstructable
end
function LookAtMonitor:SetDebugEnabled(isDebugEnabled)
  self.debugEnabled = isDebugEnabled
end
function LookAtMonitor:IsLookingAt()
  if self.position == nil or self.onScreenPct == nil then
    return self.value
  end
  if self.obstructable then
    local HudToggle = self.debugEnabled
    local penDepth = 0.2
    local verticalP = self.onScreenPct / 100
    local horizontalP = self.onScreenPct / 100
    return game.Camera.GetViewPenetration(self.position, 0, 0) > self.onScreenPct and collisionCheck.isTargetInFrustumUnobstructed(self.position, horizontalP, verticalP, penDepth, HudToggle)
  else
    return game.Camera.GetViewPenetration(self.position, 0, 0) > self.onScreenPct
  end
end
local AddLookAtMonitor = function(position)
  return LookAtMonitor.New(position)
end
function callLookAtPctChangedCallback(value, self, fn, ...)
  if value then
    self:dprint("LookAt Monitor triggered: Camera looking towards '" .. tostring(self.position) .. "' with screen space threshold of outer " .. tostring(self.onScreenPct * 100) .. " percent")
  else
    self:dprint("LookAt Monitor triggered: Camera looking away from '" .. tostring(self.position) .. "' with screen space threshold of outer " .. tostring(self.onScreenPct * 100) .. " percent")
  end
  fn(self, ...)
  return true
end
function LookAtMonitor:init(position)
  self.position = position
  self.onScreenPct = 0
  self.obstructable = false
  self.debugEnabled = false
  self.value = game.Camera.GetViewPenetration(self.position, 0, 0) > self.onScreenPct
  self:Watch(self.watch_callback, self)
  self:Start()
end
function LookAtMonitor:watch_callback()
  if self.position == nil or self.onScreenPct == nil then
    return self.value
  end
  if self.obstructable then
    local HudToggle = self.debugEnabled
    local penDepth = 0.2
    local verticalP = self.onScreenPct / 100
    local horizontalP = self.onScreenPct / 100
    return game.Camera.GetViewPenetration(self.position, 0, 0) > self.onScreenPct and collisionCheck.isTargetInFrustumUnobstructed(self.position, horizontalP, verticalP, penDepth, HudToggle)
  else
    return game.Camera.GetViewPenetration(self.position, 0, 0) > self.onScreenPct
  end
end
_G.AddLookAtMonitor = AddLookAtMonitor
return {LookAtMonitor = LookAtMonitor, Add = AddLookAtMonitor}
