local classlib = require("core.class")
local tablex = require("core.tablex")
local buttonUtil = require("ui.buttonUtil")
local consts = require("ui.consts")
local list = require("ui.list")
local util = require("ui.util")
local lamsIDs = require("ui.lamsConsts")
local colors = require("ui.colors")
local UI = game.UI
local Control = classlib.Class("Control", list.List)
local GetControlSettingValue = function(controlItem)
  return controlItem.Value
end
local GetControlSettingText = function(controlItem)
  return controlItem.Text
end
local GetControlSettingDesc = function(controlItem)
  return controlItem.Desc
end
local GetControlSettingTip = function(controlItem)
  return controlItem.ToolTip
end
local DefaultHighlightOn = function(button)
  local goButtonChild = button:GetInstancedChildObject()
  if goButtonChild ~= nil then
    local endTime = 0.5
    local animRate = 0
    UI.Anim(goButtonChild, consts.AS_Forward, "", animRate, endTime)
  end
end
local DefaultHighlightOff = function(button)
  local goButtonChild = button:GetInstancedChildObject()
  if goButtonChild ~= nil then
    local endTime = 1
    local animRate = 0
    UI.Anim(goButtonChild, consts.AS_Forward, "", animRate, endTime)
  end
end
function Control:init(state, args)
  self._active = false
  self._maxFocusableObjectCount = 2
  self._button_onGainFocus_sound = args.Button_OnGainFocus_Sound
  self._thSettingDesc = args.SettingDescTextHandle
  self._onToggleFunc = args.OnToggleFunc
  self._hoverToSelect = true
  self._hasFocus = false
  self._Button_HighlightOn = DefaultHighlightOn
  self._Button_HighlightOff = DefaultHighlightOff
  self._wrap = util.GetValueWithDefault(args.Wrap, false)
  self._selectionChangeSound = util.GetValueWithDefault(args.SelectionChangeSound, "SND_UX_Menu_Tick_Horizontal")
  self._listObjectName = util.GetValueWithDefault(args.ControlObjectName, args.ListObjectName)
  self._dummyButton = nil
  self._allButtonGOs = {}
  self._previousReleaseEvents = {}
  self._nextReleaseEvents = {}
  if args.Settings ~= nil then
    self._settings = args.Settings
  else
    self._settings = {
      {
        Text = util.GetLAMSMsg(lamsIDs.Off),
        Value = false
      },
      {
        Text = util.GetLAMSMsg(lamsIDs.On),
        Value = true
      }
    }
  end
  if args.PreviousEvents ~= nil then
    self._previousEvents = args.PreviousEvents
  else
    local dpadEvent = self._padRepeatRate == 0 and "EVT_Left_Release" or "EVT_Left_Press"
    self._previousEvents = {
      dpadEvent,
      "EVT_LeftStick_Left"
    }
  end
  for _, eventName in ipairs(self._previousEvents) do
    if consts.RELEASE_EVENTS[eventName] ~= nil then
      tablex.FastInsert(self._previousReleaseEvents, consts.RELEASE_EVENTS[eventName], #self._previousReleaseEvents + 1)
    end
  end
  if args.NextEvents ~= nil then
    self._nextEvents = args.NextEvents
  else
    local dpadEvent = self._padRepeatRate == 0 and "EVT_Right_Release" or "EVT_Right_Press"
    self._nextEvents = {
      dpadEvent,
      "EVT_LeftStick_Right"
    }
  end
  for _, eventName in ipairs(self._nextEvents) do
    if consts.RELEASE_EVENTS[eventName] ~= nil then
      tablex.FastInsert(self._nextReleaseEvents, consts.RELEASE_EVENTS[eventName], #self._nextReleaseEvents + 1)
    end
  end
  function self._Button_OnGainFocus(button)
    self:Button_OnGainFocus(button)
  end
  function self._Button_OnLoseFocus(button)
    self:Button_OnLoseFocus(button)
  end
  self._default = args.Default
  self._Get = args.Get
  self._Set = args.Set
  if not util.IsStringNilOrEmpty(self._listObjectName) then
    local goList = util.GetUiObjByName(self._listObjectName)
    assert(goList ~= nil, "Control " .. self._listObjectName .. " game object not found!")
    self:SetGameObject(goList)
    self:SetupDummyButton()
    self:Setup()
  end
end
function Control:get_settings()
  local settings = self._settings
  if type(self._settings) == "function" then
    settings = self._settings()
  end
  for _, item in ipairs(settings) do
    item.Toggle = true
  end
  return settings
end
function Control:Setup()
  local settings = self:get_settings()
  local currValue = self._Get()
  local currValueIndex = 1
  self:CreateButtonArray(settings, nil, function(setting)
    return GetControlSettingText(setting)
  end)
  self:SetSelectedButton(1, false)
  self:Update()
end
function Control:Button_OnGainFocus(button)
  self._hasFocus = true
  if self._Set ~= nil then
    local currentSetting = button:get_item()
    local currentValue = GetControlSettingValue(currentSetting)
    self._Set(currentValue)
  end
  self:Update()
end
function Control:Button_OnLoseFocus(button)
  self._hasFocus = false
end
function Control:ClearButtons()
  if self._hasFocus then
    return
  end
  for _, button in ipairs(self._buttonArray) do
    local goButtonChild = button:GetInstancedChildObject()
    if goButtonChild ~= nil then
      UI.Anim(goButtonChild, consts.AS_Forward, "", 0, 1)
    end
  end
end
function Control:Update()
  local currentButton = self:GetSelectedButton()
  local currentSetting = currentButton:get_item()
  local currentText = GetControlSettingText(currentSetting)
  local currentDesc = GetControlSettingDesc(currentSetting)
  local currentToolTip = GetControlSettingTip(currentSetting)
  self:UpdateButtons()
  self:ClearButtons()
  if self._active then
    self:SetDescText(currentDesc)
    self:OnToggleFunction()
    self:ControlToolTip(currentToolTip)
  end
  self:UpdateScrollDirectionIndicators()
end
function Control:ControlToolTip(tip)
  if tip ~= nil then
    self._state:SendEventToUIFsm("globalMenu", "EVT_SET_FOOTER_TOOL_TIP_TOP", tip)
  end
end
function Control:OnToggleFunction()
  if self._onToggleFunc ~= nil then
    local currentButton = self:GetSelectedButton()
    local currentSetting = currentButton:get_item()
    local currentValue = GetControlSettingValue(currentSetting)
    self._onToggleFunc(currentValue)
  end
end
function Control:SetGameObject(goList)
  assert(goList ~= nil, "Control:SetGameObject called with no game object!")
  self._goList = goList
  self._buttonObjectBaseName = "Button"
  self._goListChild = self._goList:FindSingleGOByName("control")
  self:SetupAllButtonGameObjects()
  self:SetupHeader()
  self:SetupBacking()
  self:SetupScrollDirectionIndicators()
  self:SetupScrollbar()
  self:ClearButtons()
end
function Control:SetDescText(currentDesc)
  if self._thSettingDesc ~= nil then
    UI.SetText(self._thSettingDesc, "")
    if not util.IsStringNilOrEmpty(currentDesc) then
      UI.SetText(self._thSettingDesc, currentDesc)
    end
  end
end
function Control:SetDefault(controlIsFocused)
  if self._default ~= nil then
    local default_value = self._default()
    if default_value ~= nil then
      self:ForceSetValue(default_value)
    end
  end
end
function Control:ForceSetValue(value)
  if self._Set ~= nil then
    self._Set(value)
    local currValueIndex = 1
    for buttonIndex, button in ipairs(self._buttonArray) do
      local setting = button:get_item()
      local settingValue = GetControlSettingValue(setting)
      if settingValue == value then
        currValueIndex = buttonIndex
        break
      end
    end
    self:SetSelectedButton(currValueIndex, false)
  end
end
function Control:DisableText()
  local currentButton = self:GetSelectedButton()
  currentButton:SetTextColor(colors.Text_Settings_Disabled, "medium_text_settings1")
end
function Control:EnableText()
  local currentButton = self:GetSelectedButton()
  currentButton:SetTextColor(colors.Text_Settings1, "medium_text_settings1")
end
function Control:OverrideSettings(newSettingsList)
  if newSettingsList then
    self._settings = newSettingsList
  else
    self._settings = {
      {
        Text = util.GetLAMSMsg(lamsIDs.Off),
        Value = false
      },
      {
        Text = util.GetLAMSMsg(lamsIDs.On),
        Value = true
      }
    }
  end
  self:Setup()
end
function Control:SetScrollBarVisibility()
end
function Control:SetScrollBarPosition()
end
return {Control = Control}
