local classlib = require("core.class")
local tablex = require("core.tablex")
local colors = require("ui.colors")
local consts = require("ui.consts")
local hooks = require("ui.hooks")
local slider = require("ui.slider")
local tutorialConsts = require("ui.tutorialConsts")
local tutorialUtil = require("ui.tutorialUtil")
local util = require("ui.util")
local Audio = game.Audio
local UI = game.UI
local SliderTapFill = classlib.Class("SliderTapFill", slider.Slider)
local PressEventHandler = function(sliderTapFill)
  sliderTapFill:StartPress()
end
local AnimEndEventHandler = function(sliderTapFill)
  local objNameHash = UI.GetEventArgStringHash(1)
  local percentComplete = UI.GetEventArgFloat(3) / 100
  local goSender = UI.GetEventSenderGameObject()
  sliderTapFill:AnimEnd(goSender, objNameHash, percentComplete)
end
function SliderTapFill:init(state, args)
  assert(state ~= nil, "Attempted to create new SliderTapFill without state!")
  assert(args ~= nil, "Attempted to create new SliderTapFill without args!")
  self._state = state
  self._active = false
  self._isIncrementing = false
  self._isFull = false
  self._isEmpty = true
  self._incrementEvents = nil
  self._decrementEvents = nil
  self._tapSound = args.TapSound
  self._percent = 0
  self._name = util.GetValueWithDefault(args.Name, "SliderTapFill_NotNamed")
  self._stopWhenFull = util.GetValueWithDefault(args.StopWhenFull, false)
  self._resistancePoint = util.GetValueWithDefault(args.ResistancePoint, 1)
  self._resistancePower = util.GetValueWithDefault(args.ResistancePower, 1)
  self._delta = util.GetValueWithDefault(args.Delta, 10)
  self._incAnimRate = util.GetValueWithDefault(args.IncAnimRate, 1)
  self._decAnimRate = util.GetValueWithDefault(args.DecAnimRate, 1)
  self._pressEvent = util.GetValueWithDefault(args.PressEvent, "EVT_Advance_Press")
  self._hookTokens = {}
  self._OnComplete = args.OnComplete
  self._OnReset = args.OnReset
  self:Setup()
  self:SetText("")
end
function SliderTapFill:Activate(show)
  if not self._active then
    util.InstallEventHooks(hooks, self, {
      self._pressEvent
    }, function(slider)
      tutorialUtil.HandleEvent(slider, {
        self._pressEvent
      }, PressEventHandler)
    end)
    util.InstallEventHooks(hooks, self, {
      "EVT_Anim_End"
    }, AnimEndEventHandler)
    self._active = true
    if show == true then
      self:Show()
    end
  end
end
function SliderTapFill:Deactivate(hide)
  if self._active then
    self._active = false
    util.UninstallEventHooks(hooks, self, {
      self._pressEvent
    })
    util.UninstallEventHooks(hooks, self, {
      "EVT_Anim_End"
    })
    tablex.Clear(self._hookTokens)
    if self._isFull == true then
      self:Reset()
    else
      self._isIncrementing = false
      self._percent = 0
      self:AnimFill(consts.AS_Reverse_NoReset, "", self._decAnimRate * 3, self._percent, 0)
    end
  end
  if hide == true then
    self:Hide()
  end
end
function SliderTapFill:Reset()
  self._isIncrementing = false
  self._isFull = false
  self._isEmpty = true
  self._percent = 0
  self:AnimFill(consts.AS_Forward, "", 0, 0)
  if self._OnReset ~= nil then
    self._OnReset()
  end
end
function SliderTapFill:ShouldStopBecauseFull()
  return self._isFull == true and self._stopWhenFull == true
end
function SliderTapFill:StartPress()
  if not self:ShouldStopBecauseFull() then
    self._isIncrementing = true
    if not util.IsStringNilOrEmpty(self._tapSound) then
      Audio.PlaySound(self._tapSound)
    end
    local endTime = self._percent + self:TapDeltaPercent()
    if 1 < endTime then
      endTime = 1
    end
    self:AnimFill(bit32.bor(consts.AS_Forward_NoReset, consts.AS_EndEvent), "", self._incAnimRate, self._percent, endTime)
  end
end
function SliderTapFill:StartDecrement()
  if not self:ShouldStopBecauseFull() then
    self._isIncrementing = false
    local endTime = self._percent - self:TapDeltaPercent()
    if endTime < 0 then
      endTime = 0
    end
    self:AnimFill(bit32.bor(consts.AS_Reverse_NoReset, consts.AS_EndEvent), "", self._decAnimRate, self._percent, endTime)
  end
end
function SliderTapFill:TapDeltaPercent()
  local newDelta = self._delta
  if self._isEmpty == true then
    self._isEmpty = false
    newDelta = 10
  elseif self._isIncrementing and self._percent >= self._resistancePoint then
    local multiplier = 1 - (self._percent - self._resistancePoint)
    newDelta = self._delta * multiplier ^ self._resistancePower
  end
  return newDelta / 100
end
function SliderTapFill:ShouldHandleAnimEndEvent(goSender, objNameHash)
  local shouldHandle = false
  if self._goSlider ~= nil then
    shouldHandle = self._goSliderChild == goSender
  end
  return shouldHandle
end
function SliderTapFill:AnimEnd(goSender, objNameHash, percentComplete)
  if self:ShouldHandleAnimEndEvent(goSender, objNameHash) == true then
    if 0.99 <= percentComplete then
      self._isFull = true
      self._percent = 1
      if not util.IsStringNilOrEmpty(self._successSound) then
        Audio.PlaySound(self._successSound)
      end
      if self._OnComplete ~= nil then
        self._OnComplete()
        tutorialUtil.CheckConditionMet(self._state, tutorialConsts.EVENT_TYPE_SLIDER_ON_COMPLETE, self._name, nil)
      end
    elseif percentComplete < 0.01 then
      self._percent = 0
      self._isEmpty = true
    else
      self._percent = percentComplete
      self:StartDecrement()
    end
  end
end
return {SliderTapFill = SliderTapFill}
