local class = require("core.class")
local animFrameMonitor = require("level.animframemonitor")
local LD = require("design.LevelDesignLibrary")
local AudioAnimFrameMonitor = class.Class("AudioAnimFrameMonitor", animFrameMonitor.AnimFrameMonitor)
local AddAudioAnimFrameMonitor = function(go)
  return AudioAnimFrameMonitor.New(go)
end
function AudioAnimFrameMonitor:AddFunctionBasedOnDirection(frame, func, direction)
  if frame ~= nil and type(frame) == "number" then
    if func ~= nil then
      if direction ~= nil and type(direction) == "string" then
        if string.lower(direction) == "forward" then
          self:OnFrameForward(frame, func)
        elseif string.lower(direction) == "backward" then
          self:OnFrameBackward(frame, func)
        end
      else
        self:OnFrame(frame, func)
      end
    else
      engine.Warning("Attempted to add a Sound Action when sound func is " .. tostring(func))
    end
  else
    engine.Warning("Attempted to add a Sound Action when frame is " .. tostring(frame))
  end
end
function AudioAnimFrameMonitor:AddSoundAction(action, frame, emitter, soundEvent, direction)
  if emitter ~= nil and soundEvent ~= nil then
    if string.lower(action) == "play" then
      self:AddFunctionBasedOnDirection(frame, function()
        LD.PlaySound(emitter, soundEvent)
      end, direction)
      table.insert(self.SoundActionList, {emitter, soundEvent})
    elseif string.lower(action) == "stop" then
      self:AddFunctionBasedOnDirection(frame, function()
        LD.StopSound(emitter, soundEvent)
      end, direction)
    else
      engine.Warning("Attempted to add a Sound Action when action is " .. tostring(action))
    end
  else
    engine.Warning("Attempted to add a Sound Action with: " .. tostring(emitter) .. " and " .. tostring(soundEvent))
  end
end
function AudioAnimFrameMonitor:AddSoundActionList(actionListTable)
  for i = 1, #actionListTable do
    self:AddSoundAction(actionListTable[i].action, actionListTable[i].frame, actionListTable[i].emitter, actionListTable[i].soundEvent, actionListTable[i].direction)
  end
end
function AudioAnimFrameMonitor:init(go)
  self.go = go
  self.value = go.AnimFrame
  self:Watch(self.watch_callback, self)
  self.frameCallbacks = {}
  self.frameForwardCallbacks = {}
  self.frameBackwardCallbacks = {}
  self.pausedSoundActionList = {}
  self.SoundActionList = {}
  self:Start()
end
function AudioAnimFrameMonitor:Start()
  self.watching = true
  self.runList:add(self)
  if self.pausedSoundActionList ~= nil then
    for i in pairs(self.pausedSoundActionList) do
      LD.PlaySound(self.pausedSoundActionList[i][1], self.pausedSoundActionList[i][2])
      table.remove(self.pausedSoundActionList, i)
    end
    self.pausedSoundActionList = {}
  end
end
function AudioAnimFrameMonitor:Stop()
  self.watching = false
  self.runList:remove(self)
  if self.SoundActionList ~= nil then
    for i in pairs(self.SoundActionList) do
      if self.SoundActionList[i][1]:IsPlaying(self.SoundActionList[i][2]) and LD.IsLoopingSound(self.SoundActionList[i][2]) and not self.SoundActionList[i][1]:IsPlaying(tostring(self.SoundActionList[i][2]) .. "_STOP") then
        local isAlreadyAdded = false
        for j = 1, #self.pausedSoundActionList do
          if self.SoundActionList[i][1] == self.pausedSoundActionList[j][1] and self.SoundActionList[i][2] == self.pausedSoundActionList[j][2] then
            isAlreadyAdded = true
          end
        end
        if not isAlreadyAdded then
          LD.StopSound(self.SoundActionList[i][1], self.SoundActionList[i][2])
          table.insert(self.pausedSoundActionList, self.SoundActionList[i])
        end
      end
    end
  end
end
_G.AddAudioAnimFrameMonitor = AddAudioAnimFrameMonitor
return {AudioAnimFrameMonitor = AudioAnimFrameMonitor, Add = AddAudioAnimFrameMonitor}
